diff --git a/src/visits/GraphCard.js b/src/visits/GraphCard.js
index 253f4011..d9be74cc 100644
--- a/src/visits/GraphCard.js
+++ b/src/visits/GraphCard.js
@@ -2,7 +2,7 @@ import { Card, CardHeader, CardBody, CardFooter } from 'reactstrap';
import { Doughnut, HorizontalBar } from 'react-chartjs-2';
import PropTypes from 'prop-types';
import React from 'react';
-import { keys, values } from 'ramda';
+import { keys, values, zipObj } from 'ramda';
import './GraphCard.scss';
const propTypes = {
@@ -11,9 +11,10 @@ const propTypes = {
isBarChart: PropTypes.bool,
stats: PropTypes.object,
max: PropTypes.number,
+ highlightedStats: PropTypes.object,
};
-const generateGraphData = (title, isBarChart, labels, data) => ({
+const generateGraphData = (title, isBarChart, labels, data, highlightedData) => ({
labels,
datasets: [
{
@@ -31,23 +32,41 @@ const generateGraphData = (title, isBarChart, labels, data) => ({
borderColor: isBarChart ? 'rgba(70, 150, 229, 1)' : 'white',
borderWidth: 2,
},
- ],
+ highlightedData && {
+ title,
+ label: 'Selected',
+ data: highlightedData,
+ backgroundColor: 'rgba(247, 127, 40, 0.4)',
+ borderColor: '#F77F28',
+ borderWidth: 2,
+ },
+ ].filter(Boolean),
});
const dropLabelIfHidden = (label) => label.startsWith('hidden') ? '' : label;
-const renderGraph = (title, isBarChart, stats, max) => {
+const renderGraph = (title, isBarChart, stats, max, highlightedStats) => {
const Component = isBarChart ? HorizontalBar : Doughnut;
const labels = keys(stats).map(dropLabelIfHidden);
- const data = values(stats);
+ const data = values(!highlightedStats ? stats : keys(highlightedStats).reduce((acc, highlightedKey) => {
+ if (acc[highlightedKey]) {
+ acc[highlightedKey] -= 1;
+ }
+
+ return acc;
+ }, stats));
+ const highlightedData = highlightedStats && values({ ...zipObj(labels, labels.map(() => 0)), ...highlightedStats });
+
const options = {
legend: isBarChart ? { display: false } : { position: 'right' },
scales: isBarChart && {
xAxes: [
{
ticks: { beginAtZero: true, max },
+ stacked: true,
},
],
+ yAxes: [{ stacked: true }],
},
tooltips: {
intersect: !isBarChart,
@@ -56,17 +75,17 @@ const renderGraph = (title, isBarChart, stats, max) => {
filter: ({ yLabel }) => !isBarChart || yLabel !== '',
},
};
- const graphData = generateGraphData(title, isBarChart, labels, data);
+ const graphData = generateGraphData(title, isBarChart, labels, data, highlightedData);
const height = isBarChart && labels.length > 20 ? labels.length * 8 : null;
// Provide a key based on the height, so that every time the dataset changes, a new graph is rendered
return ;
};
-const GraphCard = ({ title, footer, isBarChart, stats, max }) => (
+const GraphCard = ({ title, footer, isBarChart, stats, max, highlightedStats }) => (
{typeof title === 'function' ? title() : title}
- {renderGraph(title, isBarChart, stats, max)}
+ {renderGraph(title, isBarChart, stats, max, highlightedStats)}
{footer && {footer}}
);
diff --git a/src/visits/ShortUrlVisits.js b/src/visits/ShortUrlVisits.js
index 5a5ed3ec..25cbe5f8 100644
--- a/src/visits/ShortUrlVisits.js
+++ b/src/visits/ShortUrlVisits.js
@@ -15,6 +15,8 @@ import GraphCard from './GraphCard';
import { shortUrlDetailType } from './reducers/shortUrlDetail';
import VisitsTable from './VisitsTable';
+const highlightedVisitToStats = (highlightedVisit, prop) => highlightedVisit && { [highlightedVisit[prop]]: 1 };
+
const ShortUrlVisits = (
{ processStatsFromVisits },
OpenMapModalBtn
@@ -40,6 +42,7 @@ const ShortUrlVisits = (
showTable: false,
tableIsSticky: false,
isMobileDevice: false,
+ highlightedVisit: undefined,
};
loadVisits = (loadDetail = false) => {
@@ -114,9 +117,10 @@ const ShortUrlVisits = (
mapLocations.length > 0 &&
@@ -188,7 +194,11 @@ const ShortUrlVisits = (
onEntered={() => this.setState({ tableIsSticky: true })}
onExiting={() => this.setState({ tableIsSticky: false })}
>
-
+ this.setState({ highlightedVisit })}
+ />
)}
diff --git a/src/visits/SortableBarGraph.js b/src/visits/SortableBarGraph.js
index 3a538296..54a1bd9b 100644
--- a/src/visits/SortableBarGraph.js
+++ b/src/visits/SortableBarGraph.js
@@ -15,6 +15,7 @@ const pickValueFromPair = ([ , value ]) => value;
export default class SortableBarGraph extends React.Component {
static propTypes = {
stats: PropTypes.object.isRequired,
+ highlightedStats: PropTypes.object,
title: PropTypes.string.isRequired,
sortingItems: PropTypes.object.isRequired,
extraHeaderContent: PropTypes.func,
@@ -73,7 +74,7 @@ export default class SortableBarGraph extends React.Component {
}
render() {
- const { stats, sortingItems, title, extraHeaderContent, withPagination = true } = this.props;
+ const { stats, sortingItems, title, extraHeaderContent, highlightedStats, withPagination = true } = this.props;
const { currentPageStats, pagination, max } = this.determineStats(stats, sortingItems);
const activeCities = keys(currentPageStats);
const computeTitle = () => (
@@ -107,6 +108,15 @@ export default class SortableBarGraph extends React.Component {
);
- return ;
+ return (
+
+ );
}
}
diff --git a/src/visits/VisitsTable.js b/src/visits/VisitsTable.js
index 6a3c5fb1..4a8e0972 100644
--- a/src/visits/VisitsTable.js
+++ b/src/visits/VisitsTable.js
@@ -98,7 +98,7 @@ const VisitsTable = ({ visits, onVisitSelected, isSticky = false, matchMedia = w
'visits-table__sticky': isSticky,
})}
>
-
+
|
Date
diff --git a/test/visits/GraphCard.test.js b/test/visits/GraphCard.test.js
index af4e1e97..52975c61 100644
--- a/test/visits/GraphCard.test.js
+++ b/test/visits/GraphCard.test.js
@@ -59,8 +59,10 @@ describe('', () => {
xAxes: [
{
ticks: { beginAtZero: true },
+ stacked: true,
},
],
+ yAxes: [{ stacked: true }],
});
});
});
|