Finish off initial voronoi diagram implementation & update changelog.

Next up, we need to reconnect the UI
This commit is contained in:
Starbeamrainbowlabs 2019-06-11 13:45:26 +01:00
parent 4df93a3683
commit 38345222e7
Signed by: sbrl
GPG Key ID: 1BE5172E637709C2
5 changed files with 37 additions and 25 deletions

View File

@ -1,5 +1,8 @@
# Changelog # Changelog
# v0.10
- Change heatmap into a voronoi diagram ([#30](https://github.com/ConnectedHumber/Air-Quality-Web/issues/30))
# v0.9.2 - 3rd June 2019 # v0.9.2 - 3rd June 2019
- [API] Updated the [API documentation](https://aq.connectedhumber.org/__nightdocs/05-API-Docs.html) with a quick reference of the available actions at the top. - [API] Updated the [API documentation](https://aq.connectedhumber.org/__nightdocs/05-API-Docs.html) with a quick reference of the available actions at the top.

View File

@ -14,24 +14,20 @@ import Vector2 from '../Helpers/Vector2.mjs';
import GetFromUrl from '../Helpers/GetFromUrl.mjs'; import GetFromUrl from '../Helpers/GetFromUrl.mjs';
class VoronoiManager { class VoronoiManager {
get layer() { return this.overlay.layer; }
constructor(in_device_data, map) { constructor(in_device_data, in_map) {
this.device_data = in_device_data; this.device_data = in_device_data;
this.map = in_map;
this.layer = null;
this.setup_overlay(map);
this.setup_guage(); this.setup_guage();
this.setup_overlay();
} }
setup_overlay(map) { setup_overlay() {
this.overlay = new VoronoiOverlay(); this.overlay = new VoronoiOverlay();
this.overlay.addCells(...this.device_data.devices this.set_data(new Date(), "PM25"); // TODO: Make this customisable
.filter((device) => typeof device.latitude == "number" &&
typeof device.longitude == "number")
.map((device) =>
new VoronoiCell(new Vector2(device.longitude, device.latitude))
));
this.overlay.add_to(map);
} }
setup_guage() { setup_guage() {
@ -60,11 +56,19 @@ class VoronoiManager {
device.longitude, device.longitude,
device.latitude device.latitude
), ),
// See https://gka.github.io/chroma.js/
this.spec.chroma(row.value).toString() this.spec.chroma(row.value).toString()
)); ));
} }
this.overlay.set_cells(result);
if(this.layer !== null)
this.layer.remove(); // Remove the old layer if it exists
// Generate & add the new layer
this.layer = this.overlay.generate_layer();
this.layer.addTo(this.map);
console.log(result); console.log(result);
} }
} }

View File

@ -20,15 +20,15 @@ class VoronoiOverlay {
* Sets the list of cells in the voronoi overlay. * Sets the list of cells in the voronoi overlay.
* @param {VoronoiCell[]} cells The cells to add, as an array. * @param {VoronoiCell[]} cells The cells to add, as an array.
*/ */
setCells(cells) { set_cells(cells) {
this.cells.length = 0; this.cells.length = 0;
this.addCells(...cells); this.add_cells(...cells);
} }
/** /**
* Adds a cell to the voronoi overlay. * Adds a cell to the voronoi overlay.
* @param {VoronoiCell} cells The cell to add. May be specified as many times as requires to add cells in bulk. * @param {VoronoiCell} cells The cell to add. May be specified as many times as requires to add cells in bulk.
*/ */
addCells(...cells) { add_cells(...cells) {
this.cells.push(...cells); this.cells.push(...cells);
} }
@ -99,23 +99,21 @@ class VoronoiOverlay {
"coordinates": [cell.polygon.map((point) => [point.x, point.y])], "coordinates": [cell.polygon.map((point) => [point.x, point.y])],
}, },
"properties": { "properties": {
// TODO: Replace this with an actual colour "colour": cell.colour == null ? "hsl(0, 100%, 100%)" : cell.colour
"colour": `hsl(${(Math.random()*360).toFixed(2)}, 50%, 50%)`
} }
}); });
} }
return geojson; return geojson;
} }
add_to(map) { generate_layer() {
this.layer = L.geoJSON(this.render(), { return L.geoJSON(this.render(), {
style: (feature) => { return { color: feature.properties.colour } } // FUTURE: If we want to be even moar fanceh, we can check out https://leafletjs.com/reference-1.5.0.html#path
style: (feature) => { return {
color: feature.properties.colour,
fillOpacity: 0.4
} }
}); });
this.layer.addTo(map);
}
generate_overlay() {
// TODO: Generate the Leaflet SVGOverlay here
} }
} }

6
package-lock.json generated
View File

@ -30,6 +30,12 @@
"integrity": "sha512-z4j5PWjQff3qGF+5nJIegI5b7drtGA6+XAxoAOINZYkkUuwlmBvjbGtruUAugbaxQkLcCklKZ88dZaPSnFNggg==", "integrity": "sha512-z4j5PWjQff3qGF+5nJIegI5b7drtGA6+XAxoAOINZYkkUuwlmBvjbGtruUAugbaxQkLcCklKZ88dZaPSnFNggg==",
"dev": true "dev": true
}, },
"@types/chroma-js": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-1.4.1.tgz",
"integrity": "sha512-i9hUiO3bwgmzZUDwBuR65WqsBQ/nwN+H2fKX0bykXCdd8cFQEuIj8vI7FXjyb2f5z5h+pv76I/uakikKSgaqTA==",
"dev": true
},
"@types/d3-delaunay": { "@types/d3-delaunay": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-4.1.0.tgz", "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-4.1.0.tgz",

View File

@ -35,6 +35,7 @@
}, },
"devDependencies": { "devDependencies": {
"@types/chart.js": "^2.7.53", "@types/chart.js": "^2.7.53",
"@types/chroma-js": "^1.4.1",
"@types/d3-delaunay": "^4.1.0", "@types/d3-delaunay": "^4.1.0",
"@types/leaflet": "^1.4.4", "@types/leaflet": "^1.4.4",
"@types/leaflet-fullscreen": "^1.0.4", "@types/leaflet-fullscreen": "^1.0.4",