aboutsummaryrefslogtreecommitdiff
path: root/modern/src/reports
diff options
context:
space:
mode:
authorAnton Tananaev <anton@traccar.org>2022-05-15 11:30:10 -0700
committerAnton Tananaev <anton@traccar.org>2022-05-15 11:30:10 -0700
commit636181965da6d32ed966d20d259a27e297e7694f (patch)
tree8c7f59c0ed9a9c4909185f29f0d7edd3e9d97335 /modern/src/reports
parent63cf082bd077087e551d2946c3e2a48a605a3532 (diff)
downloadtrackermap-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.js58
-rw-r--r--modern/src/reports/components/Graph.js43
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;