diff options
Diffstat (limited to 'modern/src')
-rw-r--r-- | modern/src/App.js | 2 | ||||
-rw-r--r-- | modern/src/MainToolbar.js | 2 | ||||
-rw-r--r-- | modern/src/common/converter.js | 13 | ||||
-rw-r--r-- | modern/src/reports/ChartReportPage.js | 72 | ||||
-rw-r--r-- | modern/src/reports/EventReportPage.js | 4 | ||||
-rw-r--r-- | modern/src/reports/Graph.js | 35 | ||||
-rw-r--r-- | modern/src/reports/ReportLayoutPage.js | 4 | ||||
-rw-r--r-- | modern/src/reports/RouteReportPage.js | 4 | ||||
-rw-r--r-- | modern/src/reports/StopReportPage.js | 4 | ||||
-rw-r--r-- | modern/src/reports/SummaryReportPage.js | 4 | ||||
-rw-r--r-- | modern/src/reports/TripReportPage.js | 4 |
11 files changed, 135 insertions, 13 deletions
diff --git a/modern/src/App.js b/modern/src/App.js index 8a308c17..83fd9315 100644 --- a/modern/src/App.js +++ b/modern/src/App.js @@ -21,6 +21,7 @@ import { LinearProgress } from '@material-ui/core'; import TripReportPage from './reports/TripReportPage'; import StopReportPage from './reports/StopReportPage'; import SummaryReportPage from './reports/SummaryReportPage'; +import ChartReportPage from './reports/ChartReportPage'; const App = () => { const initialized = useSelector(state => !!state.session.server && !!state.session.user); @@ -50,6 +51,7 @@ const App = () => { <Route exact path='/reports/trip' component={TripReportPage} /> <Route exact path='/reports/stop' component={StopReportPage} /> <Route exact path='/reports/summary' component={SummaryReportPage} /> + <Route exact path='/reports/chart' component={ChartReportPage} /> </Switch> )} </Route> diff --git a/modern/src/MainToolbar.js b/modern/src/MainToolbar.js index 5b94b147..930e66a0 100644 --- a/modern/src/MainToolbar.js +++ b/modern/src/MainToolbar.js @@ -141,7 +141,7 @@ const MainToolbar = () => { </ListItemIcon> <ListItemText primary={t('reportSummary')} /> </ListItem> - <ListItem button disabled> + <ListItem button onClick={() => history.push('/reports/chart')}> <ListItemIcon> <TrendingUpIcon /> </ListItemIcon> diff --git a/modern/src/common/converter.js b/modern/src/common/converter.js new file mode 100644 index 00000000..e48b0760 --- /dev/null +++ b/modern/src/common/converter.js @@ -0,0 +1,13 @@ +export const speedConverter = (value, unit) => { + let factor; + switch (unit) { + case 'kmh': + factor = 1.852; + case 'mph': + factor = 1.15078; + case 'kn': + default: + factor = 1; + } + return (value * factor).toFixed(2); +}; diff --git a/modern/src/reports/ChartReportPage.js b/modern/src/reports/ChartReportPage.js new file mode 100644 index 00000000..543c8a9e --- /dev/null +++ b/modern/src/reports/ChartReportPage.js @@ -0,0 +1,72 @@ +import React, { useState } from 'react'; +import { FormControl, InputLabel, Select, MenuItem } from '@material-ui/core'; +import ReportLayoutPage from './ReportLayoutPage'; +import ReportFilter from './ReportFilter'; +import Graph from './Graph'; +import { useAttributePreference } from '../common/preferences'; +import { formatDate } from '../common/formatter'; +import { speedConverter } from '../common/converter'; +import t from '../common/localization'; + +const Filter = ({ children, 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 positions = await response.json(); + let formattedPositions = positions.map(position => { + return { + speed: Number(speedConverter(position.speed, speedUnit)), + altitude: position.altitude, + accuracy: position.accuracy, + fixTime: formatDate(position.fixTime) + } + }); + setItems(formattedPositions); + } + } + return ( + <> + <ReportFilter handleSubmit={handleSubmit} showOnly /> + {children} + </> + ) +} + +const ChartType = ({ type, setType }) => { + + return ( + <FormControl variant="filled" margin="normal" 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> + </Select> + </FormControl> + ) +} + + +const ChartReportPage = () => { + + const [items, setItems] = useState([]); + const [type, setType] = useState('speed'); + + return ( + <> + <ReportLayoutPage filter={ + <Filter setItems={setItems}> + <ChartType type={type} setType={setType} /> + </Filter> + }> + <Graph items={items} type={type} /> + </ReportLayoutPage> + </> + ) +} + +export default ChartReportPage; diff --git a/modern/src/reports/EventReportPage.js b/modern/src/reports/EventReportPage.js index 13e081e2..054181d0 100644 --- a/modern/src/reports/EventReportPage.js +++ b/modern/src/reports/EventReportPage.js @@ -6,7 +6,7 @@ import { formatPosition } from '../common/formatter'; import ReportFilter from './ReportFilter'; import ReportLayoutPage from './ReportLayoutPage'; -const ReportFilterForm = ({ setItems }) => { +const Filter = ({ setItems }) => { const [eventTypes, setEventTypes] = useState(['allEvents']); @@ -60,7 +60,7 @@ const EventReportPage = () => { const [items, setItems] = useState([]); return ( - <ReportLayoutPage reportFilterForm={ReportFilterForm} setItems={setItems}> + <ReportLayoutPage filter={<Filter setItems={setItems} />}> <TableContainer component={Paper}> <Table> <TableHead> diff --git a/modern/src/reports/Graph.js b/modern/src/reports/Graph.js new file mode 100644 index 00000000..af54e10e --- /dev/null +++ b/modern/src/reports/Graph.js @@ -0,0 +1,35 @@ +import React from 'react'; +import { Box, Paper } from '@material-ui/core'; +import {LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts'; + +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)">{parts[0]}</text> + <text x={0} y={16} dy={16} textAnchor="end" fill="#666" transform="rotate(-35)">{parts[1]}</text> + </g> + ); +} + +const Graph = ({ type, items }) => { + + return ( + <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> + ); +} + +export default Graph; diff --git a/modern/src/reports/ReportLayoutPage.js b/modern/src/reports/ReportLayoutPage.js index ddc7325b..d6fac051 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 = ({ children, filter }) => { 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 } /> + {filter} </Paper> </Grid> <Grid item xs={12} md={9} lg={10}> diff --git a/modern/src/reports/RouteReportPage.js b/modern/src/reports/RouteReportPage.js index 43d310be..f2b03616 100644 --- a/modern/src/reports/RouteReportPage.js +++ b/modern/src/reports/RouteReportPage.js @@ -5,7 +5,7 @@ import { formatPosition } from '../common/formatter'; import ReportFilter from './ReportFilter'; import ReportLayoutPage from './ReportLayoutPage'; -const ReportFilterForm = ({ setItems }) => { +const Filter = ({ setItems }) => { const handleSubmit = async (deviceId, from, to, mail, headers) => { const query = new URLSearchParams({ deviceId, from, to, mail }); @@ -30,7 +30,7 @@ const RouteReportPage = () => { const [items, setItems] = useState([]); return ( - <ReportLayoutPage reportFilterForm={ReportFilterForm} setItems={setItems}> + <ReportLayoutPage filter={<Filter setItems={setItems} />}> <TableContainer component={Paper}> <Table> <TableHead> diff --git a/modern/src/reports/StopReportPage.js b/modern/src/reports/StopReportPage.js index 77d3dfa7..d06997e2 100644 --- a/modern/src/reports/StopReportPage.js +++ b/modern/src/reports/StopReportPage.js @@ -6,7 +6,7 @@ import ReportFilter from './ReportFilter'; import ReportLayoutPage from './ReportLayoutPage'; import { useAttributePreference } from '../common/preferences'; -const ReportFilterForm = ({ setItems }) => { +const Filter = ({ setItems }) => { const handleSubmit = async (deviceId, from, to, mail, headers) => { const query = new URLSearchParams({ deviceId, from, to, mail }); @@ -32,7 +32,7 @@ const StopReportPage = () => { const [items, setItems] = useState([]); return ( - <ReportLayoutPage reportFilterForm={ReportFilterForm} setItems={setItems}> + <ReportLayoutPage filter={<Filter setItems={setItems} />}> <TableContainer component={Paper}> <Table> <TableHead> diff --git a/modern/src/reports/SummaryReportPage.js b/modern/src/reports/SummaryReportPage.js index dcd3323c..5cfd857d 100644 --- a/modern/src/reports/SummaryReportPage.js +++ b/modern/src/reports/SummaryReportPage.js @@ -6,7 +6,7 @@ import ReportFilter from './ReportFilter'; import ReportLayoutPage from './ReportLayoutPage'; import { useAttributePreference } from '../common/preferences'; -const ReportFilterForm = ({ setItems }) => { +const Filter = ({ setItems }) => { const [daily, setDaily] = useState(false); @@ -41,7 +41,7 @@ const SummaryReportPage = () => { const [items, setItems] = useState([]); return ( - <ReportLayoutPage reportFilterForm={ReportFilterForm} setItems={setItems}> + <ReportLayoutPage filter={<Filter setItems={setItems} />}> <TableContainer component={Paper}> <Table> <TableHead> diff --git a/modern/src/reports/TripReportPage.js b/modern/src/reports/TripReportPage.js index 10f1c464..c1ba6646 100644 --- a/modern/src/reports/TripReportPage.js +++ b/modern/src/reports/TripReportPage.js @@ -6,7 +6,7 @@ import ReportFilter from './ReportFilter'; import ReportLayoutPage from './ReportLayoutPage'; import { useAttributePreference } from '../common/preferences'; -const ReportFilterForm = ({ setItems }) => { +const Filter = ({ setItems }) => { const handleSubmit = async (deviceId, from, to, mail, headers) => { const query = new URLSearchParams({ deviceId, from, to, mail }); @@ -33,7 +33,7 @@ const TripReportPage = () => { const [items, setItems] = useState([]); return ( - <ReportLayoutPage reportFilterForm={ReportFilterForm} setItems={setItems}> + <ReportLayoutPage filter={<Filter setItems={setItems} />}> <TableContainer component={Paper}> <Table> <TableHead> |