mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 09:30:31 +03:00
Improved labels displayed in charts when visits are highlighted
This commit is contained in:
parent
b6ab9a1bdd
commit
6a372badfa
4 changed files with 23 additions and 9 deletions
|
@ -13,10 +13,11 @@ const propTypes = {
|
|||
stats: PropTypes.object,
|
||||
max: PropTypes.number,
|
||||
highlightedStats: PropTypes.object,
|
||||
highlightedLabel: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
};
|
||||
|
||||
const generateGraphData = (title, isBarChart, labels, data, highlightedData) => ({
|
||||
const generateGraphData = (title, isBarChart, labels, data, highlightedData, highlightedLabel) => ({
|
||||
labels,
|
||||
datasets: [
|
||||
{
|
||||
|
@ -41,7 +42,7 @@ const generateGraphData = (title, isBarChart, labels, data, highlightedData) =>
|
|||
},
|
||||
highlightedData && {
|
||||
title,
|
||||
label: 'Selected',
|
||||
label: highlightedLabel || 'Selected',
|
||||
data: highlightedData,
|
||||
backgroundColor: 'rgba(247, 127, 40, 0.4)',
|
||||
borderColor: '#F77F28',
|
||||
|
@ -60,7 +61,7 @@ const determineHeight = (isBarChart, labels) => {
|
|||
return isBarChart && labels.length > 20 ? labels.length * 8 : null;
|
||||
};
|
||||
|
||||
const renderGraph = (title, isBarChart, stats, max, highlightedStats, onClick) => {
|
||||
const renderGraph = (title, isBarChart, stats, max, highlightedStats, highlightedLabel, onClick) => {
|
||||
const hasHighlightedStats = highlightedStats && Object.keys(highlightedStats).length > 0;
|
||||
const Component = isBarChart ? HorizontalBar : Doughnut;
|
||||
const labels = keys(stats).map(dropLabelIfHidden);
|
||||
|
@ -94,7 +95,7 @@ const renderGraph = (title, isBarChart, stats, max, highlightedStats, onClick) =
|
|||
target.style.cursor = chartElement[0] ? 'pointer' : 'default';
|
||||
}),
|
||||
};
|
||||
const graphData = generateGraphData(title, isBarChart, labels, data, highlightedData);
|
||||
const graphData = generateGraphData(title, isBarChart, labels, data, highlightedData, highlightedLabel);
|
||||
const height = determineHeight(isBarChart, labels);
|
||||
|
||||
// Provide a key based on the height, so that every time the dataset changes, a new graph is rendered
|
||||
|
@ -118,10 +119,10 @@ const renderGraph = (title, isBarChart, stats, max, highlightedStats, onClick) =
|
|||
);
|
||||
};
|
||||
|
||||
const GraphCard = ({ title, footer, isBarChart, stats, max, highlightedStats, onClick }) => (
|
||||
const GraphCard = ({ title, footer, isBarChart, stats, max, highlightedStats, highlightedLabel, onClick }) => (
|
||||
<Card>
|
||||
<CardHeader className="graph-card__header">{typeof title === 'function' ? title() : title}</CardHeader>
|
||||
<CardBody>{renderGraph(title, isBarChart, stats, max, highlightedStats, onClick)}</CardBody>
|
||||
<CardBody>{renderGraph(title, isBarChart, stats, max, highlightedStats, highlightedLabel, onClick)}</CardBody>
|
||||
{footer && <CardFooter className="graph-card__footer--sticky">{footer}</CardFooter>}
|
||||
</Card>
|
||||
);
|
||||
|
|
|
@ -17,6 +17,7 @@ export default class SortableBarGraph extends React.Component {
|
|||
static propTypes = {
|
||||
stats: PropTypes.object.isRequired,
|
||||
highlightedStats: PropTypes.object,
|
||||
highlightedLabel: PropTypes.string,
|
||||
title: PropTypes.string.isRequired,
|
||||
sortingItems: PropTypes.object.isRequired,
|
||||
extraHeaderContent: PropTypes.func,
|
||||
|
|
|
@ -42,6 +42,7 @@ const VisitsStats = ({ processStatsFromVisits, normalizeVisits }, OpenMapModalBt
|
|||
const [ showTable, toggleTable ] = useToggle();
|
||||
const [ tableIsSticky, , setSticky, unsetSticky ] = useToggle();
|
||||
const [ highlightedVisits, setHighlightedVisits ] = useState([]);
|
||||
const [ highlightedLabel, setHighlightedLabel ] = useState();
|
||||
const [ isMobileDevice, setIsMobileDevice ] = useState(false);
|
||||
const determineIsMobileDevice = () => setIsMobileDevice(matchMedia('(max-width: 991px)').matches);
|
||||
const setSelectedVisits = (selectedVisits) => {
|
||||
|
@ -53,9 +54,11 @@ const VisitsStats = ({ processStatsFromVisits, normalizeVisits }, OpenMapModalBt
|
|||
|
||||
if (selectedBar === newSelectedBar) {
|
||||
setHighlightedVisits([]);
|
||||
setHighlightedLabel(undefined);
|
||||
selectedBar = undefined;
|
||||
} else {
|
||||
setHighlightedVisits(normalizedVisits.filter(propEq(prop, value)));
|
||||
setHighlightedLabel(value);
|
||||
selectedBar = newSelectedBar;
|
||||
}
|
||||
};
|
||||
|
@ -111,7 +114,12 @@ const VisitsStats = ({ processStatsFromVisits, normalizeVisits }, OpenMapModalBt
|
|||
return (
|
||||
<div className="row">
|
||||
<div className="col-12 mt-4">
|
||||
<LineChartCard title="Visits during time" visits={visits} highlightedVisits={highlightedVisits} />
|
||||
<LineChartCard
|
||||
title="Visits during time"
|
||||
visits={visits}
|
||||
highlightedVisits={highlightedVisits}
|
||||
highlightedLabel={highlightedLabel}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-xl-4 col-lg-6 mt-4">
|
||||
<GraphCard title="Operating systems" stats={os} />
|
||||
|
@ -125,6 +133,7 @@ const VisitsStats = ({ processStatsFromVisits, normalizeVisits }, OpenMapModalBt
|
|||
stats={referrers}
|
||||
withPagination={false}
|
||||
highlightedStats={highlightedVisitsToStats(highlightedVisits, 'referer')}
|
||||
highlightedLabel={highlightedLabel}
|
||||
sortingItems={{
|
||||
name: 'Referrer name',
|
||||
amount: 'Visits amount',
|
||||
|
@ -137,6 +146,7 @@ const VisitsStats = ({ processStatsFromVisits, normalizeVisits }, OpenMapModalBt
|
|||
title="Countries"
|
||||
stats={countries}
|
||||
highlightedStats={highlightedVisitsToStats(highlightedVisits, 'country')}
|
||||
highlightedLabel={highlightedLabel}
|
||||
sortingItems={{
|
||||
name: 'Country name',
|
||||
amount: 'Visits amount',
|
||||
|
@ -149,6 +159,7 @@ const VisitsStats = ({ processStatsFromVisits, normalizeVisits }, OpenMapModalBt
|
|||
title="Cities"
|
||||
stats={cities}
|
||||
highlightedStats={highlightedVisitsToStats(highlightedVisits, 'city')}
|
||||
highlightedLabel={highlightedLabel}
|
||||
extraHeaderContent={(activeCities) =>
|
||||
mapLocations.length > 0 &&
|
||||
<OpenMapModalBtn modalTitle="Cities" locations={mapLocations} activeCities={activeCities} />
|
||||
|
|
|
@ -21,6 +21,7 @@ import Checkbox from '../../utils/Checkbox';
|
|||
|
||||
const propTypes = {
|
||||
title: PropTypes.string,
|
||||
highlightedLabel: PropTypes.string,
|
||||
visits: PropTypes.arrayOf(VisitType),
|
||||
highlightedVisits: PropTypes.arrayOf(VisitType),
|
||||
};
|
||||
|
@ -91,7 +92,7 @@ const generateDataset = (stats, label, color) => ({
|
|||
backgroundColor: color,
|
||||
});
|
||||
|
||||
const LineChartCard = ({ title, visits, highlightedVisits }) => {
|
||||
const LineChartCard = ({ title, visits, highlightedVisits, highlightedLabel = 'Selected' }) => {
|
||||
const [ step, setStep ] = useState('monthly');
|
||||
const [ skipNoVisits, toggleSkipNoVisits ] = useToggle(true);
|
||||
|
||||
|
@ -109,7 +110,7 @@ const LineChartCard = ({ title, visits, highlightedVisits }) => {
|
|||
labels,
|
||||
datasets: [
|
||||
generateDataset(groupedVisits, 'Visits', '#4696e5'),
|
||||
highlightedVisits.length > 0 && generateDataset(groupedHighlighted, 'Selected', '#F77F28'),
|
||||
highlightedVisits.length > 0 && generateDataset(groupedHighlighted, highlightedLabel, '#F77F28'),
|
||||
].filter(Boolean),
|
||||
};
|
||||
const options = {
|
||||
|
|
Loading…
Reference in a new issue