diff --git a/index.html b/index.html index 9ce1009..314b07c 100644 --- a/index.html +++ b/index.html @@ -213,14 +213,10 @@
- -
-
- -
+ +
+
+
@@ -232,6 +228,18 @@
+
+ +
+
+ +
+
+
+
diff --git a/main.js b/main.js index 8d4e4e7..3906552 100644 --- a/main.js +++ b/main.js @@ -58,9 +58,12 @@ function reload() { interchangeTimeForTrains = Number(document.getElementById("interchangeTimesForTrains").value); intensityByTravelTimeMaxTime = Number(document.getElementById("intensityByTravelTimeMaxTime").value); maxTransparency = Number(document.getElementById("maxTransparency").value); + updateGradientPicker(); clipToBoundaries = document.getElementById("boundaries").value === "true"; enableAreaLayer = document.getElementById("useArea").value === "true"; updateHeatLegend(intensityByTravelTimeMaxTime); + heatmapLayer.options.gradient = gradient; + heatmapLayer._updateOptions(); if (!lastPosition) return; const [lat, lng] = lastPosition; updateOrigin(lat, lng) @@ -116,6 +119,65 @@ function updateHeatLegend(value) { document.getElementById("heat-legend-5").innerHTML = `${value}`; } +function removeGradientPicker(index) { + updateGradientPicker(index); + reload(); +} + +function updateGradientPicker(ignore = undefined) { + const newGradient = {}; + for (let index = 1; ; index++) { + if (index === ignore) { + continue; + } + const positionElement = document.getElementById(`gradient-position-${index}`); + const valueElement = document.getElementById(`gradient-value-${index}`); + if (!positionElement || !valueElement) { + break; + } + if (!newGradient.hasOwnProperty(positionElement.value) || gradientPickerPriority === index) { + newGradient[positionElement.value] = valueElement.value; + } + } + if (Object.keys(newGradient).length > 0) { + gradient = newGradient; + } + generateGradientPicker(gradient); + drawHeatLegend(); +} + +function addGradientPicker() { + let newValue = 1; + for (const position of Object.keys(gradient).sort((a, b) => Number(b) - Number(a))) { + if (Number(position) === newValue) { + newValue = Number((newValue - 0.05).toFixed(2)); + } + } + if (newValue >= 0 && newValue <= 1) { + gradient[newValue] = "#FF0000"; + } + generateGradientPicker(gradient); + reload(); +} + +function generateGradientPicker(value) { + const div = document.getElementById("gradient-picker"); + let innerHTML = ""; + const entries = Object.entries(value).sort(([a], [b]) => Number(b) - Number(a)); + let counter = 1; + for (const [position, value] of entries) { + const index = counter++; + innerHTML += ` +
+ + + +
+ `; + } + div.innerHTML = innerHTML; +} + function initMap() { tileLayers.clearLayers(); if (basemapUrl) { @@ -639,6 +701,16 @@ let interchangeTimeForTrains = 90; let walkableDistance = 1.5; let clipToBoundaries = false; let enableAreaLayer = false; +let gradient = { + 0.1: "#0000FF", + 0.6: "#00FFFF", + 0.8: "#00FF00", + 0.9: "#FFFF00", + 1.0: "#FF0000" +} + +let gradientPickerPriority = null; +generateGradientPicker(gradient); const hongKongBounds = { minLat: 22.14, maxLat: 22.57, @@ -661,13 +733,6 @@ const tileLayers = L.layerGroup().addTo(map); initMap(); const droppedPinLayer = L.layerGroup().addTo(map); -const gradient = { - 0.1: "blue", - 0.6: "cyan", - 0.8: "lime", - 0.9: "yellow", - 1.0: "red" -} const transitPointLayer = L.markerClusterGroup({spiderfyOnMaxZoom: false, disableClusteringAtZoom: 16}).addTo(map); diff --git a/style.css b/style.css index 2cae377..e5f243a 100644 --- a/style.css +++ b/style.css @@ -199,6 +199,39 @@ html { display: flex; } +.gradient-entry { + display: flex; + justify-content: space-between; +} + +.gradient-entry + .gradient-entry { + margin-top: 10px; +} + +.gradient-position { + max-width: 30%; + width: 30% +} + +.gradient-color { + max-width: 51%; + width: 51%; +} + +.gradient-add { + width: 100%; + margin-top: 10px; +} + +.gradient-remove { + width: 15%; +} + +.error { + border: 1px solid red !important; + box-shadow: 0 0 0 3px #ff000054 !important; +} + .options-button { display: none; position: fixed;