From 68b0577526f25364cb35bff13e135afadebe9d89 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 30 May 2020 09:57:21 +0200 Subject: [PATCH] Added dynamic grouping to time-based line chart --- src/visits/helpers/LineChartCard.js | 66 +++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/src/visits/helpers/LineChartCard.js b/src/visits/helpers/LineChartCard.js index 1bd950ae..d319d905 100644 --- a/src/visits/helpers/LineChartCard.js +++ b/src/visits/helpers/LineChartCard.js @@ -1,6 +1,14 @@ import React, { useState, useMemo } from 'react'; import PropTypes from 'prop-types'; -import { Card, CardHeader, CardBody } from 'reactstrap'; +import { + Card, + CardHeader, + CardBody, + UncontrolledDropdown, + DropdownToggle, + DropdownMenu, + DropdownItem, +} from 'reactstrap'; import { Line } from 'react-chartjs-2'; import { reverse } from 'ramda'; import moment from 'moment'; @@ -13,15 +21,39 @@ const propTypes = { highlightedVisits: PropTypes.arrayOf(VisitType), }; -const STEP_TO_DATE_FORMAT_MAP = { - hourly: 'YYYY-MM-DD HH:00', - daily: 'YYYY-MM-DD', - weekly: '', - monthly: 'YYYY-MM', +const steps = [ + { + value: 'monthly', + menuText: 'Month', + }, + { + value: 'weekly', + menuText: 'Week', + }, + { + value: 'daily', + menuText: 'Day', + }, + { + value: 'hourly', + menuText: 'Hour', + }, +]; + +const STEP_TO_DATE_FORMAT = { + hourly: (date) => moment(date).format('YYYY-MM-DD HH:00'), + daily: (date) => moment(date).format('YYYY-MM-DD'), + weekly(date) { + const firstWeekDay = moment(date).isoWeekday(1).format('YYYY-MM-DD'); + const lastWeekDay = moment(date).isoWeekday(7).format('YYYY-MM-DD'); + + return `${firstWeekDay} - ${lastWeekDay}`; + }, + monthly: (date) => moment(date).format('YYYY-MM'), }; const groupVisitsByStep = (step, visits) => visits.reduce((acc, visit) => { - const key = moment(visit.date).format(STEP_TO_DATE_FORMAT_MAP[step]); + const key = STEP_TO_DATE_FORMAT[step](visit.date); acc[key] = acc[key] ? acc[key] + 1 : 1; @@ -38,7 +70,7 @@ const generateDataset = (stats, label, color) => ({ }); const LineChartCard = ({ title, visits, highlightedVisits }) => { - const [ step ] = useState('monthly'); // hourly, daily, weekly, monthly + const [ step, setStep ] = useState(steps[0].value); const groupedVisits = useMemo(() => groupVisitsByStep(step, reverse(visits)), [ visits, step ]); const labels = useMemo(() => Object.keys(groupedVisits), [ groupedVisits ]); const groupedHighlighted = useMemo( @@ -66,7 +98,23 @@ const LineChartCard = ({ title, visits, highlightedVisits }) => { return ( - {title} + + {title} +
+ + + Group by + + + {steps.map(({ menuText, value }) => ( + setStep(value)}> + {menuText} + + ))} + + +
+