diff options
author | Anton Tananaev <anton@traccar.org> | 2022-05-15 11:30:10 -0700 |
---|---|---|
committer | Anton Tananaev <anton@traccar.org> | 2022-05-15 11:30:10 -0700 |
commit | 636181965da6d32ed966d20d259a27e297e7694f (patch) | |
tree | 8c7f59c0ed9a9c4909185f29f0d7edd3e9d97335 /modern/src/reports | |
parent | 63cf082bd077087e551d2946c3e2a48a605a3532 (diff) | |
download | trackermap-web-636181965da6d32ed966d20d259a27e297e7694f.tar.gz trackermap-web-636181965da6d32ed966d20d259a27e297e7694f.tar.bz2 trackermap-web-636181965da6d32ed966d20d259a27e297e7694f.zip |
Improve chart layout
Diffstat (limited to 'modern/src/reports')
-rw-r--r-- | modern/src/reports/ChartReportPage.js | 58 | ||||
-rw-r--r-- | modern/src/reports/components/Graph.js | 43 |
2 files changed, 49 insertions, 52 deletions
diff --git a/modern/src/reports/ChartReportPage.js b/modern/src/reports/ChartReportPage.js index 57c7c689..7056dc70 100644 --- a/modern/src/reports/ChartReportPage.js +++ b/modern/src/reports/ChartReportPage.js @@ -1,9 +1,11 @@ import React, { useState } from 'react'; import { - FormControl, InputLabel, Select, MenuItem, + FormControl, InputLabel, Select, MenuItem, makeStyles, } from '@material-ui/core'; +import { + CartesianGrid, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis, +} from 'recharts'; import ReportFilter, { useFilterStyles } from './components/ReportFilter'; -import Graph from './components/Graph'; import { useAttributePreference } from '../common/util/preferences'; import { formatDate } from '../common/util/formatter'; import { speedFromKnots } from '../common/util/converter'; @@ -11,8 +13,23 @@ import { useTranslation } from '../common/components/LocalizationProvider'; import PageLayout from '../common/components/PageLayout'; import ReportsMenu from './components/ReportsMenu'; +const typesArray = [ + ['speed', 'positionSpeed'], + ['accuracy', 'positionAccuracy'], + ['altitude', 'positionAltitude'], +]; +const typesMap = new Map(typesArray); + +const useStyles = makeStyles(() => ({ + chart: { + flexGrow: 1, + overflow: 'hidden', + }, +})); + const ChartReportPage = () => { - const classes = useFilterStyles(); + const classes = useStyles(); + const filterClasses = useFilterStyles(); const t = useTranslation(); const speedUnit = useAttributePreference('speedUnit'); @@ -20,6 +37,12 @@ const ChartReportPage = () => { const [items, setItems] = useState([]); const [type, setType] = useState('speed'); + const dataRange = (() => { + const values = items.map((it) => it[type]); + const result = Math.max(...values) - Math.min(...values); + return result; + })(); + const handleSubmit = async (deviceId, from, to, mail, headers) => { const query = new URLSearchParams({ deviceId, from, to, mail, @@ -31,7 +54,7 @@ const ChartReportPage = () => { speed: Number(speedFromKnots(position.speed, speedUnit)), altitude: position.altitude, accuracy: position.accuracy, - fixTime: formatDate(position.fixTime), + fixTime: formatDate(position.fixTime, 'HH:mm:ss'), })); setItems(formattedPositions); } @@ -40,18 +63,35 @@ const ChartReportPage = () => { return ( <PageLayout menu={<ReportsMenu />} breadcrumbs={['reportTitle', 'reportChart']}> <ReportFilter handleSubmit={handleSubmit} showOnly> - <div className={classes.item}> + <div className={filterClasses.item}> <FormControl variant="filled" fullWidth> <InputLabel>{t('reportChartType')}</InputLabel> <Select value={type} onChange={(e) => setType(e.target.value)}> - <MenuItem value="speed">{t('positionSpeed')}</MenuItem> - <MenuItem value="accuracy">{t('positionAccuracy')}</MenuItem> - <MenuItem value="altitude">{t('positionAltitude')}</MenuItem> + {typesArray.map(([key, string]) => ( + <MenuItem key={key} value={key}>{t(string)}</MenuItem> + ))} </Select> </FormControl> </div> </ReportFilter> - <Graph items={items} type={type} /> + {items.length > 0 && ( + <div className={classes.chart}> + <ResponsiveContainer> + <LineChart + data={items} + margin={{ + top: 30, right: 40, left: 10, bottom: 10, + }} + > + <XAxis dataKey="fixTime" /> + <YAxis type="number" domain={[`dataMin - ${dataRange / 5}`, `dataMax + ${dataRange / 5}`]} /> + <CartesianGrid strokeDasharray="3 3" /> + <Tooltip formatter={(value, name) => [value, t(typesMap.get(name))]} /> + <Line type="natural" dataKey={type} /> + </LineChart> + </ResponsiveContainer> + </div> + )} </PageLayout> ); }; diff --git a/modern/src/reports/components/Graph.js b/modern/src/reports/components/Graph.js deleted file mode 100644 index 88b51493..00000000 --- a/modern/src/reports/components/Graph.js +++ /dev/null @@ -1,43 +0,0 @@ -import React from 'react'; -import { makeStyles } from '@material-ui/core'; -import { - LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, -} from 'recharts'; - -const CustomizedAxisTick = ({ x, y, payload }) => { - if (!payload.value) { - return payload.value; - } - const parts = payload.value.split(' '); - return ( - <g transform={`translate(${x},${y})`}> - <text x={0} y={0} dy={16} textAnchor="end" fill="#666" transform="rotate(-35)">{parts[0]}</text> - <text x={0} y={16} dy={16} textAnchor="end" fill="#666" transform="rotate(-35)">{parts[1]}</text> - </g> - ); -}; - -const useStyles = makeStyles((theme) => ({ - chart: { - backgroundColor: theme.palette.colors.white, - }, -})); - -const Graph = ({ type, items }) => { - const classes = useStyles(); - - return ( - <ResponsiveContainer height={400} width="100%" debounce={1} className={classes.chart}> - <LineChart data={items}> - <XAxis dataKey="fixTime" tick={<CustomizedAxisTick />} height={60} /> - <YAxis /> - <CartesianGrid strokeDasharray="3 3" /> - <Tooltip /> - <Legend /> - <Line type="natural" dataKey={type} /> - </LineChart> - </ResponsiveContainer> - ); -}; - -export default Graph; |