@fusedashlabs/widgets 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +1 -1
- package/dist/components/chart-renderer/element/ui9000-chart-renderer.d.ts +1 -0
- package/dist/components/chart-renderer/element/ui9000-chart-renderer.d.ts.map +1 -1
- package/dist/components/chart-renderer/element/ui9000-chart-renderer.js +12 -1
- package/dist/components/chart-renderer/element/ui9000-chart-renderer.js.map +1 -1
- package/dist/components/chart-renderer/lib/registry.d.ts.map +1 -1
- package/dist/components/chart-renderer/lib/registry.js +17 -4
- package/dist/components/chart-renderer/lib/registry.js.map +1 -1
- package/dist/components/chart-renderer/lib/types.d.ts +5 -0
- package/dist/components/chart-renderer/lib/types.d.ts.map +1 -1
- package/dist/components/donut-chart/element/ui9000-donut-chart.js +1 -1
- package/dist/components/donut-chart/element/ui9000-donut-chart.js.map +1 -1
- package/dist/components/lollipop/element/styles.d.ts.map +1 -1
- package/dist/components/lollipop/element/styles.js +19 -1
- package/dist/components/lollipop/element/styles.js.map +1 -1
- package/dist/components/lollipop/element/ui9000-lollipop.d.ts +6 -1
- package/dist/components/lollipop/element/ui9000-lollipop.d.ts.map +1 -1
- package/dist/components/lollipop/element/ui9000-lollipop.js +68 -7
- package/dist/components/lollipop/element/ui9000-lollipop.js.map +1 -1
- package/dist/components/lollipop/index.d.ts +1 -1
- package/dist/components/lollipop/index.d.ts.map +1 -1
- package/dist/components/lollipop/index.js +2 -0
- package/dist/components/lollipop/index.js.map +1 -1
- package/dist/components/lollipop/lib/domain.d.ts +16 -1
- package/dist/components/lollipop/lib/domain.d.ts.map +1 -1
- package/dist/components/lollipop/lib/domain.js +56 -1
- package/dist/components/lollipop/lib/domain.js.map +1 -1
- package/dist/components/lollipop/lib/index.d.ts +3 -2
- package/dist/components/lollipop/lib/index.d.ts.map +1 -1
- package/dist/components/lollipop/lib/layout.d.ts +16 -0
- package/dist/components/lollipop/lib/layout.d.ts.map +1 -0
- package/dist/components/lollipop/lib/layout.js +16 -0
- package/dist/components/lollipop/lib/layout.js.map +1 -0
- package/dist/components/lollipop/lib/types.d.ts +5 -0
- package/dist/components/lollipop/lib/types.d.ts.map +1 -1
- package/dist/components/lollipop/metadata.json.d.ts +10 -0
- package/dist/components/lollipop/metadata.json.js +4 -1
- package/dist/components/lollipop/metadata.json.js.map +1 -1
- package/dist/components/lollipop/render/draw.d.ts +8 -1
- package/dist/components/lollipop/render/draw.d.ts.map +1 -1
- package/dist/components/lollipop/render/draw.js +155 -84
- package/dist/components/lollipop/render/draw.js.map +1 -1
- package/dist/components/map-chart/element/styles.d.ts +2 -0
- package/dist/components/map-chart/element/styles.d.ts.map +1 -0
- package/dist/components/map-chart/element/styles.js +372 -0
- package/dist/components/map-chart/element/styles.js.map +1 -0
- package/dist/components/map-chart/element/ui9000-map-chart.d.ts +54 -0
- package/dist/components/map-chart/element/ui9000-map-chart.d.ts.map +1 -0
- package/dist/components/map-chart/element/ui9000-map-chart.js +539 -0
- package/dist/components/map-chart/element/ui9000-map-chart.js.map +1 -0
- package/dist/components/map-chart/index.d.ts +5 -0
- package/dist/components/map-chart/index.d.ts.map +1 -0
- package/dist/components/map-chart/index.js +29 -0
- package/dist/components/map-chart/index.js.map +1 -0
- package/dist/components/map-chart/lib/constants.d.ts +34 -0
- package/dist/components/map-chart/lib/constants.d.ts.map +1 -0
- package/dist/components/map-chart/lib/constants.js +122 -0
- package/dist/components/map-chart/lib/constants.js.map +1 -0
- package/dist/components/map-chart/lib/domain.d.ts +12 -0
- package/dist/components/map-chart/lib/domain.d.ts.map +1 -0
- package/dist/components/map-chart/lib/domain.js +105 -0
- package/dist/components/map-chart/lib/domain.js.map +1 -0
- package/dist/components/map-chart/lib/format.d.ts +8 -0
- package/dist/components/map-chart/lib/format.d.ts.map +1 -0
- package/dist/components/map-chart/lib/format.js +45 -0
- package/dist/components/map-chart/lib/format.js.map +1 -0
- package/dist/components/map-chart/lib/geo-index.d.ts +7 -0
- package/dist/components/map-chart/lib/geo-index.d.ts.map +1 -0
- package/dist/components/map-chart/lib/geo-index.js +200 -0
- package/dist/components/map-chart/lib/geo-index.js.map +1 -0
- package/dist/components/map-chart/lib/geojson.d.ts +5 -0
- package/dist/components/map-chart/lib/geojson.d.ts.map +1 -0
- package/dist/components/map-chart/lib/geojson.js +47 -0
- package/dist/components/map-chart/lib/geojson.js.map +1 -0
- package/dist/components/map-chart/lib/index.d.ts +13 -0
- package/dist/components/map-chart/lib/index.d.ts.map +1 -0
- package/dist/components/map-chart/lib/join.d.ts +7 -0
- package/dist/components/map-chart/lib/join.d.ts.map +1 -0
- package/dist/components/map-chart/lib/join.js +156 -0
- package/dist/components/map-chart/lib/join.js.map +1 -0
- package/dist/components/map-chart/lib/legend.d.ts +45 -0
- package/dist/components/map-chart/lib/legend.d.ts.map +1 -0
- package/dist/components/map-chart/lib/legend.js +108 -0
- package/dist/components/map-chart/lib/legend.js.map +1 -0
- package/dist/components/map-chart/lib/normalize.d.ts +3 -0
- package/dist/components/map-chart/lib/normalize.d.ts.map +1 -0
- package/dist/components/map-chart/lib/normalize.js +177 -0
- package/dist/components/map-chart/lib/normalize.js.map +1 -0
- package/dist/components/map-chart/lib/pmtiles.d.ts +41 -0
- package/dist/components/map-chart/lib/pmtiles.d.ts.map +1 -0
- package/dist/components/map-chart/lib/pmtiles.js +112 -0
- package/dist/components/map-chart/lib/pmtiles.js.map +1 -0
- package/dist/components/map-chart/lib/types.d.ts +128 -0
- package/dist/components/map-chart/lib/types.d.ts.map +1 -0
- package/dist/components/map-chart/metadata.json.d.ts +83 -0
- package/dist/components/map-chart/metadata.json.js +42 -0
- package/dist/components/map-chart/metadata.json.js.map +1 -0
- package/dist/components/map-chart/render/draw.d.ts +24 -0
- package/dist/components/map-chart/render/draw.d.ts.map +1 -0
- package/dist/components/map-chart/render/draw.js +455 -0
- package/dist/components/map-chart/render/draw.js.map +1 -0
- package/dist/components/map-chart/render/index.d.ts +2 -0
- package/dist/components/map-chart/render/index.d.ts.map +1 -0
- package/dist/components/matrix-chart/element/styles.d.ts +2 -0
- package/dist/components/matrix-chart/element/styles.d.ts.map +1 -0
- package/dist/components/matrix-chart/element/styles.js +97 -0
- package/dist/components/matrix-chart/element/styles.js.map +1 -0
- package/dist/components/matrix-chart/element/ui9000-matrix-chart.d.ts +39 -0
- package/dist/components/matrix-chart/element/ui9000-matrix-chart.d.ts.map +1 -0
- package/dist/components/matrix-chart/element/ui9000-matrix-chart.js +238 -0
- package/dist/components/matrix-chart/element/ui9000-matrix-chart.js.map +1 -0
- package/dist/components/matrix-chart/index.d.ts +5 -0
- package/dist/components/matrix-chart/index.d.ts.map +1 -0
- package/dist/components/matrix-chart/index.js +20 -0
- package/dist/components/matrix-chart/lib/domain.d.ts +7 -0
- package/dist/components/matrix-chart/lib/domain.d.ts.map +1 -0
- package/dist/components/matrix-chart/lib/domain.js +58 -0
- package/dist/components/matrix-chart/lib/domain.js.map +1 -0
- package/dist/components/matrix-chart/lib/format.d.ts +5 -0
- package/dist/components/matrix-chart/lib/format.d.ts.map +1 -0
- package/dist/components/matrix-chart/lib/format.js +16 -0
- package/dist/components/matrix-chart/lib/format.js.map +1 -0
- package/dist/components/matrix-chart/lib/index.d.ts +5 -0
- package/dist/components/matrix-chart/lib/index.d.ts.map +1 -0
- package/dist/components/matrix-chart/lib/normalize.d.ts +5 -0
- package/dist/components/matrix-chart/lib/normalize.d.ts.map +1 -0
- package/dist/components/matrix-chart/lib/normalize.js +165 -0
- package/dist/components/matrix-chart/lib/normalize.js.map +1 -0
- package/dist/components/matrix-chart/lib/types.d.ts +33 -0
- package/dist/components/matrix-chart/lib/types.d.ts.map +1 -0
- package/dist/components/matrix-chart/metadata.json.d.ts +110 -0
- package/dist/components/matrix-chart/metadata.json.js +42 -0
- package/dist/components/matrix-chart/metadata.json.js.map +1 -0
- package/dist/components/matrix-chart/render/draw.d.ts +63 -0
- package/dist/components/matrix-chart/render/draw.d.ts.map +1 -0
- package/dist/components/matrix-chart/render/draw.js +225 -0
- package/dist/components/matrix-chart/render/draw.js.map +1 -0
- package/dist/components/matrix-chart/render/index.d.ts +2 -0
- package/dist/components/matrix-chart/render/index.d.ts.map +1 -0
- package/dist/components/network-graph/element/styles.d.ts.map +1 -1
- package/dist/components/network-graph/element/styles.js +177 -57
- package/dist/components/network-graph/element/styles.js.map +1 -1
- package/dist/components/network-graph/element/ui9000-network-graph.d.ts +4 -0
- package/dist/components/network-graph/element/ui9000-network-graph.d.ts.map +1 -1
- package/dist/components/network-graph/element/ui9000-network-graph.js +116 -39
- package/dist/components/network-graph/element/ui9000-network-graph.js.map +1 -1
- package/dist/components/network-graph/lib/domain.d.ts +2 -2
- package/dist/components/network-graph/lib/domain.js.map +1 -1
- package/dist/components/network-graph/lib/index.d.ts +1 -0
- package/dist/components/network-graph/lib/index.d.ts.map +1 -1
- package/dist/components/network-graph/lib/legend.d.ts +15 -0
- package/dist/components/network-graph/lib/legend.d.ts.map +1 -0
- package/dist/components/network-graph/lib/legend.js +35 -0
- package/dist/components/network-graph/lib/legend.js.map +1 -0
- package/dist/components/network-graph/render/draw.d.ts +4 -1
- package/dist/components/network-graph/render/draw.d.ts.map +1 -1
- package/dist/components/network-graph/render/draw.js +34 -9
- package/dist/components/network-graph/render/draw.js.map +1 -1
- package/dist/components/pie-chart/element/styles.d.ts.map +1 -1
- package/dist/components/pie-chart/element/styles.js +34 -1
- package/dist/components/pie-chart/element/styles.js.map +1 -1
- package/dist/components/pie-chart/element/ui9000-pie-chart.d.ts +0 -2
- package/dist/components/pie-chart/element/ui9000-pie-chart.d.ts.map +1 -1
- package/dist/components/pie-chart/element/ui9000-pie-chart.js +2 -8
- package/dist/components/pie-chart/element/ui9000-pie-chart.js.map +1 -1
- package/dist/components/pie-chart/metadata.json.d.ts +1 -7
- package/dist/components/pie-chart/metadata.json.js +2 -2
- package/dist/components/polar-area-chart/element/styles.d.ts +1 -1
- package/dist/components/polar-area-chart/element/styles.d.ts.map +1 -1
- package/dist/components/{donut-group-chart → polar-area-chart}/element/styles.js +9 -27
- package/dist/components/polar-area-chart/element/styles.js.map +1 -0
- package/dist/components/polar-area-chart/element/ui9000-polar-area-chart.d.ts.map +1 -1
- package/dist/components/polar-area-chart/element/ui9000-polar-area-chart.js +4 -3
- package/dist/components/polar-area-chart/element/ui9000-polar-area-chart.js.map +1 -1
- package/dist/components/polar-area-chart/index.d.ts +1 -1
- package/dist/components/polar-area-chart/index.d.ts.map +1 -1
- package/dist/components/polar-area-chart/index.js +2 -1
- package/dist/components/polar-area-chart/lib/domain.d.ts +8 -0
- package/dist/components/polar-area-chart/lib/domain.d.ts.map +1 -1
- package/dist/components/polar-area-chart/lib/domain.js +20 -0
- package/dist/components/polar-area-chart/lib/domain.js.map +1 -1
- package/dist/components/polar-area-chart/lib/index.d.ts +1 -1
- package/dist/components/polar-area-chart/lib/index.d.ts.map +1 -1
- package/dist/components/polar-area-chart/lib/normalize.d.ts.map +1 -1
- package/dist/components/polar-area-chart/lib/normalize.js +72 -6
- package/dist/components/polar-area-chart/lib/normalize.js.map +1 -1
- package/dist/components/polar-area-chart/lib/types.d.ts +6 -1
- package/dist/components/polar-area-chart/lib/types.d.ts.map +1 -1
- package/dist/components/polar-area-chart/metadata.json.d.ts +1 -1
- package/dist/components/polar-area-chart/metadata.json.js +1 -1
- package/dist/components/polar-area-chart/render/draw.d.ts.map +1 -1
- package/dist/components/polar-area-chart/render/draw.js +2 -2
- package/dist/components/polar-area-chart/render/draw.js.map +1 -1
- package/dist/components/punchcard-chart/metadata.json.d.ts +1 -1
- package/dist/components/punchcard-chart/metadata.json.js +1 -1
- package/dist/components/sankey-chart/element/styles.d.ts.map +1 -1
- package/dist/components/sankey-chart/element/styles.js +7 -27
- package/dist/components/sankey-chart/element/styles.js.map +1 -1
- package/dist/components/sankey-chart/element/ui9000-sankey-chart.d.ts +5 -5
- package/dist/components/sankey-chart/element/ui9000-sankey-chart.d.ts.map +1 -1
- package/dist/components/sankey-chart/element/ui9000-sankey-chart.js +37 -35
- package/dist/components/sankey-chart/element/ui9000-sankey-chart.js.map +1 -1
- package/dist/components/treemap-chart/element/styles.d.ts +2 -0
- package/dist/components/treemap-chart/element/styles.d.ts.map +1 -0
- package/dist/components/treemap-chart/element/styles.js +141 -0
- package/dist/components/treemap-chart/element/styles.js.map +1 -0
- package/dist/components/treemap-chart/element/ui9000-treemap-chart.d.ts +35 -0
- package/dist/components/treemap-chart/element/ui9000-treemap-chart.d.ts.map +1 -0
- package/dist/components/treemap-chart/element/ui9000-treemap-chart.js +177 -0
- package/dist/components/treemap-chart/element/ui9000-treemap-chart.js.map +1 -0
- package/dist/components/treemap-chart/index.d.ts +5 -0
- package/dist/components/treemap-chart/index.d.ts.map +1 -0
- package/dist/components/treemap-chart/index.js +22 -0
- package/dist/components/treemap-chart/index.js.map +1 -0
- package/dist/components/treemap-chart/lib/color.d.ts +25 -0
- package/dist/components/treemap-chart/lib/color.d.ts.map +1 -0
- package/dist/components/treemap-chart/lib/color.js +67 -0
- package/dist/components/treemap-chart/lib/color.js.map +1 -0
- package/dist/components/treemap-chart/lib/format.d.ts +7 -0
- package/dist/components/treemap-chart/lib/format.d.ts.map +1 -0
- package/dist/components/treemap-chart/lib/format.js +9 -0
- package/dist/components/treemap-chart/lib/format.js.map +1 -0
- package/dist/components/treemap-chart/lib/index.d.ts +6 -0
- package/dist/components/treemap-chart/lib/index.d.ts.map +1 -0
- package/dist/components/treemap-chart/lib/layout.d.ts +18 -0
- package/dist/components/treemap-chart/lib/layout.d.ts.map +1 -0
- package/dist/components/treemap-chart/lib/layout.js +31 -0
- package/dist/components/treemap-chart/lib/layout.js.map +1 -0
- package/dist/components/treemap-chart/lib/normalize.d.ts +4 -0
- package/dist/components/treemap-chart/lib/normalize.d.ts.map +1 -0
- package/dist/components/treemap-chart/lib/normalize.js +182 -0
- package/dist/components/treemap-chart/lib/normalize.js.map +1 -0
- package/dist/components/treemap-chart/lib/types.d.ts +63 -0
- package/dist/components/treemap-chart/lib/types.d.ts.map +1 -0
- package/dist/components/treemap-chart/metadata.json.d.ts +126 -0
- package/dist/components/treemap-chart/metadata.json.js +45 -0
- package/dist/components/treemap-chart/render/draw.d.ts +24 -0
- package/dist/components/treemap-chart/render/draw.d.ts.map +1 -0
- package/dist/components/treemap-chart/render/draw.js +124 -0
- package/dist/components/treemap-chart/render/draw.js.map +1 -0
- package/dist/components/treemap-chart/render/index.d.ts +2 -0
- package/dist/components/treemap-chart/render/index.d.ts.map +1 -0
- package/dist/element/chart-legend-render.d.ts +5 -0
- package/dist/element/chart-legend-render.d.ts.map +1 -1
- package/dist/element/chart-legend-render.js +19 -1
- package/dist/element/chart-legend-render.js.map +1 -1
- package/dist/element/chart-shell-styles.d.ts.map +1 -1
- package/dist/element/chart-shell-styles.js +35 -0
- package/dist/element/chart-shell-styles.js.map +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +73 -39
- package/dist/index.js.map +1 -1
- package/dist/lazy/index.d.ts +4 -2
- package/dist/lazy/index.d.ts.map +1 -1
- package/dist/lazy/index.js +24 -8
- package/dist/lazy/index.js.map +1 -1
- package/dist/lazy/map-chart.d.ts +4 -0
- package/dist/lazy/map-chart.d.ts.map +1 -0
- package/dist/lazy/map-chart.js +5 -0
- package/dist/lazy/map-chart.js.map +1 -0
- package/dist/lazy/matrix-chart.d.ts +4 -0
- package/dist/lazy/matrix-chart.d.ts.map +1 -0
- package/dist/lazy/matrix-chart.js +5 -0
- package/dist/lazy/matrix-chart.js.map +1 -0
- package/dist/lazy/treemap-chart.d.ts +4 -0
- package/dist/lazy/treemap-chart.d.ts.map +1 -0
- package/dist/lazy/treemap-chart.js +5 -0
- package/dist/lazy/treemap-chart.js.map +1 -0
- package/dist/node_modules/lit-html/directive.js +28 -0
- package/dist/node_modules/lit-html/directive.js.map +1 -0
- package/dist/node_modules/lit-html/directives/style-map.js +37 -0
- package/dist/node_modules/lit-html/directives/style-map.js.map +1 -0
- package/dist/node_modules/lit-html/lit-html.js +231 -0
- package/dist/node_modules/lit-html/lit-html.js.map +1 -0
- package/dist/utils/axis-units.d.ts +15 -0
- package/dist/utils/axis-units.d.ts.map +1 -0
- package/dist/utils/axis-units.js +27 -0
- package/dist/utils/axis-units.js.map +1 -0
- package/dist/utils/chart-helpers.d.ts +4 -6
- package/dist/utils/chart-helpers.d.ts.map +1 -1
- package/dist/utils/chart-helpers.js +16 -15
- package/dist/utils/chart-helpers.js.map +1 -1
- package/dist/utils/format-text.d.ts +5 -0
- package/dist/utils/format-text.d.ts.map +1 -1
- package/dist/utils/format-text.js +7 -0
- package/dist/utils/format-text.js.map +1 -1
- package/dist/utils/fuse-palette.d.ts +12 -0
- package/dist/utils/fuse-palette.d.ts.map +1 -1
- package/dist/utils/fuse-palette.js +23 -1
- package/dist/utils/fuse-palette.js.map +1 -1
- package/dist/utils/fuse-widget.d.ts +13 -4
- package/dist/utils/fuse-widget.d.ts.map +1 -1
- package/dist/utils/fuse-widget.js.map +1 -1
- package/dist/utils/fusedash-visual.d.ts +65 -52
- package/dist/utils/fusedash-visual.d.ts.map +1 -1
- package/dist/utils/fusedash-visual.js +48 -29
- package/dist/utils/fusedash-visual.js.map +1 -1
- package/package.json +38 -11
- package/dist/components/donut-group-chart/element/styles.d.ts +0 -2
- package/dist/components/donut-group-chart/element/styles.d.ts.map +0 -1
- package/dist/components/donut-group-chart/element/styles.js.map +0 -1
- package/dist/components/donut-group-chart/element/ui9000-donut-group-chart.d.ts +0 -34
- package/dist/components/donut-group-chart/element/ui9000-donut-group-chart.d.ts.map +0 -1
- package/dist/components/donut-group-chart/element/ui9000-donut-group-chart.js +0 -169
- package/dist/components/donut-group-chart/element/ui9000-donut-group-chart.js.map +0 -1
- package/dist/components/donut-group-chart/index.d.ts +0 -5
- package/dist/components/donut-group-chart/index.d.ts.map +0 -1
- package/dist/components/donut-group-chart/index.js +0 -23
- package/dist/components/donut-group-chart/lib/domain.d.ts +0 -39
- package/dist/components/donut-group-chart/lib/domain.d.ts.map +0 -1
- package/dist/components/donut-group-chart/lib/domain.js +0 -51
- package/dist/components/donut-group-chart/lib/domain.js.map +0 -1
- package/dist/components/donut-group-chart/lib/format.d.ts +0 -7
- package/dist/components/donut-group-chart/lib/format.d.ts.map +0 -1
- package/dist/components/donut-group-chart/lib/format.js +0 -21
- package/dist/components/donut-group-chart/lib/format.js.map +0 -1
- package/dist/components/donut-group-chart/lib/index.d.ts +0 -5
- package/dist/components/donut-group-chart/lib/index.d.ts.map +0 -1
- package/dist/components/donut-group-chart/lib/normalize.d.ts +0 -14
- package/dist/components/donut-group-chart/lib/normalize.d.ts.map +0 -1
- package/dist/components/donut-group-chart/lib/normalize.js +0 -98
- package/dist/components/donut-group-chart/lib/normalize.js.map +0 -1
- package/dist/components/donut-group-chart/lib/types.d.ts +0 -49
- package/dist/components/donut-group-chart/lib/types.d.ts.map +0 -1
- package/dist/components/donut-group-chart/metadata.json.d.ts +0 -113
- package/dist/components/donut-group-chart/metadata.json.js +0 -45
- package/dist/components/donut-group-chart/render/draw.d.ts +0 -44
- package/dist/components/donut-group-chart/render/draw.d.ts.map +0 -1
- package/dist/components/donut-group-chart/render/draw.js +0 -194
- package/dist/components/donut-group-chart/render/draw.js.map +0 -1
- package/dist/components/donut-group-chart/render/index.d.ts +0 -2
- package/dist/components/donut-group-chart/render/index.d.ts.map +0 -1
- package/dist/components/donut-group-chart/tests/fixtures.d.ts +0 -33
- package/dist/components/donut-group-chart/tests/fixtures.d.ts.map +0 -1
- package/dist/lazy/donut-group-chart.d.ts +0 -4
- package/dist/lazy/donut-group-chart.d.ts.map +0 -1
- package/dist/lazy/donut-group-chart.js +0 -5
- package/dist/lazy/donut-group-chart.js.map +0 -1
- /package/dist/components/{donut-group-chart → matrix-chart}/index.js.map +0 -0
- /package/dist/components/{donut-group-chart → treemap-chart}/metadata.json.js.map +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2
|
+
function isFeatureCollection(value) {
|
|
3
|
+
if (!value || typeof value !== "object") return false;
|
|
4
|
+
const obj = value;
|
|
5
|
+
return obj.type === "FeatureCollection" && Array.isArray(obj.features);
|
|
6
|
+
}
|
|
7
|
+
async function fetchMapGeoJson(mapType, baseUrl) {
|
|
8
|
+
const trimmed = baseUrl == null ? void 0 : baseUrl.trim();
|
|
9
|
+
if (!trimmed || !mapType) return null;
|
|
10
|
+
const url = `${trimmed.replace(/\/$/, "")}/${geoJsonFileName(mapType)}`;
|
|
11
|
+
const hit = cache.get(url);
|
|
12
|
+
if (hit) return hit;
|
|
13
|
+
const pending = (async () => {
|
|
14
|
+
try {
|
|
15
|
+
const res = await fetch(url);
|
|
16
|
+
if (!res.ok) return null;
|
|
17
|
+
const json = await res.json();
|
|
18
|
+
return isFeatureCollection(json) ? json : null;
|
|
19
|
+
} catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
})();
|
|
23
|
+
cache.set(url, pending);
|
|
24
|
+
return pending;
|
|
25
|
+
}
|
|
26
|
+
function geoJsonFileName(mapType) {
|
|
27
|
+
switch (mapType) {
|
|
28
|
+
case "city":
|
|
29
|
+
return "city.json";
|
|
30
|
+
case "county":
|
|
31
|
+
return "county.json";
|
|
32
|
+
case "state":
|
|
33
|
+
return "state.json";
|
|
34
|
+
case "province":
|
|
35
|
+
case "region":
|
|
36
|
+
return "province.json";
|
|
37
|
+
case "country":
|
|
38
|
+
default:
|
|
39
|
+
return "country.json";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
fetchMapGeoJson,
|
|
44
|
+
geoJsonFileName,
|
|
45
|
+
isFeatureCollection
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=geojson.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geojson.js","sources":["../../../../src/components/map-chart/lib/geojson.ts"],"sourcesContent":["import type { GeoJsonFeatureCollection } from './types.js';\n\nconst cache = new Map<string, Promise<GeoJsonFeatureCollection | null>>();\n\nexport function isFeatureCollection(value: unknown): value is GeoJsonFeatureCollection {\n if (!value || typeof value !== 'object') return false;\n const obj = value as { type?: string; features?: unknown };\n return obj.type === 'FeatureCollection' && Array.isArray(obj.features);\n}\n\nexport async function fetchMapGeoJson(\n mapType: string,\n baseUrl?: string,\n): Promise<GeoJsonFeatureCollection | null> {\n const trimmed = baseUrl?.trim();\n if (!trimmed || !mapType) return null;\n const url = `${trimmed.replace(/\\/$/, '')}/${geoJsonFileName(mapType)}`;\n const hit = cache.get(url);\n if (hit) return hit;\n\n const pending = (async () => {\n try {\n const res = await fetch(url);\n if (!res.ok) return null;\n const json: unknown = await res.json();\n return isFeatureCollection(json) ? json : null;\n } catch {\n return null;\n }\n })();\n cache.set(url, pending);\n return pending;\n}\n\nexport function geoJsonFileName(mapType: string): string {\n switch (mapType) {\n case 'city':\n return 'city.json';\n case 'county':\n return 'county.json';\n case 'state':\n return 'state.json';\n case 'province':\n case 'region':\n return 'province.json';\n case 'country':\n default:\n return 'country.json';\n }\n}\n"],"names":[],"mappings":"AAEA,MAAM,4BAAY,IAAA;AAEX,SAAS,oBAAoB,OAAmD;AACrF,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,MAAM;AACZ,SAAO,IAAI,SAAS,uBAAuB,MAAM,QAAQ,IAAI,QAAQ;AACvE;AAEA,eAAsB,gBACpB,SACA,SAC0C;AAC1C,QAAM,UAAU,mCAAS;AACzB,MAAI,CAAC,WAAW,CAAC,QAAS,QAAO;AACjC,QAAM,MAAM,GAAG,QAAQ,QAAQ,OAAO,EAAE,CAAC,IAAI,gBAAgB,OAAO,CAAC;AACrE,QAAM,MAAM,MAAM,IAAI,GAAG;AACzB,MAAI,IAAK,QAAO;AAEhB,QAAM,WAAW,YAAY;AAC3B,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,GAAG;AAC3B,UAAI,CAAC,IAAI,GAAI,QAAO;AACpB,YAAM,OAAgB,MAAM,IAAI,KAAA;AAChC,aAAO,oBAAoB,IAAI,IAAI,OAAO;AAAA,IAC5C,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAA;AACA,QAAM,IAAI,KAAK,OAAO;AACtB,SAAO;AACT;AAEO,SAAS,gBAAgB,SAAyB;AACvD,UAAQ,SAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL;AACE,aAAO;AAAA,EAAA;AAEb;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { COUNTRY_SYNONYMS, DEFAULT_BUBBLES_RADIUS, DEFAULT_SPIKE_SIZES, GEOJSON_KEYS, LAYER_ORDER, MAP_ADMIN_TYPES, MAP_STYLES, MAPBOX_CSS_HREF, MAX_COLOR_RANGE, sanitizeId, sanitizeKey, } from './constants.js';
|
|
2
|
+
export { collectionBBox, colorForValue, featureBBox, featureCenter, generateColorRanges, rangesFromPaletteStops, valuesOfRows, } from './domain.js';
|
|
3
|
+
export { darkenColor, formatMapValue, formatRangeLabel, hexToRgba, numericValue } from './format.js';
|
|
4
|
+
export { createFeaturesIndex, getRegionId, getRegionIdFromFeatureProperties, inferMapTypeFromKeyNames, normalizeDataValue, } from './geo-index.js';
|
|
5
|
+
export { fetchMapGeoJson, geoJsonFileName, isFeatureCollection } from './geojson.js';
|
|
6
|
+
export { isMapVisualisation, joinLayerFeatures, joinModelLayers, orderedLayers } from './join.js';
|
|
7
|
+
export { clampLayerSlider, defaultLayerSlider, featuresForYear, featuresInSliderRange, formatAverage, formatFieldLabel, formatLegendBucket, legendLayerOrder, layerAverage, legendSpikeHeight, MUTED_LEGEND_FILL, rangeTrackOffset, slideThumb, sliderIndexFromPointer, sliderValueWindow, thumbTrackPercent, } from './legend.js';
|
|
8
|
+
export type { LayerSlider } from './legend.js';
|
|
9
|
+
export { normalizeMapData } from './normalize.js';
|
|
10
|
+
export { choroplethPmtilesSource, featuresHavePolygonGeometry, getPmtilesConfig, PMTILES_CONFIG, resolvePmtilesUrl, } from './pmtiles.js';
|
|
11
|
+
export type { PmtilesLayerConfig } from './pmtiles.js';
|
|
12
|
+
export type { ColorRange, FeaturesIndex, GeoJsonFeature, GeoJsonFeatureCollection, MapChartInput, MapHoverEntry, MapLayerModel, MapModel, MapRow, MapVisualisation, } from './types.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/map-chart/lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,UAAU,EACV,eAAe,EACf,eAAe,EACf,UAAU,EACV,WAAW,GACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,cAAc,EACd,aAAa,EACb,WAAW,EACX,aAAa,EACb,mBAAmB,EACnB,sBAAsB,EACtB,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACrG,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,gCAAgC,EAChC,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAClG,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,gBAAgB,EAChB,cAAc,EACd,iBAAiB,GAClB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EACV,UAAU,EACV,aAAa,EACb,cAAc,EACd,wBAAwB,EACxB,aAAa,EACb,aAAa,EACb,aAAa,EACb,QAAQ,EACR,MAAM,EACN,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { MapVisualisation } from './constants.js';
|
|
2
|
+
import { GeoJsonFeatureCollection, MapLayerModel } from './types.js';
|
|
3
|
+
export declare function joinLayerFeatures(layer: MapLayerModel, collection: GeoJsonFeatureCollection | null | undefined): MapLayerModel;
|
|
4
|
+
export declare function joinModelLayers(layers: MapLayerModel[], geoJsonByType: Record<string, GeoJsonFeatureCollection | undefined>): MapLayerModel[];
|
|
5
|
+
export declare function orderedLayers(layers: MapLayerModel[]): MapLayerModel[];
|
|
6
|
+
export declare function isMapVisualisation(value: string | undefined): value is MapVisualisation;
|
|
7
|
+
//# sourceMappingURL=join.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"join.d.ts","sourceRoot":"","sources":["../../../../src/components/map-chart/lib/join.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAI7F,OAAO,KAAK,EAGV,wBAAwB,EACxB,aAAa,EAEd,MAAM,YAAY,CAAC;AAMpB,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,aAAa,EACpB,UAAU,EAAE,wBAAwB,GAAG,IAAI,GAAG,SAAS,GACtD,aAAa,CAuEf;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EAAE,EACvB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,GAAG,SAAS,CAAC,GAClE,aAAa,EAAE,CAEjB;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAKtE;AA2FD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,gBAAgB,CAEvF"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { sanitizeKey, LAYER_ORDER, MAX_SPIKES } from "./constants.js";
|
|
2
|
+
import { colorForValue, featureCenter } from "./domain.js";
|
|
3
|
+
import { numericValue, hexToRgba } from "./format.js";
|
|
4
|
+
import { createFeaturesIndex, getRegionId } from "./geo-index.js";
|
|
5
|
+
function rawRegionValue(row, layer) {
|
|
6
|
+
return row[layer.geoKey] ?? row[layer.mapType];
|
|
7
|
+
}
|
|
8
|
+
function joinLayerFeatures(layer, collection) {
|
|
9
|
+
var _a, _b;
|
|
10
|
+
if (!((_a = collection == null ? void 0 : collection.features) == null ? void 0 : _a.length)) {
|
|
11
|
+
return { ...layer, features: [], colorById: {}, matchTotal: 0, matchHit: 0 };
|
|
12
|
+
}
|
|
13
|
+
const index = createFeaturesIndex(collection.features, layer.mapType);
|
|
14
|
+
let matchTotal = 0;
|
|
15
|
+
let matchHit = 0;
|
|
16
|
+
const features = [];
|
|
17
|
+
const colorById = {};
|
|
18
|
+
for (const row of layer.rows) {
|
|
19
|
+
const raw = rawRegionValue(row, layer);
|
|
20
|
+
if (Array.isArray(raw)) {
|
|
21
|
+
const value2 = numericValue(row[layer.valueKey]);
|
|
22
|
+
if (raw.length < 2) continue;
|
|
23
|
+
features.push({
|
|
24
|
+
type: "Feature",
|
|
25
|
+
properties: { ...row, value: value2, regionId: null, regionName: null },
|
|
26
|
+
geometry: { type: "Point", coordinates: raw }
|
|
27
|
+
});
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const dataValue = String(raw ?? "").toLowerCase();
|
|
31
|
+
if (!dataValue) continue;
|
|
32
|
+
matchTotal += 1;
|
|
33
|
+
const regionId = getRegionId(dataValue, layer.mapType, index);
|
|
34
|
+
if (!regionId) continue;
|
|
35
|
+
matchHit += 1;
|
|
36
|
+
const regionFeature = index.byId.get(regionId);
|
|
37
|
+
if (!regionFeature) continue;
|
|
38
|
+
const value = numericValue(row[layer.valueKey]);
|
|
39
|
+
const regionName = (typeof row[layer.geoKey] === "string" && row[layer.geoKey] ? String(row[layer.geoKey]) : void 0) ?? (typeof ((_b = regionFeature.properties) == null ? void 0 : _b.name) === "string" ? regionFeature.properties.name : regionId);
|
|
40
|
+
if (layer.visualisationType === "choropleth") {
|
|
41
|
+
features.push({
|
|
42
|
+
...regionFeature,
|
|
43
|
+
id: regionId,
|
|
44
|
+
properties: {
|
|
45
|
+
...regionFeature.properties,
|
|
46
|
+
id: regionId,
|
|
47
|
+
regionId,
|
|
48
|
+
value,
|
|
49
|
+
regionName
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
colorById[regionId] = hexToRgba(colorForValue(value, layer.colorRanges), 1);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const center = featureCenter(regionFeature);
|
|
56
|
+
if (!center) continue;
|
|
57
|
+
features.push({
|
|
58
|
+
type: "Feature",
|
|
59
|
+
properties: { ...row, value, regionId, regionName },
|
|
60
|
+
geometry: { type: "Point", coordinates: [center.lng, center.lat] }
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
const nextFeatures = layer.visualisationType === "spike" ? spikeFeatures(features, layer) : features;
|
|
64
|
+
return { ...layer, features: nextFeatures, colorById, matchTotal, matchHit };
|
|
65
|
+
}
|
|
66
|
+
function orderedLayers(layers) {
|
|
67
|
+
return [...layers].sort(
|
|
68
|
+
(a, b) => (LAYER_ORDER[a.visualisationType] ?? 99) - (LAYER_ORDER[b.visualisationType] ?? 99)
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
function spikeFeatures(features, layer) {
|
|
72
|
+
const points = features.filter((f) => {
|
|
73
|
+
var _a;
|
|
74
|
+
return ((_a = f.geometry) == null ? void 0 : _a.type) === "Point";
|
|
75
|
+
});
|
|
76
|
+
if (!points.length) return [];
|
|
77
|
+
const ranked = [...points].sort(
|
|
78
|
+
(a, b) => {
|
|
79
|
+
var _a, _b;
|
|
80
|
+
return numericValue((_a = b.properties) == null ? void 0 : _a.value) - numericValue((_b = a.properties) == null ? void 0 : _b.value);
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
const limited = ranked.slice(0, MAX_SPIKES);
|
|
84
|
+
const values = limited.map((f) => {
|
|
85
|
+
var _a;
|
|
86
|
+
return numericValue((_a = f.properties) == null ? void 0 : _a.value) || 1;
|
|
87
|
+
});
|
|
88
|
+
const minValue = Math.min(...values);
|
|
89
|
+
const maxValue = Math.max(...values);
|
|
90
|
+
const layerIdClean = sanitizeKey(layer.layerId);
|
|
91
|
+
return limited.map((feature, index) => {
|
|
92
|
+
var _a, _b, _c, _d;
|
|
93
|
+
const value = numericValue((_a = feature.properties) == null ? void 0 : _a.value);
|
|
94
|
+
const size = spikeSize(value, layer.colorRanges, minValue, maxValue);
|
|
95
|
+
const regionId = String(((_b = feature.properties) == null ? void 0 : _b.regionId) ?? "");
|
|
96
|
+
const iconName = `spike-icon-${layerIdClean}_${index}${regionId ? `_${sanitizeKey(regionId)}` : ""}`;
|
|
97
|
+
const color = layer.fillColor.replace("#", "");
|
|
98
|
+
const spikeText = typeof ((_c = feature.properties) == null ? void 0 : _c.spikeText) === "string" ? feature.properties.spikeText : typeof ((_d = feature.properties) == null ? void 0 : _d.label) === "string" ? feature.properties.label : void 0;
|
|
99
|
+
const svgContent = spikeSvg(size, color, spikeText);
|
|
100
|
+
return {
|
|
101
|
+
...feature,
|
|
102
|
+
properties: {
|
|
103
|
+
...feature.properties,
|
|
104
|
+
size,
|
|
105
|
+
iconName,
|
|
106
|
+
svgContent,
|
|
107
|
+
layerId: layer.layerId
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function spikeSize(value, ranges, minValue, maxValue) {
|
|
113
|
+
if (ranges.length) {
|
|
114
|
+
const range = ranges.find((r) => value >= r.start && value <= r.end);
|
|
115
|
+
if (range == null ? void 0 : range.height) return range.height;
|
|
116
|
+
if (value < ranges[0].start && ranges[0].height) return ranges[0].height;
|
|
117
|
+
const last = ranges[ranges.length - 1];
|
|
118
|
+
if (value > last.end && last.height) return last.height;
|
|
119
|
+
}
|
|
120
|
+
if (maxValue === minValue) return 28;
|
|
121
|
+
const ratio = (value - minValue) / (maxValue - minValue);
|
|
122
|
+
const heights = [8, 12, 16, 22, 28, 34, 42, 54];
|
|
123
|
+
return heights[Math.round(ratio * (heights.length - 1))] ?? 28;
|
|
124
|
+
}
|
|
125
|
+
function spikeSvg(size, color, text) {
|
|
126
|
+
const hex = color.startsWith("#") ? color : `#${color}`;
|
|
127
|
+
const fill = hexToRgba(hex, 1);
|
|
128
|
+
const actualHeight = size;
|
|
129
|
+
const fontSize = 20;
|
|
130
|
+
const textHeight = fontSize + 8;
|
|
131
|
+
const gap = 4;
|
|
132
|
+
const totalHeight = text ? textHeight + gap + actualHeight : actualHeight;
|
|
133
|
+
const spikeOffsetY = text ? textHeight + gap : 0;
|
|
134
|
+
const spikeWidth = 30;
|
|
135
|
+
const svgWidth = text ? Math.max(spikeWidth, text.length * 12 + 10) : spikeWidth;
|
|
136
|
+
const spikeOffsetX = text ? (svgWidth - spikeWidth) / 2 : 0;
|
|
137
|
+
const centerX = spikeWidth / 2;
|
|
138
|
+
const left = centerX - 6;
|
|
139
|
+
const right = centerX + 6;
|
|
140
|
+
const top = 0.25;
|
|
141
|
+
const bottom = actualHeight - 0.75;
|
|
142
|
+
const textEl = text ? `<text x="${svgWidth / 2}" y="${fontSize + 4}" text-anchor="middle" fill="black" font-size="${fontSize}" font-weight="bold" font-family="Arial, sans-serif" stroke="white" stroke-width="1" paint-order="stroke">${escapeXml(text)}</text>` : "";
|
|
143
|
+
return `<svg width="${svgWidth}" height="${totalHeight}" viewBox="0 0 ${svgWidth} ${totalHeight}" fill="none" xmlns="http://www.w3.org/2000/svg"><g transform="translate(${spikeOffsetX}, ${spikeOffsetY})"><path d="M${right} ${bottom}L${centerX} ${top}L${left} ${bottom}Z" fill="${fill}"/><path d="M${centerX + 10} ${bottom}H${right + 2}L${centerX} ${top}L${left - 2} ${bottom}H${centerX - 10}" stroke="${fill}" fill="none" stroke-width="1"/></g>${textEl}</svg>`;
|
|
144
|
+
}
|
|
145
|
+
function escapeXml(value) {
|
|
146
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
147
|
+
}
|
|
148
|
+
function isMapVisualisation(value) {
|
|
149
|
+
return value === "choropleth" || value === "bubbles" || value === "spike" || value === "markers";
|
|
150
|
+
}
|
|
151
|
+
export {
|
|
152
|
+
isMapVisualisation,
|
|
153
|
+
joinLayerFeatures,
|
|
154
|
+
orderedLayers
|
|
155
|
+
};
|
|
156
|
+
//# sourceMappingURL=join.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"join.js","sources":["../../../../src/components/map-chart/lib/join.ts"],"sourcesContent":["import { LAYER_ORDER, MAX_SPIKES, sanitizeKey, type MapVisualisation } from './constants.js';\nimport { colorForValue, featureCenter } from './domain.js';\nimport { hexToRgba, numericValue } from './format.js';\nimport { createFeaturesIndex, getRegionId } from './geo-index.js';\nimport type {\n ColorRange,\n GeoJsonFeature,\n GeoJsonFeatureCollection,\n MapLayerModel,\n MapRow,\n} from './types.js';\n\nfunction rawRegionValue(row: MapRow, layer: MapLayerModel): unknown {\n return row[layer.geoKey] ?? row[layer.mapType];\n}\n\nexport function joinLayerFeatures(\n layer: MapLayerModel,\n collection: GeoJsonFeatureCollection | null | undefined,\n): MapLayerModel {\n if (!collection?.features?.length) {\n return { ...layer, features: [], colorById: {}, matchTotal: 0, matchHit: 0 };\n }\n\n const index = createFeaturesIndex(collection.features, layer.mapType);\n let matchTotal = 0;\n let matchHit = 0;\n const features: GeoJsonFeature[] = [];\n const colorById: Record<string, string> = {};\n\n for (const row of layer.rows) {\n const raw = rawRegionValue(row, layer);\n if (Array.isArray(raw)) {\n const value = numericValue(row[layer.valueKey]);\n if (raw.length < 2) continue;\n features.push({\n type: 'Feature',\n properties: { ...row, value, regionId: null, regionName: null },\n geometry: { type: 'Point', coordinates: raw },\n });\n continue;\n }\n\n const dataValue = String(raw ?? '').toLowerCase();\n if (!dataValue) continue;\n matchTotal += 1;\n const regionId = getRegionId(dataValue, layer.mapType, index);\n if (!regionId) continue;\n matchHit += 1;\n\n const regionFeature = index.byId.get(regionId);\n if (!regionFeature) continue;\n const value = numericValue(row[layer.valueKey]);\n const regionName =\n (typeof row[layer.geoKey] === 'string' && row[layer.geoKey]\n ? String(row[layer.geoKey])\n : undefined) ??\n (typeof regionFeature.properties?.name === 'string'\n ? regionFeature.properties.name\n : regionId);\n\n if (layer.visualisationType === 'choropleth') {\n features.push({\n ...regionFeature,\n id: regionId,\n properties: {\n ...regionFeature.properties,\n id: regionId,\n regionId,\n value,\n regionName,\n },\n });\n colorById[regionId] = hexToRgba(colorForValue(value, layer.colorRanges), 1);\n continue;\n }\n\n const center = featureCenter(regionFeature);\n if (!center) continue;\n features.push({\n type: 'Feature',\n properties: { ...row, value, regionId, regionName },\n geometry: { type: 'Point', coordinates: [center.lng, center.lat] },\n });\n }\n\n const nextFeatures =\n layer.visualisationType === 'spike' ? spikeFeatures(features, layer) : features;\n\n return { ...layer, features: nextFeatures, colorById, matchTotal, matchHit };\n}\n\nexport function joinModelLayers(\n layers: MapLayerModel[],\n geoJsonByType: Record<string, GeoJsonFeatureCollection | undefined>,\n): MapLayerModel[] {\n return layers.map((layer) => joinLayerFeatures(layer, geoJsonByType[layer.mapType]));\n}\n\nexport function orderedLayers(layers: MapLayerModel[]): MapLayerModel[] {\n return [...layers].sort(\n (a, b) =>\n (LAYER_ORDER[a.visualisationType] ?? 99) - (LAYER_ORDER[b.visualisationType] ?? 99),\n );\n}\n\nfunction spikeFeatures(features: GeoJsonFeature[], layer: MapLayerModel): GeoJsonFeature[] {\n const points = features.filter((f) => f.geometry?.type === 'Point');\n if (!points.length) return [];\n const ranked = [...points].sort(\n (a, b) => numericValue(b.properties?.value) - numericValue(a.properties?.value),\n );\n const limited = ranked.slice(0, MAX_SPIKES);\n const values = limited.map((f) => numericValue(f.properties?.value) || 1);\n const minValue = Math.min(...values);\n const maxValue = Math.max(...values);\n const layerIdClean = sanitizeKey(layer.layerId);\n\n return limited.map((feature, index) => {\n const value = numericValue(feature.properties?.value);\n const size = spikeSize(value, layer.colorRanges, minValue, maxValue);\n const regionId = String(feature.properties?.regionId ?? '');\n const iconName = `spike-icon-${layerIdClean}_${index}${regionId ? `_${sanitizeKey(regionId)}` : ''}`;\n const color = layer.fillColor.replace('#', '');\n const spikeText =\n typeof feature.properties?.spikeText === 'string'\n ? feature.properties.spikeText\n : typeof feature.properties?.label === 'string'\n ? feature.properties.label\n : undefined;\n const svgContent = spikeSvg(size, color, spikeText);\n return {\n ...feature,\n properties: {\n ...feature.properties,\n size,\n iconName,\n svgContent,\n layerId: layer.layerId,\n },\n };\n });\n}\n\nfunction spikeSize(\n value: number,\n ranges: ColorRange[],\n minValue: number,\n maxValue: number,\n): number {\n if (ranges.length) {\n const range = ranges.find((r) => value >= r.start && value <= r.end);\n if (range?.height) return range.height;\n if (value < ranges[0].start && ranges[0].height) return ranges[0].height;\n const last = ranges[ranges.length - 1];\n if (value > last.end && last.height) return last.height;\n }\n if (maxValue === minValue) return 28;\n const ratio = (value - minValue) / (maxValue - minValue);\n const heights = [8, 12, 16, 22, 28, 34, 42, 54];\n return heights[Math.round(ratio * (heights.length - 1))] ?? 28;\n}\n\nfunction spikeSvg(size: number, color: string, text?: string): string {\n const hex = color.startsWith('#') ? color : `#${color}`;\n const fill = hexToRgba(hex, 1);\n const actualHeight = size;\n const fontSize = 20;\n const textHeight = fontSize + 8;\n const gap = 4;\n const totalHeight = text ? textHeight + gap + actualHeight : actualHeight;\n const spikeOffsetY = text ? textHeight + gap : 0;\n const spikeWidth = 30;\n const svgWidth = text ? Math.max(spikeWidth, text.length * 12 + 10) : spikeWidth;\n const spikeOffsetX = text ? (svgWidth - spikeWidth) / 2 : 0;\n const centerX = spikeWidth / 2;\n const left = centerX - 6;\n const right = centerX + 6;\n const top = 0.25;\n const bottom = actualHeight - 0.75;\n const textEl = text\n ? `<text x=\"${svgWidth / 2}\" y=\"${fontSize + 4}\" text-anchor=\"middle\" fill=\"black\" font-size=\"${fontSize}\" font-weight=\"bold\" font-family=\"Arial, sans-serif\" stroke=\"white\" stroke-width=\"1\" paint-order=\"stroke\">${escapeXml(text)}</text>`\n : '';\n\n return `<svg width=\"${svgWidth}\" height=\"${totalHeight}\" viewBox=\"0 0 ${svgWidth} ${totalHeight}\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><g transform=\"translate(${spikeOffsetX}, ${spikeOffsetY})\"><path d=\"M${right} ${bottom}L${centerX} ${top}L${left} ${bottom}Z\" fill=\"${fill}\"/><path d=\"M${centerX + 10} ${bottom}H${right + 2}L${centerX} ${top}L${left - 2} ${bottom}H${centerX - 10}\" stroke=\"${fill}\" fill=\"none\" stroke-width=\"1\"/></g>${textEl}</svg>`;\n}\n\nfunction escapeXml(value: string): string {\n return value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n}\n\nexport function isMapVisualisation(value: string | undefined): value is MapVisualisation {\n return value === 'choropleth' || value === 'bubbles' || value === 'spike' || value === 'markers';\n}\n"],"names":["value"],"mappings":";;;;AAYA,SAAS,eAAe,KAAa,OAA+B;AAClE,SAAO,IAAI,MAAM,MAAM,KAAK,IAAI,MAAM,OAAO;AAC/C;AAEO,SAAS,kBACd,OACA,YACe;;AACf,MAAI,GAAC,8CAAY,aAAZ,mBAAsB,SAAQ;AACjC,WAAO,EAAE,GAAG,OAAO,UAAU,IAAI,WAAW,CAAA,GAAI,YAAY,GAAG,UAAU,EAAA;AAAA,EAC3E;AAEA,QAAM,QAAQ,oBAAoB,WAAW,UAAU,MAAM,OAAO;AACpE,MAAI,aAAa;AACjB,MAAI,WAAW;AACf,QAAM,WAA6B,CAAA;AACnC,QAAM,YAAoC,CAAA;AAE1C,aAAW,OAAO,MAAM,MAAM;AAC5B,UAAM,MAAM,eAAe,KAAK,KAAK;AACrC,QAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,YAAMA,SAAQ,aAAa,IAAI,MAAM,QAAQ,CAAC;AAC9C,UAAI,IAAI,SAAS,EAAG;AACpB,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,YAAY,EAAE,GAAG,KAAK,OAAAA,QAAO,UAAU,MAAM,YAAY,KAAA;AAAA,QACzD,UAAU,EAAE,MAAM,SAAS,aAAa,IAAA;AAAA,MAAI,CAC7C;AACD;AAAA,IACF;AAEA,UAAM,YAAY,OAAO,OAAO,EAAE,EAAE,YAAA;AACpC,QAAI,CAAC,UAAW;AAChB,kBAAc;AACd,UAAM,WAAW,YAAY,WAAW,MAAM,SAAS,KAAK;AAC5D,QAAI,CAAC,SAAU;AACf,gBAAY;AAEZ,UAAM,gBAAgB,MAAM,KAAK,IAAI,QAAQ;AAC7C,QAAI,CAAC,cAAe;AACpB,UAAM,QAAQ,aAAa,IAAI,MAAM,QAAQ,CAAC;AAC9C,UAAM,cACH,OAAO,IAAI,MAAM,MAAM,MAAM,YAAY,IAAI,MAAM,MAAM,IACtD,OAAO,IAAI,MAAM,MAAM,CAAC,IACxB,YACH,SAAO,mBAAc,eAAd,mBAA0B,UAAS,WACvC,cAAc,WAAW,OACzB;AAEN,QAAI,MAAM,sBAAsB,cAAc;AAC5C,eAAS,KAAK;AAAA,QACZ,GAAG;AAAA,QACH,IAAI;AAAA,QACJ,YAAY;AAAA,UACV,GAAG,cAAc;AAAA,UACjB,IAAI;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MACF,CACD;AACD,gBAAU,QAAQ,IAAI,UAAU,cAAc,OAAO,MAAM,WAAW,GAAG,CAAC;AAC1E;AAAA,IACF;AAEA,UAAM,SAAS,cAAc,aAAa;AAC1C,QAAI,CAAC,OAAQ;AACb,aAAS,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,YAAY,EAAE,GAAG,KAAK,OAAO,UAAU,WAAA;AAAA,MACvC,UAAU,EAAE,MAAM,SAAS,aAAa,CAAC,OAAO,KAAK,OAAO,GAAG,EAAA;AAAA,IAAE,CAClE;AAAA,EACH;AAEA,QAAM,eACJ,MAAM,sBAAsB,UAAU,cAAc,UAAU,KAAK,IAAI;AAEzE,SAAO,EAAE,GAAG,OAAO,UAAU,cAAc,WAAW,YAAY,SAAA;AACpE;AASO,SAAS,cAAc,QAA0C;AACtE,SAAO,CAAC,GAAG,MAAM,EAAE;AAAA,IACjB,CAAC,GAAG,OACD,YAAY,EAAE,iBAAiB,KAAK,OAAO,YAAY,EAAE,iBAAiB,KAAK;AAAA,EAAA;AAEtF;AAEA,SAAS,cAAc,UAA4B,OAAwC;AACzF,QAAM,SAAS,SAAS,OAAO,CAAC;;AAAM,oBAAE,aAAF,mBAAY,UAAS;AAAA,GAAO;AAClE,MAAI,CAAC,OAAO,OAAQ,QAAO,CAAA;AAC3B,QAAM,SAAS,CAAC,GAAG,MAAM,EAAE;AAAA,IACzB,CAAC,GAAG;;AAAM,2BAAa,OAAE,eAAF,mBAAc,KAAK,IAAI,cAAa,OAAE,eAAF,mBAAc,KAAK;AAAA;AAAA,EAAA;AAEhF,QAAM,UAAU,OAAO,MAAM,GAAG,UAAU;AAC1C,QAAM,SAAS,QAAQ,IAAI,CAAC,MAAA;;AAAM,yBAAa,OAAE,eAAF,mBAAc,KAAK,KAAK;AAAA,GAAC;AACxE,QAAM,WAAW,KAAK,IAAI,GAAG,MAAM;AACnC,QAAM,WAAW,KAAK,IAAI,GAAG,MAAM;AACnC,QAAM,eAAe,YAAY,MAAM,OAAO;AAE9C,SAAO,QAAQ,IAAI,CAAC,SAAS,UAAU;;AACrC,UAAM,QAAQ,cAAa,aAAQ,eAAR,mBAAoB,KAAK;AACpD,UAAM,OAAO,UAAU,OAAO,MAAM,aAAa,UAAU,QAAQ;AACnE,UAAM,WAAW,SAAO,aAAQ,eAAR,mBAAoB,aAAY,EAAE;AAC1D,UAAM,WAAW,cAAc,YAAY,IAAI,KAAK,GAAG,WAAW,IAAI,YAAY,QAAQ,CAAC,KAAK,EAAE;AAClG,UAAM,QAAQ,MAAM,UAAU,QAAQ,KAAK,EAAE;AAC7C,UAAM,YACJ,SAAO,aAAQ,eAAR,mBAAoB,eAAc,WACrC,QAAQ,WAAW,YACnB,SAAO,aAAQ,eAAR,mBAAoB,WAAU,WACnC,QAAQ,WAAW,QACnB;AACR,UAAM,aAAa,SAAS,MAAM,OAAO,SAAS;AAClD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,YAAY;AAAA,QACV,GAAG,QAAQ;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,MAAM;AAAA,MAAA;AAAA,IACjB;AAAA,EAEJ,CAAC;AACH;AAEA,SAAS,UACP,OACA,QACA,UACA,UACQ;AACR,MAAI,OAAO,QAAQ;AACjB,UAAM,QAAQ,OAAO,KAAK,CAAC,MAAM,SAAS,EAAE,SAAS,SAAS,EAAE,GAAG;AACnE,QAAI,+BAAO,OAAQ,QAAO,MAAM;AAChC,QAAI,QAAQ,OAAO,CAAC,EAAE,SAAS,OAAO,CAAC,EAAE,OAAQ,QAAO,OAAO,CAAC,EAAE;AAClE,UAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AACrC,QAAI,QAAQ,KAAK,OAAO,KAAK,eAAe,KAAK;AAAA,EACnD;AACA,MAAI,aAAa,SAAU,QAAO;AAClC,QAAM,SAAS,QAAQ,aAAa,WAAW;AAC/C,QAAM,UAAU,CAAC,GAAG,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE;AAC9C,SAAO,QAAQ,KAAK,MAAM,SAAS,QAAQ,SAAS,EAAE,CAAC,KAAK;AAC9D;AAEA,SAAS,SAAS,MAAc,OAAe,MAAuB;AACpE,QAAM,MAAM,MAAM,WAAW,GAAG,IAAI,QAAQ,IAAI,KAAK;AACrD,QAAM,OAAO,UAAU,KAAK,CAAC;AAC7B,QAAM,eAAe;AACrB,QAAM,WAAW;AACjB,QAAM,aAAa,WAAW;AAC9B,QAAM,MAAM;AACZ,QAAM,cAAc,OAAO,aAAa,MAAM,eAAe;AAC7D,QAAM,eAAe,OAAO,aAAa,MAAM;AAC/C,QAAM,aAAa;AACnB,QAAM,WAAW,OAAO,KAAK,IAAI,YAAY,KAAK,SAAS,KAAK,EAAE,IAAI;AACtE,QAAM,eAAe,QAAQ,WAAW,cAAc,IAAI;AAC1D,QAAM,UAAU,aAAa;AAC7B,QAAM,OAAO,UAAU;AACvB,QAAM,QAAQ,UAAU;AACxB,QAAM,MAAM;AACZ,QAAM,SAAS,eAAe;AAC9B,QAAM,SAAS,OACX,YAAY,WAAW,CAAC,QAAQ,WAAW,CAAC,kDAAkD,QAAQ,6GAA6G,UAAU,IAAI,CAAC,YAClO;AAEJ,SAAO,eAAe,QAAQ,aAAa,WAAW,kBAAkB,QAAQ,IAAI,WAAW,4EAA4E,YAAY,KAAK,YAAY,gBAAgB,KAAK,IAAI,MAAM,IAAI,OAAO,IAAI,GAAG,IAAI,IAAI,IAAI,MAAM,YAAY,IAAI,gBAAgB,UAAU,EAAE,IAAI,MAAM,IAAI,QAAQ,CAAC,IAAI,OAAO,IAAI,GAAG,IAAI,OAAO,CAAC,IAAI,MAAM,IAAI,UAAU,EAAE,aAAa,IAAI,uCAAuC,MAAM;AACtc;AAEA,SAAS,UAAU,OAAuB;AACxC,SAAO,MACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ;AAC3B;AAEO,SAAS,mBAAmB,OAAsD;AACvF,SAAO,UAAU,gBAAgB,UAAU,aAAa,UAAU,WAAW,UAAU;AACzF;"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { MapVisualisation } from './constants.js';
|
|
2
|
+
import { ColorRange, GeoJsonFeature } from './types.js';
|
|
3
|
+
/** Inclusive-left, exclusive-right bucket window — FuseDash MapLegend RangeInput. */
|
|
4
|
+
export type LayerSlider = {
|
|
5
|
+
leftSlider: number;
|
|
6
|
+
rightSlider: number;
|
|
7
|
+
};
|
|
8
|
+
export declare const MUTED_LEGEND_FILL = "#6C758429";
|
|
9
|
+
export declare function defaultLayerSlider(rangeCount: number): LayerSlider;
|
|
10
|
+
/**
|
|
11
|
+
* FuseDash RangeInput: left stays strictly below right, right strictly above
|
|
12
|
+
* left — thumbs never share a slot.
|
|
13
|
+
*/
|
|
14
|
+
export declare function slideThumb(current: LayerSlider, edge: 'leftSlider' | 'rightSlider', raw: number, rangeCount: number): LayerSlider;
|
|
15
|
+
export declare function clampLayerSlider(next: LayerSlider, rangeCount: number): LayerSlider | null;
|
|
16
|
+
export declare function sliderIndexFromPointer(clientX: number, track: {
|
|
17
|
+
left: number;
|
|
18
|
+
width: number;
|
|
19
|
+
}, rangeCount: number): number;
|
|
20
|
+
/** FuseDash RangeInput `getThumbPosition` — percent along that thumb's track. */
|
|
21
|
+
export declare function thumbTrackPercent(value: number, rangeCount: number): string;
|
|
22
|
+
/** FuseDash RangeInput track shift: 7px when a thumb sits on 0 or MAX. */
|
|
23
|
+
export declare function rangeTrackOffset(edge: 'left' | 'right', value: number, rangeCount: number): string;
|
|
24
|
+
export declare function sliderValueWindow(ranges: ColorRange[], slider: LayerSlider): {
|
|
25
|
+
start: number;
|
|
26
|
+
end: number;
|
|
27
|
+
};
|
|
28
|
+
/** FuseDash year filter — rows without the selected year drop out. */
|
|
29
|
+
export declare function featuresForYear(features: GeoJsonFeature[], year: string | undefined, yearKey: string): GeoJsonFeature[];
|
|
30
|
+
/** Keep marks whose value sits inside the legend thumb window. */
|
|
31
|
+
export declare function featuresInSliderRange(features: GeoJsonFeature[], ranges: ColorRange[], slider: LayerSlider): GeoJsonFeature[];
|
|
32
|
+
/** FuseDash MapLegend lists markers → spikes → bubbles → choropleth. */
|
|
33
|
+
export declare function legendLayerOrder<T extends {
|
|
34
|
+
visualisationType: MapVisualisation;
|
|
35
|
+
}>(layers: T[]): T[];
|
|
36
|
+
export declare function layerAverage(values: number[]): number;
|
|
37
|
+
/** Client MapLegendItem `renderValue`. */
|
|
38
|
+
export declare function formatAverage(value: number): string;
|
|
39
|
+
/** Client `formatCapitalizedText` — first word capped, `_`/`-` → spaces. */
|
|
40
|
+
export declare function formatFieldLabel(text: string): string;
|
|
41
|
+
/** Client MapLegendItem `formatValue` — abbreviated bucket edge. */
|
|
42
|
+
export declare function formatLegendBucket(value: number, toFixed?: number): string;
|
|
43
|
+
/** Legend spikes use DEFAULT_SPIKE_SIZES, not the map `range.height` (those go to 100px). */
|
|
44
|
+
export declare function legendSpikeHeight(index: number): number;
|
|
45
|
+
//# sourceMappingURL=legend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legend.d.ts","sourceRoot":"","sources":["../../../../src/components/map-chart/lib/legend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEzF,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7D,qFAAqF;AACrF,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,iBAAiB,cAAc,CAAC;AAE7C,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,CAElE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,YAAY,GAAG,aAAa,EAClC,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,GACjB,WAAW,CAYb;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAM1F;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EACtC,UAAU,EAAE,MAAM,GACjB,MAAM,CAKR;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAG3E;AAED,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAIlG;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,UAAU,EAAE,EACpB,MAAM,EAAE,WAAW,GAClB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAIhC;AAED,sEAAsE;AACtE,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,cAAc,EAAE,EAC1B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,MAAM,GACd,cAAc,EAAE,CAGlB;AAED,kEAAkE;AAClE,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,cAAc,EAAE,EAC1B,MAAM,EAAE,UAAU,EAAE,EACpB,MAAM,EAAE,WAAW,GAClB,cAAc,EAAE,CAOlB;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,CAAC,SAAS;IAAE,iBAAiB,EAAE,gBAAgB,CAAA;CAAE,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAIpG;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAGrD;AAED,0CAA0C;AAC1C,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAInD;AAED,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKrD;AAED,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,SAAI,GAAG,MAAM,CASrE;AAED,6FAA6F;AAC7F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGvD"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { LAYER_ORDER, DEFAULT_SPIKE_SIZES } from "./constants.js";
|
|
2
|
+
import { numericValue } from "./format.js";
|
|
3
|
+
const MUTED_LEGEND_FILL = "#6C758429";
|
|
4
|
+
function defaultLayerSlider(rangeCount) {
|
|
5
|
+
return { leftSlider: 0, rightSlider: Math.max(rangeCount, 1) };
|
|
6
|
+
}
|
|
7
|
+
function slideThumb(current, edge, raw, rangeCount) {
|
|
8
|
+
const max = Math.max(rangeCount, 1);
|
|
9
|
+
if (edge === "leftSlider") {
|
|
10
|
+
return {
|
|
11
|
+
leftSlider: Math.max(0, Math.min(current.rightSlider - 1, raw)),
|
|
12
|
+
rightSlider: current.rightSlider
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
leftSlider: current.leftSlider,
|
|
17
|
+
rightSlider: Math.max(current.leftSlider + 1, Math.min(max, raw))
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function sliderIndexFromPointer(clientX, track, rangeCount) {
|
|
21
|
+
const max = Math.max(rangeCount, 1);
|
|
22
|
+
if (track.width <= 0) return 0;
|
|
23
|
+
const ratio = (clientX - track.left) / track.width;
|
|
24
|
+
return Math.max(0, Math.min(max, Math.round(ratio * max)));
|
|
25
|
+
}
|
|
26
|
+
function thumbTrackPercent(value, rangeCount) {
|
|
27
|
+
const max = Math.max(rangeCount, 1);
|
|
28
|
+
return `${value / max * 100}%`;
|
|
29
|
+
}
|
|
30
|
+
function rangeTrackOffset(edge, value, rangeCount) {
|
|
31
|
+
const max = Math.max(rangeCount, 1);
|
|
32
|
+
if (edge === "left") return value === 0 ? "7px" : "0px";
|
|
33
|
+
return value === max ? "7px" : "0px";
|
|
34
|
+
}
|
|
35
|
+
function sliderValueWindow(ranges, slider) {
|
|
36
|
+
var _a, _b;
|
|
37
|
+
const start = ((_a = ranges[slider.leftSlider]) == null ? void 0 : _a.start) ?? 0;
|
|
38
|
+
const end = ((_b = ranges[Math.max(0, slider.rightSlider - 1)]) == null ? void 0 : _b.end) ?? 0;
|
|
39
|
+
return { start, end };
|
|
40
|
+
}
|
|
41
|
+
function featuresForYear(features, year, yearKey) {
|
|
42
|
+
if (!year) return features;
|
|
43
|
+
return features.filter((feature) => {
|
|
44
|
+
var _a;
|
|
45
|
+
return String(((_a = feature.properties) == null ? void 0 : _a[yearKey]) ?? "") === year;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function featuresInSliderRange(features, ranges, slider) {
|
|
49
|
+
if (!ranges.length) return features;
|
|
50
|
+
const { start, end } = sliderValueWindow(ranges, slider);
|
|
51
|
+
return features.filter((feature) => {
|
|
52
|
+
var _a;
|
|
53
|
+
const value = numericValue((_a = feature.properties) == null ? void 0 : _a.value);
|
|
54
|
+
return value >= start && value <= end;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function legendLayerOrder(layers) {
|
|
58
|
+
return [...layers].sort(
|
|
59
|
+
(a, b) => (LAYER_ORDER[a.visualisationType] ?? 99) - (LAYER_ORDER[b.visualisationType] ?? 99)
|
|
60
|
+
).reverse();
|
|
61
|
+
}
|
|
62
|
+
function layerAverage(values) {
|
|
63
|
+
if (!values.length) return 0;
|
|
64
|
+
return values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
65
|
+
}
|
|
66
|
+
function formatAverage(value) {
|
|
67
|
+
if (!Number.isFinite(value)) return "0";
|
|
68
|
+
const decimals = value % 1 !== 0 ? 2 : 0;
|
|
69
|
+
return value.toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
70
|
+
}
|
|
71
|
+
function formatFieldLabel(text) {
|
|
72
|
+
if (!text) return "";
|
|
73
|
+
if (!Number.isNaN(Number(text))) return text;
|
|
74
|
+
const formatted = text.replace(/[_-]/g, " ").replace(/\s+/g, " ").trim();
|
|
75
|
+
return formatted.charAt(0).toUpperCase() + formatted.slice(1).toLowerCase();
|
|
76
|
+
}
|
|
77
|
+
function formatLegendBucket(value, toFixed = 2) {
|
|
78
|
+
if (!Number.isFinite(value) || value === Infinity || value === -Infinity) return "0";
|
|
79
|
+
if (Math.abs(value) < 1e3) return value.toFixed(toFixed);
|
|
80
|
+
const abbreviations = ["B", "M", "K"];
|
|
81
|
+
for (let i = 0; i < abbreviations.length; i++) {
|
|
82
|
+
const unit = Math.pow(1e3, abbreviations.length - i);
|
|
83
|
+
if (Math.abs(value) >= unit) return `${(value / unit).toFixed(1)} ${abbreviations[i]}`;
|
|
84
|
+
}
|
|
85
|
+
return value.toFixed(toFixed);
|
|
86
|
+
}
|
|
87
|
+
function legendSpikeHeight(index) {
|
|
88
|
+
const size = DEFAULT_SPIKE_SIZES[index] ?? 8;
|
|
89
|
+
return Math.max(0, Math.round(size - size / 5));
|
|
90
|
+
}
|
|
91
|
+
export {
|
|
92
|
+
MUTED_LEGEND_FILL,
|
|
93
|
+
defaultLayerSlider,
|
|
94
|
+
featuresForYear,
|
|
95
|
+
featuresInSliderRange,
|
|
96
|
+
formatAverage,
|
|
97
|
+
formatFieldLabel,
|
|
98
|
+
formatLegendBucket,
|
|
99
|
+
layerAverage,
|
|
100
|
+
legendLayerOrder,
|
|
101
|
+
legendSpikeHeight,
|
|
102
|
+
rangeTrackOffset,
|
|
103
|
+
slideThumb,
|
|
104
|
+
sliderIndexFromPointer,
|
|
105
|
+
sliderValueWindow,
|
|
106
|
+
thumbTrackPercent
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=legend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legend.js","sources":["../../../../src/components/map-chart/lib/legend.ts"],"sourcesContent":["import { DEFAULT_SPIKE_SIZES, LAYER_ORDER, type MapVisualisation } from './constants.js';\nimport { numericValue } from './format.js';\nimport type { ColorRange, GeoJsonFeature } from './types.js';\n\n/** Inclusive-left, exclusive-right bucket window — FuseDash MapLegend RangeInput. */\nexport type LayerSlider = {\n leftSlider: number;\n rightSlider: number;\n};\n\nexport const MUTED_LEGEND_FILL = '#6C758429';\n\nexport function defaultLayerSlider(rangeCount: number): LayerSlider {\n return { leftSlider: 0, rightSlider: Math.max(rangeCount, 1) };\n}\n\n/**\n * FuseDash RangeInput: left stays strictly below right, right strictly above\n * left — thumbs never share a slot.\n */\nexport function slideThumb(\n current: LayerSlider,\n edge: 'leftSlider' | 'rightSlider',\n raw: number,\n rangeCount: number,\n): LayerSlider {\n const max = Math.max(rangeCount, 1);\n if (edge === 'leftSlider') {\n return {\n leftSlider: Math.max(0, Math.min(current.rightSlider - 1, raw)),\n rightSlider: current.rightSlider,\n };\n }\n return {\n leftSlider: current.leftSlider,\n rightSlider: Math.max(current.leftSlider + 1, Math.min(max, raw)),\n };\n}\n\nexport function clampLayerSlider(next: LayerSlider, rangeCount: number): LayerSlider | null {\n const max = Math.max(rangeCount, 1);\n const left = Math.max(0, Math.min(max, next.leftSlider));\n const right = Math.max(0, Math.min(max, next.rightSlider));\n if (left >= right) return null;\n return { leftSlider: left, rightSlider: right };\n}\n\nexport function sliderIndexFromPointer(\n clientX: number,\n track: { left: number; width: number },\n rangeCount: number,\n): number {\n const max = Math.max(rangeCount, 1);\n if (track.width <= 0) return 0;\n const ratio = (clientX - track.left) / track.width;\n return Math.max(0, Math.min(max, Math.round(ratio * max)));\n}\n\n/** FuseDash RangeInput `getThumbPosition` — percent along that thumb's track. */\nexport function thumbTrackPercent(value: number, rangeCount: number): string {\n const max = Math.max(rangeCount, 1);\n return `${(value / max) * 100}%`;\n}\n\n/** FuseDash RangeInput track shift: 7px when a thumb sits on 0 or MAX. */\nexport function rangeTrackOffset(edge: 'left' | 'right', value: number, rangeCount: number): string {\n const max = Math.max(rangeCount, 1);\n if (edge === 'left') return value === 0 ? '7px' : '0px';\n return value === max ? '7px' : '0px';\n}\n\nexport function sliderValueWindow(\n ranges: ColorRange[],\n slider: LayerSlider,\n): { start: number; end: number } {\n const start = ranges[slider.leftSlider]?.start ?? 0;\n const end = ranges[Math.max(0, slider.rightSlider - 1)]?.end ?? 0;\n return { start, end };\n}\n\n/** FuseDash year filter — rows without the selected year drop out. */\nexport function featuresForYear(\n features: GeoJsonFeature[],\n year: string | undefined,\n yearKey: string,\n): GeoJsonFeature[] {\n if (!year) return features;\n return features.filter((feature) => String(feature.properties?.[yearKey] ?? '') === year);\n}\n\n/** Keep marks whose value sits inside the legend thumb window. */\nexport function featuresInSliderRange(\n features: GeoJsonFeature[],\n ranges: ColorRange[],\n slider: LayerSlider,\n): GeoJsonFeature[] {\n if (!ranges.length) return features;\n const { start, end } = sliderValueWindow(ranges, slider);\n return features.filter((feature) => {\n const value = numericValue(feature.properties?.value);\n return value >= start && value <= end;\n });\n}\n\n/** FuseDash MapLegend lists markers → spikes → bubbles → choropleth. */\nexport function legendLayerOrder<T extends { visualisationType: MapVisualisation }>(layers: T[]): T[] {\n return [...layers].sort(\n (a, b) => (LAYER_ORDER[a.visualisationType] ?? 99) - (LAYER_ORDER[b.visualisationType] ?? 99),\n ).reverse();\n}\n\nexport function layerAverage(values: number[]): number {\n if (!values.length) return 0;\n return values.reduce((sum, value) => sum + value, 0) / values.length;\n}\n\n/** Client MapLegendItem `renderValue`. */\nexport function formatAverage(value: number): string {\n if (!Number.isFinite(value)) return '0';\n const decimals = value % 1 !== 0 ? 2 : 0;\n return value.toFixed(decimals).replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\n/** Client `formatCapitalizedText` — first word capped, `_`/`-` → spaces. */\nexport function formatFieldLabel(text: string): string {\n if (!text) return '';\n if (!Number.isNaN(Number(text))) return text;\n const formatted = text.replace(/[_-]/g, ' ').replace(/\\s+/g, ' ').trim();\n return formatted.charAt(0).toUpperCase() + formatted.slice(1).toLowerCase();\n}\n\n/** Client MapLegendItem `formatValue` — abbreviated bucket edge. */\nexport function formatLegendBucket(value: number, toFixed = 2): string {\n if (!Number.isFinite(value) || value === Infinity || value === -Infinity) return '0';\n if (Math.abs(value) < 1000) return value.toFixed(toFixed);\n const abbreviations = ['B', 'M', 'K'];\n for (let i = 0; i < abbreviations.length; i++) {\n const unit = Math.pow(1000, abbreviations.length - i);\n if (Math.abs(value) >= unit) return `${(value / unit).toFixed(1)} ${abbreviations[i]}`;\n }\n return value.toFixed(toFixed);\n}\n\n/** Legend spikes use DEFAULT_SPIKE_SIZES, not the map `range.height` (those go to 100px). */\nexport function legendSpikeHeight(index: number): number {\n const size = DEFAULT_SPIKE_SIZES[index] ?? 8;\n return Math.max(0, Math.round(size - size / 5));\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { GeoJsonFeatureCollection, MapChartInput, MapModel } from './types.js';
|
|
2
|
+
export declare function normalizeMapData(input: MapChartInput, geoJson?: GeoJsonFeatureCollection | Record<string, GeoJsonFeatureCollection>): MapModel;
|
|
3
|
+
//# sourceMappingURL=normalize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../src/components/map-chart/lib/normalize.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,wBAAwB,EACxB,aAAa,EAIb,QAAQ,EAGT,MAAM,YAAY,CAAC;AAsBpB,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,aAAa,EACpB,OAAO,CAAC,EAAE,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,GAC5E,QAAQ,CAqFV"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { resolveFormattingColor, SEQUENTIAL_1, QUALITATIVE_2 } from "../../../utils/fuse-palette.js";
|
|
2
|
+
import { valuesOfRows, rangesFromPaletteStops, generateColorRanges } from "./domain.js";
|
|
3
|
+
import { inferMapTypeFromKeyNames } from "./geo-index.js";
|
|
4
|
+
import { isFeatureCollection } from "./geojson.js";
|
|
5
|
+
import { isMapVisualisation, joinLayerFeatures } from "./join.js";
|
|
6
|
+
import { layerAverage } from "./legend.js";
|
|
7
|
+
const EMPTY = { title: "", terrain: false, showLegend: true, layers: [] };
|
|
8
|
+
function asRecord(value) {
|
|
9
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
function rowsFromUnknown(value) {
|
|
13
|
+
if (!Array.isArray(value)) return [];
|
|
14
|
+
return value.filter(
|
|
15
|
+
(row) => !!row && typeof row === "object" && !Array.isArray(row)
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
function isChatRow(value) {
|
|
19
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
20
|
+
const row = value;
|
|
21
|
+
return typeof row.label === "string" && typeof row.value === "number";
|
|
22
|
+
}
|
|
23
|
+
function normalizeMapData(input, geoJson) {
|
|
24
|
+
if (input == null) return EMPTY;
|
|
25
|
+
if (Array.isArray(input)) {
|
|
26
|
+
if (!input.length) return EMPTY;
|
|
27
|
+
if (isChatRow(input[0])) {
|
|
28
|
+
return normalizeMapData(
|
|
29
|
+
{
|
|
30
|
+
name: "",
|
|
31
|
+
chartType: "mapChart",
|
|
32
|
+
layers: [
|
|
33
|
+
{
|
|
34
|
+
name: "Map",
|
|
35
|
+
visualisationType: "choropleth",
|
|
36
|
+
geospatialData: ["label"],
|
|
37
|
+
arrangeByMetric: ["value"],
|
|
38
|
+
data: input.map((row) => ({
|
|
39
|
+
label: row.label,
|
|
40
|
+
value: row.value
|
|
41
|
+
})),
|
|
42
|
+
mapType: input[0].mapType ?? "country"
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
geoJson
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return EMPTY;
|
|
50
|
+
}
|
|
51
|
+
const obj = asRecord(input);
|
|
52
|
+
if (!obj) return EMPTY;
|
|
53
|
+
if (Array.isArray(obj.points)) {
|
|
54
|
+
const points = obj.points;
|
|
55
|
+
return normalizeMapData(
|
|
56
|
+
points.map((p) => ({ label: String(p.x ?? ""), value: Number(p.y ?? 0) })),
|
|
57
|
+
geoJson
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
if (Array.isArray(obj.regions)) {
|
|
61
|
+
const regions = obj.regions;
|
|
62
|
+
return normalizeMapData(
|
|
63
|
+
regions.map((r) => ({
|
|
64
|
+
label: String(r.name ?? r.label ?? ""),
|
|
65
|
+
value: Number(r.value ?? 0)
|
|
66
|
+
})),
|
|
67
|
+
geoJson
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
const widget = obj;
|
|
71
|
+
const rawLayers = (widget.layers ?? []).filter((layer) => !layer.hideLayer);
|
|
72
|
+
const fallbackRows = rowsFromUnknown(widget.data);
|
|
73
|
+
const layersIn = rawLayers.length > 0 ? rawLayers : fallbackRows.length ? [
|
|
74
|
+
{
|
|
75
|
+
name: widget.name ?? "Map",
|
|
76
|
+
visualisationType: widget.visualisationType ?? "choropleth",
|
|
77
|
+
geospatialData: inferKeys(fallbackRows),
|
|
78
|
+
arrangeByMetric: inferValueKeys(fallbackRows),
|
|
79
|
+
data: fallbackRows,
|
|
80
|
+
mapType: widget.mapType,
|
|
81
|
+
formatting: widget.formatting
|
|
82
|
+
}
|
|
83
|
+
] : [];
|
|
84
|
+
if (!layersIn.length) return EMPTY;
|
|
85
|
+
const inlineGeo = resolveGeoJson(widget.geoJson ?? geoJson);
|
|
86
|
+
const layers = layersIn.map(
|
|
87
|
+
(layer, index) => buildLayer(layer, index, widget, inlineGeo[layer.mapType ?? ""] ?? widget.geoJson ?? void 0)
|
|
88
|
+
);
|
|
89
|
+
return {
|
|
90
|
+
title: typeof widget.name === "string" ? widget.name : "",
|
|
91
|
+
terrain: Boolean(widget.terrain),
|
|
92
|
+
showLegend: widget.legend !== false,
|
|
93
|
+
layers
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function inferKeys(rows) {
|
|
97
|
+
const first = rows[0];
|
|
98
|
+
if (!first) return ["label"];
|
|
99
|
+
const geo = Object.keys(first).find((k) => inferMapTypeFromKeyNames([k]));
|
|
100
|
+
if (geo) return [geo];
|
|
101
|
+
if ("label" in first) return ["label"];
|
|
102
|
+
return [Object.keys(first)[0] ?? "label"];
|
|
103
|
+
}
|
|
104
|
+
function inferValueKeys(rows) {
|
|
105
|
+
const first = rows[0];
|
|
106
|
+
if (!first) return ["value"];
|
|
107
|
+
if ("value" in first) return ["value"];
|
|
108
|
+
const numeric = Object.keys(first).find((k) => typeof first[k] === "number");
|
|
109
|
+
return [numeric ?? "value"];
|
|
110
|
+
}
|
|
111
|
+
function resolveGeoJson(geoJson) {
|
|
112
|
+
if (!geoJson) return {};
|
|
113
|
+
if (isFeatureCollection(geoJson)) {
|
|
114
|
+
return { country: geoJson, "": geoJson };
|
|
115
|
+
}
|
|
116
|
+
return geoJson;
|
|
117
|
+
}
|
|
118
|
+
function buildLayer(layer, index, widget, geoJson) {
|
|
119
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
120
|
+
const rows = rowsFromUnknown(layer.data);
|
|
121
|
+
const visualisationType = isMapVisualisation(layer.visualisationType) ? layer.visualisationType : "choropleth";
|
|
122
|
+
const geoKey = ((_a = layer.geospatialData) == null ? void 0 : _a[0]) ?? inferKeys(rows)[0] ?? "label";
|
|
123
|
+
const valueKey = ((_b = layer.arrangeByMetric) == null ? void 0 : _b[0]) ?? inferValueKeys(rows)[0] ?? "value";
|
|
124
|
+
const mapType = layer.mapType || inferMapTypeFromKeyNames(layer.geospatialData ?? []) || inferMapTypeFromKeyNames([geoKey]) || "country";
|
|
125
|
+
const values = valuesOfRows(rows, valueKey);
|
|
126
|
+
const formatting = ((_c = layer.formatting) == null ? void 0 : _c.length) ? layer.formatting : widget.formatting ?? [];
|
|
127
|
+
const isQualitative = visualisationType === "bubbles" || visualisationType === "spike" || visualisationType === "markers";
|
|
128
|
+
const customHex = (_f = (_e = (_d = layer.palette) == null ? void 0 : _d.customColors) == null ? void 0 : _e.find((c) => c.hex)) == null ? void 0 : _f.hex;
|
|
129
|
+
const fillColor = customHex ?? (isQualitative ? resolveFormattingColor(formatting, "default", formatting.length || 1) : SEQUENTIAL_1[3]);
|
|
130
|
+
const paletteColors = isQualitative ? [fillColor, ...QUALITATIVE_2.filter((c) => c !== fillColor)] : [...SEQUENTIAL_1];
|
|
131
|
+
const paletteRange = (_g = layer.palette) == null ? void 0 : _g.range;
|
|
132
|
+
const colorRanges = paletteRange && paletteRange.length > 1 ? rangesFromPaletteStops(paletteRange, paletteColors) : generateColorRanges(values, paletteColors);
|
|
133
|
+
const years = collectYears(rows, layer.timePeriod);
|
|
134
|
+
const layerId = String(layer.layerId || layer.query || layer.name || `layer-${index}`);
|
|
135
|
+
const model = {
|
|
136
|
+
layerId,
|
|
137
|
+
layerName: layer.name || "Map",
|
|
138
|
+
visualisationType,
|
|
139
|
+
mapType,
|
|
140
|
+
geoKey,
|
|
141
|
+
valueKey,
|
|
142
|
+
yearKey: ((_h = layer.timePeriod) == null ? void 0 : _h.field) || "year",
|
|
143
|
+
rows,
|
|
144
|
+
values,
|
|
145
|
+
colorRanges,
|
|
146
|
+
fillColor,
|
|
147
|
+
average: layerAverage(values),
|
|
148
|
+
years: years.years,
|
|
149
|
+
selectedYear: years.year,
|
|
150
|
+
features: [],
|
|
151
|
+
colorById: {},
|
|
152
|
+
matchTotal: 0,
|
|
153
|
+
matchHit: 0
|
|
154
|
+
};
|
|
155
|
+
const layerGeo = layer.geoJson ?? geoJson;
|
|
156
|
+
return layerGeo ? joinLayerFeatures(model, layerGeo) : model;
|
|
157
|
+
}
|
|
158
|
+
function collectYears(rows, timePeriod) {
|
|
159
|
+
var _a;
|
|
160
|
+
if ((_a = timePeriod == null ? void 0 : timePeriod.values) == null ? void 0 : _a.length) {
|
|
161
|
+
return { year: timePeriod.values[0], years: [...timePeriod.values] };
|
|
162
|
+
}
|
|
163
|
+
const field = (timePeriod == null ? void 0 : timePeriod.field) || "year";
|
|
164
|
+
const years = [];
|
|
165
|
+
for (const row of rows) {
|
|
166
|
+
const value = row[field];
|
|
167
|
+
if (value == null || value === "") continue;
|
|
168
|
+
const text = String(value);
|
|
169
|
+
if (!years.includes(text)) years.push(text);
|
|
170
|
+
}
|
|
171
|
+
years.sort();
|
|
172
|
+
return { year: years[0], years };
|
|
173
|
+
}
|
|
174
|
+
export {
|
|
175
|
+
normalizeMapData
|
|
176
|
+
};
|
|
177
|
+
//# sourceMappingURL=normalize.js.map
|