From f4a232b760b25d8a3cc708f32696dff13fdfc19a Mon Sep 17 00:00:00 2001 From: liamcottle Date: Tue, 20 Aug 2024 18:47:50 +1200 Subject: [PATCH] a few changes to position history feature --- src/index.js | 21 ++++--- src/public/index.html | 138 +++++++++++++++++++++++------------------- 2 files changed, 88 insertions(+), 71 deletions(-) diff --git a/src/index.js b/src/index.js index 6f8245d..42b2790 100644 --- a/src/index.js +++ b/src/index.js @@ -431,10 +431,16 @@ app.get('/api/v1/nodes/:nodeId/traceroutes', async (req, res) => { app.get('/api/v1/nodes/:nodeId/position-history', async (req, res) => { try { - const nodeId = parseInt(req.params.nodeId); - const timeFrom = req.query.time_from ? parseInt(req.query.time_from) : new Date().getTime() - 3600 * 1000; - const timeTo = req.query.time_to ? parseInt(req.query.time_to) : new Date().getTime(); + // defaults + const nowInMilliseconds = new Date().getTime(); + const oneHourAgoInMilliseconds = new Date().getTime() - (3600 * 1000); + // get request params + const nodeId = parseInt(req.params.nodeId); + const timeFrom = req.query.time_from ? parseInt(req.query.time_from) : oneHourAgoInMilliseconds; + const timeTo = req.query.time_to ? parseInt(req.query.time_to) : nowInMilliseconds; + + // find node const node = await prisma.node.findFirst({ where: { node_id: nodeId, @@ -477,8 +483,7 @@ app.get('/api/v1/nodes/:nodeId/position-history', async (req, res) => { latitude: position.latitude, longitude: position.longitude, altitude: position.altitude, - accuracy: position.accuracy, - time: position.created_at, + created_at: position.created_at, }); }); @@ -488,12 +493,12 @@ app.get('/api/v1/nodes/:nodeId/position-history', async (req, res) => { latitude: mapReport.latitude, longitude: mapReport.longitude, altitude: mapReport.altitude, - accuracy: mapReport.accuracy, - time: mapReport.created_at, + created_at: mapReport.created_at, }); }); - positionHistory.sort((a, b) => a.time - b.time); + // sort oldest to newest + positionHistory.sort((a, b) => a.created_at - b.created_at); res.json({ position_history: positionHistory, diff --git a/src/public/index.html b/src/public/index.html index 9b03c6c..f27e51e 100644 --- a/src/public/index.html +++ b/src/public/index.html @@ -66,6 +66,12 @@ border: 1px solid white; } + .icon-position-history { + background-color: #a855f7; + border-radius: 25px; + border: 1px solid white; + } + .waypoint-label { font-size: 26px; background-color: transparent; @@ -751,8 +757,8 @@
Position
-
@@ -1610,26 +1616,13 @@
-
-
-
-

{{ selectedNodeToShowPositionHistory.short_name }} Position history

-
-
- - -
-
- - -
-
- -
-
+
+
+
{{ selectedNodeToShowPositionHistory.short_name }} Position History
+
- +
+ + +
+ + +
+ + +
+ + +
+ +
@@ -1812,8 +1820,9 @@ selectedNodeMqttMetrics: [], selectedNodeTraceroutes: [], - positionHistoryFromTimeDate: new Date(new Date().getTime() - 3600 * 1000).toISOString().slice(0, 16), - positionHistoryToTimeDate: new Date().toISOString().slice(0, 16), + // YYYY-MM-DDTHH:mm is the format expected by the datetime-local input type + positionHistoryDateTimeFrom: moment().subtract(1, "hours").format('YYYY-MM-DDTHH:mm'), + positionHistoryDateTimeTo: moment().format('YYYY-MM-DDTHH:mm'), selectedNodePositionHistory: [], selectedNodeToShowPositionHistory: null, selectedNodePositionHistoryMarkers: [], @@ -1847,7 +1856,7 @@ this.loadNodePowerMetrics(node.node_id); this.loadNodeMqttMetrics(node.node_id); this.loadNodeTraceroutes(node.node_id); - this.loadNodePositionHistory(node.node_id); + //this.loadNodePositionHistory(node.node_id); }; // handle node callback from outside of vue @@ -1944,12 +1953,15 @@ }, loadNodePositionHistory: function(nodeId) { this.selectedNodePositionHistory = []; - window.axios.get(`/api/v1/nodes/${nodeId}/position-history?time_from=${new Date(this.positionHistoryFromTimeDate).getTime()}&time_to=${new Date(this.positionHistoryToTimeDate).getTime()}`).then((response) => { + window.axios.get(`/api/v1/nodes/${nodeId}/position-history`, { + params: { + // parse from datetime-local format, and send as unix timestamp in milliseconds + time_from: moment(this.positionHistoryDateTimeFrom, "YYYY-MM-DDTHH:mm").format("x"), + time_to: moment(this.positionHistoryDateTimeTo, "YYYY-MM-DDTHH:mm").format("x"), + }, + }).then((response) => { this.selectedNodePositionHistory = response.data.position_history; - - console.log(this.selectedNodePositionHistory); - - if (this.selectedNodeToShowPositionHistory != null) { + if(this.selectedNodeToShowPositionHistory != null){ clearAllPositionHistory(); onPositionHistoryUpdated(response.data.position_history); } @@ -2570,10 +2582,21 @@ getRegionFrequencyRange: function(regionName) { return window.getRegionFrequencyRange(regionName); }, - handleNodePositionHistory: function(nodeId) { - this.selectedNodeToShowPositionHistory = this.selectedNode - this.selectedNode = null - onPositionHistoryUpdated(this.selectedNodePositionHistory) + showNodePositionHistory: function(nodeId) { + + // find node + const node = findNodeById(nodeId); + if(!node){ + return; + } + + // update ui + this.selectedNode = null; + this.selectedNodeToShowPositionHistory = node; + + // load position history + this.loadNodePositionHistory(nodeId); + }, getShareLinkForNode: function(nodeId) { return window.location.origin + `/?node_id=${nodeId}`; @@ -2599,11 +2622,11 @@ this.selectedNodeToShowNeighbours = null; }, dismissShowingNodePositionHistory: function() { - this.selectedNodePositionHistory = [], - this.selectedNodeToShowPositionHistory = null - this.selectedNodePositionHistoryMarkers = [], - this.selectedNodePositionHistoryPolyLines = [], - cleanUpPositionHistory() + this.selectedNodePositionHistory = []; + this.selectedNodeToShowPositionHistory = null; + this.selectedNodePositionHistoryMarkers = []; + this.selectedNodePositionHistoryPolyLines = []; + cleanUpPositionHistory(); }, formatUptimeSeconds: function(secondsToFormat) { secondsToFormat = Number(secondsToFormat); @@ -2792,6 +2815,11 @@ iconSize: [16, 16], // increase from 12px to 16px to make hover easier }); + var iconPositionHistory = L.divIcon({ + className: 'icon-position-history', + iconSize: [16, 16], // increase from 12px to 16px to make hover easier + }); + // create legend var legendLayerGroup = new L.LayerGroup(); var legend = L.control({position: 'bottomleft'}); @@ -3608,14 +3636,13 @@ } function onPositionHistoryUpdated(updatedPositionHistories) { - let positionHistoryMarkers = []; - let positionHistoryLines = []; + let positionHistoryLinesCords = []; // add nodes for(var positionHistory of updatedPositionHistories) { - // skip nodes without position + // skip position history without position if(!positionHistory.latitude || !positionHistory.longitude){ continue; } @@ -3623,10 +3650,8 @@ // fix lat long positionHistory.latitude = positionHistory.latitude / 10000000; positionHistory.longitude = positionHistory.longitude / 10000000; - var hasLocation = isValidLatLng(positionHistory.latitude, positionHistory.longitude); - if(hasLocation){ // wrap longitude for shortest path, everything to left of australia should be shown on the right @@ -3635,25 +3660,15 @@ longitude += 360; } - positionHistoryLinesCords.push([positionHistory.latitude, longitude]) + positionHistoryLinesCords.push([positionHistory.latitude, longitude]); - // determine emoji to show as marker icon - const emoji = 128205; - const emojiText = String.fromCodePoint(emoji) - - let tooltip = "" - - tooltip += `Position: ${positionHistory.latitude}, ${positionHistory.longitude}
` - tooltip += `Heard by:
` - tooltip += `Timestamp: ${new Date(positionHistory.time).toLocaleString()}
` + let tooltip = ""; + tooltip += `${moment(new Date(positionHistory.created_at)).format("DD/MM/YYYY hh:mm A")}
`; + tooltip += `Position: ${positionHistory.latitude}, ${positionHistory.longitude}
`; // create position history marker const marker = L.marker([positionHistory.latitude, longitude],{ - icon: L.divIcon({ - className: 'waypoint-label', - iconSize: [26, 26], // increase from 12px to 26px - html: emojiText, - }), + icon: iconPositionHistory, }).bindPopup(tooltip).on('click', function(event) { // close tooltip on click to prevent tooltip and popup showing at same time event.target.closeTooltip(); @@ -3662,15 +3677,12 @@ // add marker to position history layer group marker.addTo(nodePositionHistoryLayerGroup); - positionHistoryMarkers.push(marker) - } } - const line = L.polyline(positionHistoryLinesCords).addTo(nodePositionHistoryLayerGroup); - - positionHistoryLines.push(line) + // show lines between position history markers + L.polyline(positionHistoryLinesCords).addTo(nodePositionHistoryLayerGroup); }