aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modern/src/common/chartTypes.js7
-rw-r--r--modern/src/common/formatter.js25
-rw-r--r--modern/src/reports/ChartReportPage.js90
-rw-r--r--modern/src/reports/ChartType.js53
-rw-r--r--modern/src/reports/ReportLayoutPage.js4
5 files changed, 81 insertions, 98 deletions
diff --git a/modern/src/common/chartTypes.js b/modern/src/common/chartTypes.js
new file mode 100644
index 00000000..fa868a96
--- /dev/null
+++ b/modern/src/common/chartTypes.js
@@ -0,0 +1,7 @@
+import t from '../common/localization';
+
+export const chartTypes = [
+ { id: 'speed', name: t('positionSpeed') },
+ { id: 'accuracy', name: t('positionAccuracy') },
+ { id: 'altitude', name: t('positionAltitude') },
+];
diff --git a/modern/src/common/formatter.js b/modern/src/common/formatter.js
index 8ef00400..b2f305a0 100644
--- a/modern/src/common/formatter.js
+++ b/modern/src/common/formatter.js
@@ -9,7 +9,7 @@ export const formatPosition = (value, key) => {
case 'fixTime':
case 'deviceTime':
case 'serverTime':
- return moment(value).format('YYYY-MM-DD HH:mm');
+ return moment(value).format('LLL');
case 'latitude':
case 'longitude':
return value.toFixed(5);
@@ -80,3 +80,26 @@ export const formatVolume = (value, unit) => {
export const formatHours = (value) => {
return moment.duration(value).humanize();
};
+
+const speedConverter = (value, unit) => {
+ switch (unit) {
+ case 'kmh':
+ return (value * 1.852).toFixed(2);
+ case 'mph':
+ return (value * 1.15078).toFixed(2);
+ case 'kn':
+ default:
+ return (value * 1).toFixed(2);
+ }
+};
+
+export const getConverter = (key) => {
+ switch (key) {
+ case 'speed':
+ return speedConverter;
+ default:
+ return function (value) {
+ return value;
+ }
+ }
+};
diff --git a/modern/src/reports/ChartReportPage.js b/modern/src/reports/ChartReportPage.js
index 68989331..e37f7ca1 100644
--- a/modern/src/reports/ChartReportPage.js
+++ b/modern/src/reports/ChartReportPage.js
@@ -1,43 +1,53 @@
import React, { useState } from 'react';
-import { Card, CardHeader, CardContent } from '@material-ui/core';
-import { Box, Divider } from '@material-ui/core';
-import { makeStyles } from '@material-ui/core/styles';
+import { Box, Paper, FormControl, InputLabel, Select, MenuItem } from '@material-ui/core';
import ReportFilter from './ReportFilter';
import ReportLayoutPage from './ReportLayoutPage';
-import ChartType from './ChartType';
+import t from '../common/localization';
+import { chartTypes } from '../common/chartTypes';
+import { useAttributePreference } from '../common/preferences';
+import { getConverter, formatDate } from '../common/formatter';
import {LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
-const useStyles = makeStyles((theme) => ({
- formControl: {
- minWidth: 160,
- },
-}));
+const ReportFilterForm = ({ setItems, setType }) => {
-const ReportFilterForm = ({ setItems }) => {
+ const speedUnit = useAttributePreference('speedUnit');
const handleSubmit = async (deviceId, from, to, mail, headers) => {
const query = new URLSearchParams({ deviceId, from, to, mail });
const response = await fetch(`/api/reports/route?${query.toString()}`, { headers });
if (response.ok) {
- const contentType = response.headers.get('content-type');
- if (contentType) {
- if (contentType === 'application/json') {
- setItems(await response.json());
- } else {
- window.location.assign(window.URL.createObjectURL(await response.blob()));
- }
- }
+ const data = await response.json();
+ let formattedData = data.map((obj)=>{
+ return Object.assign(obj,
+ {speed: getConverter('speed')(obj.speed, speedUnit)},
+ {fixTime: formatDate(obj.fixTime)}
+ );
+ })
+ setItems(formattedData);
}
- };
+ }
- return <ReportFilter handleSubmit={handleSubmit} showOnly />;
+ return (
+ <ReportFilter handleSubmit={handleSubmit} showOnly >
+ <FormControl variant="filled" margin="normal" fullWidth>
+ <InputLabel>{t('reportChartType')}</InputLabel>
+ <Select defaultValue="speed" onChange={e => setType(e.target.value)}>
+ {chartTypes.map(item => (
+ <MenuItem key={item.id} value={item.id}>{item.name}</MenuItem>
+ ))}
+ </Select>
+ </FormControl>
+ </ReportFilter>
+ )
};
-const CustomizedAxisTick = ({ x, y, stroke, payload }) =>{
+const CustomizedAxisTick = ({ x, y, payload }) =>{
+ 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)">{payload.value}</text>
+ <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>
);
}
@@ -48,27 +58,23 @@ const ChartReportPage = () => {
const [type, setType] = useState('speed');
return (
- <ReportLayoutPage reportFilterForm={ReportFilterForm} setItems={setItems} >
- <Card>
- <CardHeader action={<ChartType type={type} setType={setType}/>} />
- <Divider />
- <CardContent>
- <Box height={400} position="relative">
- <ResponsiveContainer>
- <LineChart data={items}>
- <XAxis dataKey="fixTime" interval="preserveStartEnd" height={60} tick={<CustomizedAxisTick/>} />
- <YAxis />
- <CartesianGrid strokeDasharray="3 3" />
- <Tooltip />
- <Legend />
- <Line type="monotone" dataKey={type} stroke="#8884d8" />
- </LineChart>
- </ResponsiveContainer>
- </Box>
- </CardContent>
- </Card>
+ <ReportLayoutPage reportFilterForm={ReportFilterForm} setItems={setItems} setType={setType}>
+ <Paper>
+ <Box height={400}>
+ <ResponsiveContainer>
+ <LineChart data={items}>
+ <XAxis dataKey="fixTime" tick={<CustomizedAxisTick/>} height={60} />
+ <YAxis />
+ <CartesianGrid strokeDasharray="3 3" />
+ <Tooltip />
+ <Legend />
+ <Line type="natural" dataKey={type} />
+ </LineChart>
+ </ResponsiveContainer>
+ </Box>
+ </Paper>
</ReportLayoutPage>
);
-}
+};
export default ChartReportPage;
diff --git a/modern/src/reports/ChartType.js b/modern/src/reports/ChartType.js
deleted file mode 100644
index 586ea88a..00000000
--- a/modern/src/reports/ChartType.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import React from 'react';
-import { FormControl, Select, MenuItem } from '@material-ui/core';
-import { makeStyles } from '@material-ui/core/styles';
-import t from '../common/localization';
-
-const useStyles = makeStyles((theme) => ({
- formControl: {
- minWidth: 160,
- },
-}));
-
-const ChartType = ({ type, setType }) => {
- const classes = useStyles();
-
- return (
- <FormControl className={classes.formControl}>
- <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>
- <MenuItem value="index">{t('positionIndex')}</MenuItem>
- <MenuItem value="hdop">{t('positionHdop')}</MenuItem>
- <MenuItem value="vdop">{t('positionVdop')}</MenuItem>
- <MenuItem value="pdop">{t('positionPdop')}</MenuItem>
- <MenuItem value="sat">{t('positionSat')}</MenuItem>
- <MenuItem value="satVisible">{t('positionSatVisible')}</MenuItem>
- <MenuItem value="rssi">{t('positionRssi')}</MenuItem>
- <MenuItem value="gps">{t('positionGps')}</MenuItem>
- <MenuItem value="odometer">{t('positionOdometer')}</MenuItem>
- <MenuItem value="serviceOdometer">{t('positionServiceOdometer')}</MenuItem>
- <MenuItem value="tripOdometer">{t('positionTripOdometer')}</MenuItem>
- <MenuItem value="hours">{t('positionHours')}</MenuItem>
- <MenuItem value="steps">{t('positionSteps')}</MenuItem>
- <MenuItem value="power">{t('positionPower')}</MenuItem>
- <MenuItem value="battery">{t('positionBattery')}</MenuItem>
- <MenuItem value="batteryLevel">{t('positionBatteryLevel')}</MenuItem>
- <MenuItem value="fuel">{t('positionFuel')}</MenuItem>
- <MenuItem value="fuelConsumption">{t('positionFuelConsumption')}</MenuItem>
- <MenuItem value="distance">{t('positionDistance')}</MenuItem>
- <MenuItem value="totalDistance">{t('deviceTotalDistance')}</MenuItem>
- <MenuItem value="rpm">{t('positionRpm')}</MenuItem>
- <MenuItem value="throttle">{t('positionThrottle')}</MenuItem>
- <MenuItem value="armed">{t('positionArmed')}</MenuItem>
- <MenuItem value="acceleration">{t('positionAcceleration')}</MenuItem>
- <MenuItem value="deviceTemp">{t('positionDeviceTemp')}</MenuItem>
- <MenuItem value="obdSpeed">{t('positionObdSpeed')}</MenuItem>
- <MenuItem value="obdOdometer">{t('positionObdOdometer')}</MenuItem>
- </Select>
- </FormControl>
- );
-}
-
-export default ChartType;
diff --git a/modern/src/reports/ReportLayoutPage.js b/modern/src/reports/ReportLayoutPage.js
index ddc7325b..e4219bfd 100644
--- a/modern/src/reports/ReportLayoutPage.js
+++ b/modern/src/reports/ReportLayoutPage.js
@@ -18,7 +18,7 @@ const useStyles = makeStyles(theme => ({
},
}));
-const ReportLayoutPage = ({ reportFilterForm:ReportFilterForm, setItems, children }) => {
+const ReportLayoutPage = ({ reportFilterForm:ReportFilterForm, setItems, setType, children }) => {
const classes = useStyles();
return (
<div className={classes.root}>
@@ -27,7 +27,7 @@ const ReportLayoutPage = ({ reportFilterForm:ReportFilterForm, setItems, childre
<Grid container spacing={2}>
<Grid item xs={12} md={3} lg={2}>
<Paper className={classes.form}>
- <ReportFilterForm setItems={ setItems } />
+ <ReportFilterForm setItems={ setItems } setType={ setType }/>
</Paper>
</Grid>
<Grid item xs={12} md={9} lg={10}>