aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modern/src/common/attributes/usePositionAttributes.js2
-rw-r--r--modern/src/reports/ChartReportPage.js52
2 files changed, 41 insertions, 13 deletions
diff --git a/modern/src/common/attributes/usePositionAttributes.js b/modern/src/common/attributes/usePositionAttributes.js
index d6ee5805..4b779090 100644
--- a/modern/src/common/attributes/usePositionAttributes.js
+++ b/modern/src/common/attributes/usePositionAttributes.js
@@ -16,6 +16,7 @@ export default (t) => useMemo(() => ({
speed: {
name: t('positionSpeed'),
type: 'number',
+ dataType: 'speed',
},
course: {
name: t('positionCourse'),
@@ -28,6 +29,7 @@ export default (t) => useMemo(() => ({
accuracy: {
name: t('positionAccuracy'),
type: 'number',
+ dataType: 'distance',
},
valid: {
name: t('positionValid'),
diff --git a/modern/src/reports/ChartReportPage.js b/modern/src/reports/ChartReportPage.js
index becdfb57..860d99f0 100644
--- a/modern/src/reports/ChartReportPage.js
+++ b/modern/src/reports/ChartReportPage.js
@@ -13,6 +13,8 @@ import PageLayout from '../common/components/PageLayout';
import ReportsMenu from './components/ReportsMenu';
import usePositionAttributes from '../common/attributes/usePositionAttributes';
import { useCatch } from '../reactHelper';
+import { useAttributePreference } from '../common/util/preferences';
+import { distanceFromMeters, speedFromKnots, volumeFromLiters } from '../common/util/converter';
const useStyles = makeStyles(() => ({
chart: {
@@ -28,14 +30,17 @@ const ChartReportPage = () => {
const positionAttributes = usePositionAttributes(t);
+ const distanceUnit = useAttributePreference('distanceUnit');
+ const speedUnit = useAttributePreference('speedUnit');
+ const volumeUnit = useAttributePreference('volumeUnit');
+
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 values = items.map((it) => it[type]);
+ const minValue = Math.min(...values);
+ const maxValue = Math.max(...values);
+ const valueRange = maxValue - minValue;
const handleSubmit = useCatch(async (deviceId, from, to, mail, headers) => {
const query = new URLSearchParams({
@@ -44,11 +49,32 @@ const ChartReportPage = () => {
const response = await fetch(`/api/reports/route?${query.toString()}`, { headers });
if (response.ok) {
const positions = await response.json();
- const formattedPositions = positions.map((position) => ({
- ...position,
- ...position.attributes,
- fixTime: formatDate(position.fixTime, 'HH:mm:ss'),
- }));
+ const formattedPositions = positions.map((position) => {
+ const data = { ...position, ...position.attributes };
+ const formatted = {};
+ formatted.fixTime = formatDate(position.fixTime, 'HH:mm:ss');
+ Object.keys(data).forEach((key) => {
+ const value = data[key];
+ if (typeof value === 'number') {
+ const definition = positionAttributes[key] || {};
+ switch (definition.dataType) {
+ case 'speed':
+ formatted[key] = speedFromKnots(value, speedUnit).toFixed(2);
+ break;
+ case 'distance':
+ formatted[key] = distanceFromMeters(value, distanceUnit).toFixed(2);
+ break;
+ case 'volume':
+ formatted[key] = volumeFromLiters(value, volumeUnit).toFixed(2);
+ break;
+ default:
+ formatted[key] = value;
+ break;
+ }
+ }
+ });
+ return formatted;
+ });
setItems(formattedPositions);
} else {
throw Error(await response.text());
@@ -79,10 +105,10 @@ const ChartReportPage = () => {
}}
>
<XAxis dataKey="fixTime" />
- <YAxis type="number" domain={[`dataMin - ${dataRange / 5}`, `dataMax + ${dataRange / 5}`]} />
+ <YAxis type="number" domain={[minValue - valueRange / 5, maxValue + valueRange / 5]} />
<CartesianGrid strokeDasharray="3 3" />
- <Tooltip formatter={(value, name) => [value, positionAttributes[name].name]} />
- <Line type="natural" dataKey={type} />
+ <Tooltip formatter={(value, key) => [value, positionAttributes[key].name]} />
+ <Line type="monotone" dataKey={type} />
</LineChart>
</ResponsiveContainer>
</div>