diff options
Diffstat (limited to 'modern')
-rw-r--r-- | modern/src/common/chartTypes.js | 7 | ||||
-rw-r--r-- | modern/src/common/formatter.js | 25 | ||||
-rw-r--r-- | modern/src/reports/ChartReportPage.js | 90 | ||||
-rw-r--r-- | modern/src/reports/ChartType.js | 53 | ||||
-rw-r--r-- | modern/src/reports/ReportLayoutPage.js | 4 |
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}> |