diff options
Diffstat (limited to 'app')
| -rw-r--r-- | app/main.js | 11 | ||||
| -rw-r--r-- | app/map.js | 185 |
2 files changed, 87 insertions, 109 deletions
diff --git a/app/main.js b/app/main.js index 2485cb1..5bd3534 100644 --- a/app/main.js +++ b/app/main.js @@ -603,8 +603,15 @@ export class App { this.#filtered = houses.slice(); if (this.#map) { - this.#map.initialize(districts, coastLine, mainRoads, trainTracks, trainStations); - this.#map.setHouses(houses, this.#colorParameter); + this.#map.initialize( + districts, + coastLine, + mainRoads, + trainTracks, + trainStations, + houses, + this.#colorParameter, + ); } // Populate district multi-select @@ -67,20 +67,10 @@ export class PanningConfig { export class MapEl { /** @type {SVGSVGElement} */ svg; - /** @type {SVGGElement} */ - #housesGroup; - /** @type {SVGGElement} */ - #districtsGroup; - /** @type {SVGGElement} */ - #trainTracksGroup; - /** @type {SVGGElement} */ - #background; - /** @type {SVGGElement} */ - #trainStationsGroup; /** @type {House[]} */ #houses = []; - /** @type {string} */ - #colorParameter = ColorParameter.price; + /** @type {SVGGElement|null} */ + #housesGroup = null; /** @type {Function|null} */ #onHouseClick; /** @type {Function} */ @@ -113,76 +103,9 @@ export class MapEl { }), ); - this.#housesGroup = Svg.g( - new SvgOptions({ - attributes: { - "pointer-events": "visiblePainted", - r: "0.003", - stroke: "rgba(51, 51, 51, 1)", - "stroke-linecap": "butt", - "stroke-width": "0.001", - }, - id: "houses", - }), - ); - this.#trainTracksGroup = Svg.g( - new SvgOptions({ - attributes: { - fill: "none", - "pointer-events": "none", - stroke: "rgba(255, 68, 68, 1)", - "stroke-width": "0.001", - }, - id: "train-tracks", - }), - ); - this.#trainStationsGroup = Svg.g( - new SvgOptions({ - attributes: { - fill: "rgba(255, 68, 68, 1)", - "pointer-events": "none", - r: "0.003", - stroke: "rgba(204, 0, 0, 1)", - "stroke-width": "0.001", - }, - id: "train-stations", - }), - ); - this.#districtsGroup = Svg.g( - new SvgOptions({ - attributes: {}, - id: "districts", - }), - ); - this.#background = Svg.g( - new SvgOptions({ - attributes: { - "pointer-events": "none", - "stroke-width": "0.0005", - }, - id: "background", - }), - ); - this.svg = svg; this.#onHouseClick = options.onHouseClick; this.#onHouseHover = options.onHouseHover; - - const transformGroup = Svg.g( - new SvgOptions({ - attributes: { transform: "scale(1, -1)" }, - id: "map-transform", - }), - ); - - transformGroup.append( - this.#background, - this.#districtsGroup, - this.#trainTracksGroup, - this.#trainStationsGroup, - this.#housesGroup, - ); - this.svg.append(transformGroup); this.#enablePanning(this.svg); } @@ -204,22 +127,78 @@ export class MapEl { * @param {Collection} mainRoads * @param {TrainTracks[]} tracks * @param {TrainStation[]} stations + * @param {House[]} houses + * @param {string} colorParameter * @returns {SVGSVGElement} */ - initialize(districts, coastLine, mainRoads, tracks, stations) { + initialize(districts, coastLine, mainRoads, tracks, stations, houses, colorParameter) { + this.#houses = houses; this.#setInitialViewBox(District.bounds(districts)); - this.#districtsGroup.replaceChildren( - ...MapEl.#getDistricts(districts), - ...MapEl.#getDistrictLabels(districts), + const transformGroup = Svg.g( + new SvgOptions({ + attributes: { transform: "scale(1, -1)" }, + children: [ + Svg.g( + new SvgOptions({ + attributes: { + "pointer-events": "none", + "stroke-width": "0.0005", + }, + children: [...MapEl.#getCoastLine(coastLine), ...MapEl.#getRoads(mainRoads)], + id: "background", + }), + ), + Svg.g( + new SvgOptions({ + attributes: { + fill: "none", + "pointer-events": "none", + stroke: "rgba(255, 68, 68, 1)", + "stroke-width": "0.001", + }, + children: MapEl.#getTracks(tracks), + id: "train-tracks", + }), + ), + Svg.g( + new SvgOptions({ + attributes: { + fill: "rgba(255, 68, 68, 1)", + "pointer-events": "none", + r: "0.003", + stroke: "rgba(204, 0, 0, 1)", + "stroke-width": "0.001", + }, + children: MapEl.#getStations(stations), + id: "train-stations", + }), + ), + Svg.g( + new SvgOptions({ + attributes: {}, + children: [...MapEl.#getDistricts(districts), ...MapEl.#getDistrictLabels(districts)], + id: "districts", + }), + ), + Svg.g( + new SvgOptions({ + attributes: { + "pointer-events": "visiblePainted", + r: "0.003", + stroke: "rgba(51, 51, 51, 1)", + "stroke-linecap": "butt", + "stroke-width": "0.001", + }, + children: this.getHouses(houses, colorParameter), + id: "houses", + }), + ), + ], + id: "map-transform", + }), ); + this.svg.append(transformGroup); - this.#trainTracksGroup.replaceChildren(...MapEl.#getTracks(tracks)); - this.#trainStationsGroup.replaceChildren(...MapEl.#getStations(stations)); - - this.#background.replaceChildren( - ...MapEl.#getCoastLine(coastLine), - ...MapEl.#getRoads(mainRoads), - ); const coastBounds = Bounds.union(coastLine.features.map((f) => f.geometry.bounds())); const roadBounds = Bounds.union(mainRoads.features.map((f) => f.geometry.bounds())); this.#fullBounds = Bounds.union([coastBounds, roadBounds]); @@ -436,13 +415,10 @@ export class MapEl { /** * Set houses data and render markers * @param {House[]} houses - * @param {string} [colorParameter=this.#colorParameter] + * @param {ColorParameter} colorParameter */ - setHouses(houses, colorParameter = this.#colorParameter) { - this.#houses = houses; - this.#colorParameter = colorParameter; - - const houseElements = houses.map((house) => { + getHouses(houses, colorParameter) { + return houses.map((house) => { const circle = Svg.circle( house.coordinates, new SvgOptions({ @@ -479,7 +455,6 @@ export class MapEl { }, 200); } }); - circle.addEventListener("click", (e) => { e.stopPropagation(); if (this.#onHouseClick) { @@ -487,10 +462,8 @@ export class MapEl { this.#persistentModal = true; } }); - return circle; }); - this.#housesGroup.replaceChildren(...houseElements); } /** @@ -606,13 +579,11 @@ export class MapEl { /** * Update house colors based on current color parameter - * @param {string} colorParameter + * @param {ColorParameter} colorParameter */ setColorParameter(colorParameter) { - this.#colorParameter = colorParameter; - - const markers = this.#housesGroup.querySelectorAll(".house-marker"); - markers.forEach((marker) => { + const markers = this.#housesGroup?.querySelectorAll(".house-marker"); + markers?.forEach((marker) => { const houseId = marker.id; const house = this.#houses.find((h) => h.id === houseId); if (house) { @@ -628,9 +599,9 @@ export class MapEl { */ updateHouseVisibility(filteredHouseIds) { const filteredSet = new Set(filteredHouseIds); - const markers = this.#housesGroup.querySelectorAll(".house-marker"); + const markers = this.#housesGroup?.querySelectorAll(".house-marker"); - markers.forEach((marker) => { + markers?.forEach((marker) => { const houseId = marker.id; marker.setAttribute("display", filteredSet.has(houseId) ? "" : "none"); }); @@ -654,7 +625,7 @@ export class MapEl { /** * Get color for house based on parameter value * @param {House} house - * @param {string} colorParameter + * @param {ColorParameter} colorParameter * @returns {string} */ static #getHouseColor(house, colorParameter) { |
