@fusedashlabs/widgets 0.4.0 → 0.4.2
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 +21 -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 +18 -4
- 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 +3 -1
- package/dist/components/chart-renderer/lib/registry.js.map +1 -1
- package/dist/components/kpi-widget/element/styles.d.ts.map +1 -1
- package/dist/components/kpi-widget/element/styles.js +268 -5
- package/dist/components/kpi-widget/element/styles.js.map +1 -1
- package/dist/components/kpi-widget/element/ui9000-kpi-widget.d.ts +10 -1
- package/dist/components/kpi-widget/element/ui9000-kpi-widget.d.ts.map +1 -1
- package/dist/components/kpi-widget/element/ui9000-kpi-widget.js +154 -27
- package/dist/components/kpi-widget/element/ui9000-kpi-widget.js.map +1 -1
- package/dist/components/kpi-widget/index.d.ts +1 -1
- package/dist/components/kpi-widget/index.d.ts.map +1 -1
- package/dist/components/kpi-widget/index.js +7 -4
- package/dist/components/kpi-widget/lib/extract.d.ts +5 -1
- package/dist/components/kpi-widget/lib/extract.d.ts.map +1 -1
- package/dist/components/kpi-widget/lib/extract.js +110 -34
- package/dist/components/kpi-widget/lib/extract.js.map +1 -1
- package/dist/components/kpi-widget/lib/format.d.ts +5 -0
- package/dist/components/kpi-widget/lib/format.d.ts.map +1 -1
- package/dist/components/kpi-widget/lib/format.js +10 -1
- package/dist/components/kpi-widget/lib/format.js.map +1 -1
- package/dist/components/kpi-widget/lib/grid.d.ts +5 -0
- package/dist/components/kpi-widget/lib/grid.d.ts.map +1 -1
- package/dist/components/kpi-widget/lib/grid.js +18 -0
- package/dist/components/kpi-widget/lib/grid.js.map +1 -1
- package/dist/components/kpi-widget/lib/index.d.ts +5 -5
- package/dist/components/kpi-widget/lib/index.d.ts.map +1 -1
- package/dist/components/kpi-widget/lib/normalize.d.ts +2 -0
- package/dist/components/kpi-widget/lib/normalize.d.ts.map +1 -1
- package/dist/components/kpi-widget/lib/normalize.js +73 -12
- package/dist/components/kpi-widget/lib/normalize.js.map +1 -1
- package/dist/components/kpi-widget/lib/types.d.ts +41 -0
- package/dist/components/kpi-widget/lib/types.d.ts.map +1 -1
- package/dist/components/kpi-widget/metadata.json.d.ts +1 -1
- package/dist/components/kpi-widget/metadata.json.js +1 -1
- package/dist/components/map-chart/element/ui9000-map-chart.d.ts +1 -0
- package/dist/components/map-chart/element/ui9000-map-chart.d.ts.map +1 -1
- package/dist/components/map-chart/element/ui9000-map-chart.js +12 -4
- package/dist/components/map-chart/element/ui9000-map-chart.js.map +1 -1
- package/dist/components/map-chart/lib/geojson.d.ts.map +1 -1
- package/dist/components/map-chart/lib/geojson.js +3 -1
- package/dist/components/map-chart/lib/geojson.js.map +1 -1
- package/dist/components/map-chart/metadata.json.d.ts +1 -1
- package/dist/components/map-chart/metadata.json.js +1 -1
- package/dist/components/map-chart/render/draw.d.ts.map +1 -1
- package/dist/components/map-chart/render/draw.js +2 -1
- package/dist/components/map-chart/render/draw.js.map +1 -1
- package/dist/components/partial-dependence-chart/element/styles.d.ts +2 -0
- package/dist/components/partial-dependence-chart/element/styles.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/element/styles.js +48 -0
- package/dist/components/partial-dependence-chart/element/styles.js.map +1 -0
- package/dist/components/partial-dependence-chart/element/ui9000-partial-dependence-chart.d.ts +30 -0
- package/dist/components/partial-dependence-chart/element/ui9000-partial-dependence-chart.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/element/ui9000-partial-dependence-chart.js +163 -0
- package/dist/components/partial-dependence-chart/element/ui9000-partial-dependence-chart.js.map +1 -0
- package/dist/components/partial-dependence-chart/index.d.ts +5 -0
- package/dist/components/partial-dependence-chart/index.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/index.js +18 -0
- package/dist/components/partial-dependence-chart/index.js.map +1 -0
- package/dist/components/partial-dependence-chart/lib/domain.d.ts +6 -0
- package/dist/components/partial-dependence-chart/lib/domain.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/lib/domain.js +16 -0
- package/dist/components/partial-dependence-chart/lib/domain.js.map +1 -0
- package/dist/components/partial-dependence-chart/lib/index.d.ts +5 -0
- package/dist/components/partial-dependence-chart/lib/index.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/lib/normalize.d.ts +4 -0
- package/dist/components/partial-dependence-chart/lib/normalize.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/lib/normalize.js +167 -0
- package/dist/components/partial-dependence-chart/lib/normalize.js.map +1 -0
- package/dist/components/partial-dependence-chart/lib/series.d.ts +15 -0
- package/dist/components/partial-dependence-chart/lib/series.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/lib/series.js +63 -0
- package/dist/components/partial-dependence-chart/lib/series.js.map +1 -0
- package/dist/components/partial-dependence-chart/lib/types.d.ts +50 -0
- package/dist/components/partial-dependence-chart/lib/types.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/metadata.json.d.ts +80 -0
- package/dist/components/partial-dependence-chart/metadata.json.js +42 -0
- package/dist/components/partial-dependence-chart/metadata.json.js.map +1 -0
- package/dist/components/partial-dependence-chart/render/draw.d.ts +34 -0
- package/dist/components/partial-dependence-chart/render/draw.d.ts.map +1 -0
- package/dist/components/partial-dependence-chart/render/draw.js +95 -0
- package/dist/components/partial-dependence-chart/render/draw.js.map +1 -0
- package/dist/components/partial-dependence-chart/render/index.d.ts +2 -0
- package/dist/components/partial-dependence-chart/render/index.d.ts.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -10
- package/dist/index.js.map +1 -1
- package/dist/lazy/index.d.ts +2 -1
- package/dist/lazy/index.d.ts.map +1 -1
- package/dist/lazy/index.js +8 -0
- package/dist/lazy/index.js.map +1 -1
- package/dist/lazy/partial-dependence-chart.d.ts +4 -0
- package/dist/lazy/partial-dependence-chart.d.ts.map +1 -0
- package/dist/lazy/partial-dependence-chart.js +5 -0
- package/dist/lazy/partial-dependence-chart.js.map +1 -0
- package/dist/utils/chart-helpers.d.ts +2 -0
- package/dist/utils/chart-helpers.d.ts.map +1 -1
- package/dist/utils/chart-helpers.js +15 -0
- package/dist/utils/chart-helpers.js.map +1 -1
- package/dist/utils/fusedash-visual.d.ts +12 -0
- package/dist/utils/fusedash-visual.d.ts.map +1 -1
- package/dist/utils/fusedash-visual.js +7 -0
- package/dist/utils/fusedash-visual.js.map +1 -1
- package/package.json +11 -2
- package/dist/node_modules/lit-html/directive.js +0 -28
- package/dist/node_modules/lit-html/directive.js.map +0 -1
- package/dist/node_modules/lit-html/directives/style-map.js +0 -37
- package/dist/node_modules/lit-html/directives/style-map.js.map +0 -1
- package/dist/node_modules/lit-html/lit-html.js +0 -231
- package/dist/node_modules/lit-html/lit-html.js.map +0 -1
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export declare const MIN_KPI_CELL_WIDTH = 90;
|
|
2
|
+
export declare const ADVANCED_KPI_VALUE_PERCENT = 25;
|
|
3
|
+
export declare const ADVANCED_KPI_CHART_PERCENT = 75;
|
|
4
|
+
export type AdvancedSplitLayout = 'horizontal' | 'stacked';
|
|
5
|
+
/** Port of client `getAdvancedSplitLayout` (KpiFlexibleComponent/styles). */
|
|
6
|
+
export declare function getAdvancedSplitLayout(width: number, height: number, previousLayout?: AdvancedSplitLayout): AdvancedSplitLayout;
|
|
2
7
|
export declare const getPreferredKpiColumnCounts: (kpiCount: number) => number[];
|
|
3
8
|
export declare const getKpiGridColumns: (containerWidth: number, kpiCount: number, minCellWidth?: number) => number;
|
|
4
9
|
export type KpiGridScrollAxis = 'vertical' | 'horizontal' | 'both';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../../src/components/kpi-widget/lib/grid.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,eAAO,MAAM,2BAA2B,GAAI,UAAU,MAAM,KAAG,MAAM,EAcpE,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,gBAAgB,MAAM,EACtB,UAAU,MAAM,EAChB,eAAc,MAA2B,KACxC,MAWF,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC;AAEnE,eAAO,MAAM,oBAAoB,GAC/B,aAAa,MAAM,EACnB,UAAU,MAAM,KACf,iBAUF,CAAC"}
|
|
1
|
+
{"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../../src/components/kpi-widget/lib/grid.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAC7C,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG,SAAS,CAAC;AAE3D,6EAA6E;AAC7E,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,cAAc,GAAE,mBAAkC,GACjD,mBAAmB,CAkBrB;AAED,eAAO,MAAM,2BAA2B,GAAI,UAAU,MAAM,KAAG,MAAM,EAcpE,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,gBAAgB,MAAM,EACtB,UAAU,MAAM,EAChB,eAAc,MAA2B,KACxC,MAWF,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC;AAEnE,eAAO,MAAM,oBAAoB,GAC/B,aAAa,MAAM,EACnB,UAAU,MAAM,KACf,iBAUF,CAAC"}
|
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
const MIN_KPI_CELL_WIDTH = 90;
|
|
2
|
+
const ADVANCED_KPI_VALUE_PERCENT = 25;
|
|
3
|
+
function getAdvancedSplitLayout(width, height, previousLayout = "horizontal") {
|
|
4
|
+
if (width <= 0 || height <= 0) return previousLayout;
|
|
5
|
+
const valueColWidth = width * (ADVANCED_KPI_VALUE_PERCENT / 100);
|
|
6
|
+
const aspectRatio = height / width;
|
|
7
|
+
if (previousLayout === "stacked") {
|
|
8
|
+
if (valueColWidth >= 64 && width >= 200 && aspectRatio <= 1.45) {
|
|
9
|
+
return "horizontal";
|
|
10
|
+
}
|
|
11
|
+
return "stacked";
|
|
12
|
+
}
|
|
13
|
+
if (valueColWidth < 52 || width < 170 || aspectRatio > 1.62) {
|
|
14
|
+
return "stacked";
|
|
15
|
+
}
|
|
16
|
+
return "horizontal";
|
|
17
|
+
}
|
|
2
18
|
const getPreferredKpiColumnCounts = (kpiCount) => {
|
|
3
19
|
if (kpiCount <= 1) return [1];
|
|
4
20
|
const divisors = [];
|
|
@@ -30,7 +46,9 @@ const getKpiGridScrollAxis = (gridColumns, kpiCount) => {
|
|
|
30
46
|
return "both";
|
|
31
47
|
};
|
|
32
48
|
export {
|
|
49
|
+
ADVANCED_KPI_VALUE_PERCENT,
|
|
33
50
|
MIN_KPI_CELL_WIDTH,
|
|
51
|
+
getAdvancedSplitLayout,
|
|
34
52
|
getKpiGridColumns,
|
|
35
53
|
getKpiGridScrollAxis,
|
|
36
54
|
getPreferredKpiColumnCounts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid.js","sources":["../../../../src/components/kpi-widget/lib/grid.ts"],"sourcesContent":["export const MIN_KPI_CELL_WIDTH = 90;\n\nexport const getPreferredKpiColumnCounts = (kpiCount: number): number[] => {\n if (kpiCount <= 1) return [1];\n\n const divisors: number[] = [];\n for (let i = kpiCount; i >= 1; i -= 1) {\n if (kpiCount % i === 0) divisors.push(i);\n }\n\n if (kpiCount % 2 !== 0 && kpiCount > 2 && !divisors.includes(2)) {\n divisors.push(2);\n divisors.sort((a, b) => b - a);\n }\n\n return divisors;\n};\n\nexport const getKpiGridColumns = (\n containerWidth: number,\n kpiCount: number,\n minCellWidth: number = MIN_KPI_CELL_WIDTH,\n): number => {\n if (kpiCount <= 1) return 1;\n if (containerWidth <= 0) return 1;\n\n const maxColumns = Math.max(\n 1,\n Math.min(kpiCount, Math.floor(containerWidth / minCellWidth)),\n );\n\n const preferred = getPreferredKpiColumnCounts(kpiCount);\n return preferred.find((cols) => cols <= maxColumns) ?? 1;\n};\n\nexport type KpiGridScrollAxis = 'vertical' | 'horizontal' | 'both';\n\nexport const getKpiGridScrollAxis = (\n gridColumns: number,\n kpiCount: number,\n): KpiGridScrollAxis => {\n if (kpiCount <= 1) return 'vertical';\n\n const columns = Math.max(1, gridColumns);\n const gridRows = Math.ceil(kpiCount / columns);\n\n if (columns === 1) return 'vertical';\n if (gridRows === 1) return 'horizontal';\n\n return 'both';\n};\n"],"names":[],"mappings":"AAAO,MAAM,qBAAqB;AAE3B,MAAM,8BAA8B,CAAC,aAA+B;AACzE,MAAI,YAAY,EAAG,QAAO,CAAC,CAAC;AAE5B,QAAM,WAAqB,CAAA;AAC3B,WAAS,IAAI,UAAU,KAAK,GAAG,KAAK,GAAG;AACrC,QAAI,WAAW,MAAM,EAAG,UAAS,KAAK,CAAC;AAAA,EACzC;AAEA,MAAI,WAAW,MAAM,KAAK,WAAW,KAAK,CAAC,SAAS,SAAS,CAAC,GAAG;AAC/D,aAAS,KAAK,CAAC;AACf,aAAS,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAAA,EAC/B;AAEA,SAAO;AACT;AAEO,MAAM,oBAAoB,CAC/B,gBACA,UACA,eAAuB,uBACZ;AACX,MAAI,YAAY,EAAG,QAAO;AAC1B,MAAI,kBAAkB,EAAG,QAAO;AAEhC,QAAM,aAAa,KAAK;AAAA,IACtB;AAAA,IACA,KAAK,IAAI,UAAU,KAAK,MAAM,iBAAiB,YAAY,CAAC;AAAA,EAAA;AAG9D,QAAM,YAAY,4BAA4B,QAAQ;AACtD,SAAO,UAAU,KAAK,CAAC,SAAS,QAAQ,UAAU,KAAK;AACzD;AAIO,MAAM,uBAAuB,CAClC,aACA,aACsB;AACtB,MAAI,YAAY,EAAG,QAAO;AAE1B,QAAM,UAAU,KAAK,IAAI,GAAG,WAAW;AACvC,QAAM,WAAW,KAAK,KAAK,WAAW,OAAO;AAE7C,MAAI,YAAY,EAAG,QAAO;AAC1B,MAAI,aAAa,EAAG,QAAO;AAE3B,SAAO;AACT;"}
|
|
1
|
+
{"version":3,"file":"grid.js","sources":["../../../../src/components/kpi-widget/lib/grid.ts"],"sourcesContent":["export const MIN_KPI_CELL_WIDTH = 90;\n\nexport const ADVANCED_KPI_VALUE_PERCENT = 25;\nexport const ADVANCED_KPI_CHART_PERCENT = 75;\n\nexport type AdvancedSplitLayout = 'horizontal' | 'stacked';\n\n/** Port of client `getAdvancedSplitLayout` (KpiFlexibleComponent/styles). */\nexport function getAdvancedSplitLayout(\n width: number,\n height: number,\n previousLayout: AdvancedSplitLayout = 'horizontal',\n): AdvancedSplitLayout {\n if (width <= 0 || height <= 0) return previousLayout;\n\n const valueColWidth = width * (ADVANCED_KPI_VALUE_PERCENT / 100);\n const aspectRatio = height / width;\n\n if (previousLayout === 'stacked') {\n if (valueColWidth >= 64 && width >= 200 && aspectRatio <= 1.45) {\n return 'horizontal';\n }\n return 'stacked';\n }\n\n if (valueColWidth < 52 || width < 170 || aspectRatio > 1.62) {\n return 'stacked';\n }\n\n return 'horizontal';\n}\n\nexport const getPreferredKpiColumnCounts = (kpiCount: number): number[] => {\n if (kpiCount <= 1) return [1];\n\n const divisors: number[] = [];\n for (let i = kpiCount; i >= 1; i -= 1) {\n if (kpiCount % i === 0) divisors.push(i);\n }\n\n if (kpiCount % 2 !== 0 && kpiCount > 2 && !divisors.includes(2)) {\n divisors.push(2);\n divisors.sort((a, b) => b - a);\n }\n\n return divisors;\n};\n\nexport const getKpiGridColumns = (\n containerWidth: number,\n kpiCount: number,\n minCellWidth: number = MIN_KPI_CELL_WIDTH,\n): number => {\n if (kpiCount <= 1) return 1;\n if (containerWidth <= 0) return 1;\n\n const maxColumns = Math.max(\n 1,\n Math.min(kpiCount, Math.floor(containerWidth / minCellWidth)),\n );\n\n const preferred = getPreferredKpiColumnCounts(kpiCount);\n return preferred.find((cols) => cols <= maxColumns) ?? 1;\n};\n\nexport type KpiGridScrollAxis = 'vertical' | 'horizontal' | 'both';\n\nexport const getKpiGridScrollAxis = (\n gridColumns: number,\n kpiCount: number,\n): KpiGridScrollAxis => {\n if (kpiCount <= 1) return 'vertical';\n\n const columns = Math.max(1, gridColumns);\n const gridRows = Math.ceil(kpiCount / columns);\n\n if (columns === 1) return 'vertical';\n if (gridRows === 1) return 'horizontal';\n\n return 'both';\n};\n"],"names":[],"mappings":"AAAO,MAAM,qBAAqB;AAE3B,MAAM,6BAA6B;AAMnC,SAAS,uBACd,OACA,QACA,iBAAsC,cACjB;AACrB,MAAI,SAAS,KAAK,UAAU,EAAG,QAAO;AAEtC,QAAM,gBAAgB,SAAS,6BAA6B;AAC5D,QAAM,cAAc,SAAS;AAE7B,MAAI,mBAAmB,WAAW;AAChC,QAAI,iBAAiB,MAAM,SAAS,OAAO,eAAe,MAAM;AAC9D,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB,MAAM,QAAQ,OAAO,cAAc,MAAM;AAC3D,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEO,MAAM,8BAA8B,CAAC,aAA+B;AACzE,MAAI,YAAY,EAAG,QAAO,CAAC,CAAC;AAE5B,QAAM,WAAqB,CAAA;AAC3B,WAAS,IAAI,UAAU,KAAK,GAAG,KAAK,GAAG;AACrC,QAAI,WAAW,MAAM,EAAG,UAAS,KAAK,CAAC;AAAA,EACzC;AAEA,MAAI,WAAW,MAAM,KAAK,WAAW,KAAK,CAAC,SAAS,SAAS,CAAC,GAAG;AAC/D,aAAS,KAAK,CAAC;AACf,aAAS,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAAA,EAC/B;AAEA,SAAO;AACT;AAEO,MAAM,oBAAoB,CAC/B,gBACA,UACA,eAAuB,uBACZ;AACX,MAAI,YAAY,EAAG,QAAO;AAC1B,MAAI,kBAAkB,EAAG,QAAO;AAEhC,QAAM,aAAa,KAAK;AAAA,IACtB;AAAA,IACA,KAAK,IAAI,UAAU,KAAK,MAAM,iBAAiB,YAAY,CAAC;AAAA,EAAA;AAG9D,QAAM,YAAY,4BAA4B,QAAQ;AACtD,SAAO,UAAU,KAAK,CAAC,SAAS,QAAQ,UAAU,KAAK;AACzD;AAIO,MAAM,uBAAuB,CAClC,aACA,aACsB;AACtB,MAAI,YAAY,EAAG,QAAO;AAE1B,QAAM,UAAU,KAAK,IAAI,GAAG,WAAW;AACvC,QAAM,WAAW,KAAK,KAAK,WAAW,OAAO;AAE7C,MAAI,YAAY,EAAG,QAAO;AAC1B,MAAI,aAAa,EAAG,QAAO;AAE3B,SAAO;AACT;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { normalizeKpiData } from './normalize.js';
|
|
2
|
-
export { extractCardsFromKpi } from './extract.js';
|
|
3
|
-
export { formatKpiValue } from './format.js';
|
|
4
|
-
export { getKpiGridColumns, getKpiGridScrollAxis, MIN_KPI_CELL_WIDTH, type KpiGridScrollAxis, } from './grid.js';
|
|
5
|
-
export type { KpiCardModel, KpiValueLabel, KpiWidgetData, KpiWidgetModel, RawKpiItem, } from './types.js';
|
|
1
|
+
export { normalizeKpiData, extractGroupId } from './normalize.js';
|
|
2
|
+
export { extractCardsFromKpi, isAdvancedKpiItem, visualisationChartType } from './extract.js';
|
|
3
|
+
export { formatKpiValue, splitFormattedKpiValue } from './format.js';
|
|
4
|
+
export { getKpiGridColumns, getKpiGridScrollAxis, getAdvancedSplitLayout, MIN_KPI_CELL_WIDTH, ADVANCED_KPI_VALUE_PERCENT, ADVANCED_KPI_CHART_PERCENT, type KpiGridScrollAxis, type AdvancedSplitLayout, } from './grid.js';
|
|
5
|
+
export type { KpiCardModel, KpiCardRole, KpiStatusBadge, KpiStatusVariant, KpiValueLabel, KpiWidgetData, KpiWidgetLayout, KpiWidgetModel, RawKpiItem, RawKpiVisualisation, } from './types.js';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/kpi-widget/lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/kpi-widget/lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC9F,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,EAClB,0BAA0B,EAC1B,0BAA0B,EAC1B,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,GACzB,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,YAAY,EACZ,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,eAAe,EACf,cAAc,EACd,UAAU,EACV,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { KpiWidgetData, KpiWidgetModel } from './types.js';
|
|
2
|
+
/** Client `extractGroupId` — groupName is `{label}-group-kpi-ids-{id}`. */
|
|
3
|
+
export declare function extractGroupId(value?: string | null): string;
|
|
2
4
|
/** Normalize chat / FuseDash KPI payloads into display cards. */
|
|
3
5
|
export declare function normalizeKpiData(input: KpiWidgetData): KpiWidgetModel;
|
|
4
6
|
//# sourceMappingURL=normalize.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../src/components/kpi-widget/lib/normalize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;AAiB5E,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../src/components/kpi-widget/lib/normalize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;AAiB5E,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE5D;AAgFD,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc,CAyBrE"}
|
|
@@ -1,34 +1,95 @@
|
|
|
1
|
-
import { extractCardsFromKpi } from "./extract.js";
|
|
2
|
-
const EMPTY = { cards: [] };
|
|
1
|
+
import { isAdvancedKpiItem, extractCardsFromKpi } from "./extract.js";
|
|
2
|
+
const EMPTY = { layout: "empty", cards: [], supporting: [] };
|
|
3
3
|
function isRawKpiItem(input) {
|
|
4
|
-
return input != null && typeof input === "object" && !Array.isArray(input) && ("data" in input || "column" in input);
|
|
4
|
+
return input != null && typeof input === "object" && !Array.isArray(input) && ("data" in input || "column" in input || "type" in input);
|
|
5
5
|
}
|
|
6
|
-
function
|
|
7
|
-
return
|
|
6
|
+
function isNormalizedModel(input) {
|
|
7
|
+
return Array.isArray(input.cards) && "layout" in input;
|
|
8
|
+
}
|
|
9
|
+
function extractGroupId(value) {
|
|
10
|
+
var _a;
|
|
11
|
+
return ((_a = value == null ? void 0 : value.split("-group-kpi-ids-")) == null ? void 0 : _a[0]) ?? "";
|
|
12
|
+
}
|
|
13
|
+
function sortItems(items) {
|
|
14
|
+
return [...items].sort((a, b) => {
|
|
15
|
+
if (isAdvancedKpiItem(a) && !isAdvancedKpiItem(b)) return -1;
|
|
16
|
+
if (!isAdvancedKpiItem(a) && isAdvancedKpiItem(b)) return 1;
|
|
17
|
+
return 0;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function footerFrom(items) {
|
|
21
|
+
const first = items[0];
|
|
22
|
+
return {
|
|
23
|
+
target: first == null ? void 0 : first.target,
|
|
24
|
+
showTimestamp: first == null ? void 0 : first.showTimestamp,
|
|
25
|
+
updatedAt: first == null ? void 0 : first.updatedAt
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function sectionTitle(items, advanced, topName) {
|
|
29
|
+
var _a, _b;
|
|
30
|
+
if (advanced) return void 0;
|
|
31
|
+
if (items.length === 1) return (_a = items[0]) == null ? void 0 : _a.name;
|
|
32
|
+
const grouped = extractGroupId((_b = items[0]) == null ? void 0 : _b.groupName);
|
|
33
|
+
if (grouped) return grouped;
|
|
34
|
+
return (topName == null ? void 0 : topName.trim()) || void 0;
|
|
35
|
+
}
|
|
36
|
+
function buildFromItems(items, topName) {
|
|
37
|
+
if (!items.length) return EMPTY;
|
|
38
|
+
const sorted = sortItems(items);
|
|
39
|
+
const advancedIndex = sorted.findIndex(isAdvancedKpiItem);
|
|
40
|
+
const advanced = advancedIndex >= 0;
|
|
41
|
+
const footer = footerFrom(sorted);
|
|
42
|
+
if (advanced) {
|
|
43
|
+
const mainItem = sorted[advancedIndex];
|
|
44
|
+
const mainCards = extractCardsFromKpi(mainItem);
|
|
45
|
+
const main = mainCards[0];
|
|
46
|
+
const supporting = sorted.filter((_, i) => i !== advancedIndex).flatMap((item) => extractCardsFromKpi(item));
|
|
47
|
+
const viz = mainItem.visualisation && typeof mainItem.visualisation === "object" ? mainItem.visualisation : null;
|
|
48
|
+
return {
|
|
49
|
+
layout: "advanced",
|
|
50
|
+
title: sectionTitle(sorted, true, topName),
|
|
51
|
+
cards: main ? [main, ...supporting] : supporting,
|
|
52
|
+
main,
|
|
53
|
+
supporting,
|
|
54
|
+
visualisation: viz,
|
|
55
|
+
...footer
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const cards = sorted.flatMap((item) => extractCardsFromKpi(item));
|
|
59
|
+
const hideNames = sorted.length === 1 && cards.length >= 1;
|
|
60
|
+
const titledCards = hideNames ? cards.map((card) => ({ ...card, hideName: true })) : cards;
|
|
61
|
+
const layout = titledCards.length === 0 ? "empty" : titledCards.length === 1 ? "single" : "grid";
|
|
62
|
+
return {
|
|
63
|
+
layout,
|
|
64
|
+
title: sectionTitle(sorted, false, topName),
|
|
65
|
+
cards: titledCards,
|
|
66
|
+
supporting: [],
|
|
67
|
+
...footer
|
|
68
|
+
};
|
|
8
69
|
}
|
|
9
70
|
function normalizeKpiData(input) {
|
|
10
71
|
if (!input) return EMPTY;
|
|
11
72
|
if (Array.isArray(input)) {
|
|
12
73
|
if (!input.length) return EMPTY;
|
|
13
|
-
return
|
|
74
|
+
return buildFromItems(input);
|
|
14
75
|
}
|
|
15
76
|
if (typeof input === "object") {
|
|
16
|
-
if (
|
|
17
|
-
|
|
18
|
-
}
|
|
77
|
+
if (isNormalizedModel(input)) return input;
|
|
78
|
+
const topName = typeof input.name === "string" ? input.name : void 0;
|
|
19
79
|
if (Array.isArray(input.items)) {
|
|
20
|
-
return
|
|
80
|
+
return buildFromItems(input.items, topName);
|
|
21
81
|
}
|
|
22
82
|
if (Array.isArray(input.kpis)) {
|
|
23
|
-
return
|
|
83
|
+
return buildFromItems(input.kpis, topName);
|
|
24
84
|
}
|
|
25
85
|
if (isRawKpiItem(input)) {
|
|
26
|
-
return
|
|
86
|
+
return buildFromItems([input], topName);
|
|
27
87
|
}
|
|
28
88
|
}
|
|
29
89
|
return EMPTY;
|
|
30
90
|
}
|
|
31
91
|
export {
|
|
92
|
+
extractGroupId,
|
|
32
93
|
normalizeKpiData
|
|
33
94
|
};
|
|
34
95
|
//# sourceMappingURL=normalize.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.js","sources":["../../../../src/components/kpi-widget/lib/normalize.ts"],"sourcesContent":["import { extractCardsFromKpi } from './extract.js';\nimport type { KpiWidgetData, KpiWidgetModel, RawKpiItem } from './types.js';\n\nconst EMPTY: KpiWidgetModel = { cards: [] };\n\nfunction isRawKpiItem(input: unknown): input is RawKpiItem {\n return (\n input != null &&\n typeof input === 'object' &&\n !Array.isArray(input) &&\n ('data' in (input as object) || 'column' in (input as object))\n );\n}\n\nfunction
|
|
1
|
+
{"version":3,"file":"normalize.js","sources":["../../../../src/components/kpi-widget/lib/normalize.ts"],"sourcesContent":["import { extractCardsFromKpi, isAdvancedKpiItem } from './extract.js';\nimport type { KpiWidgetData, KpiWidgetModel, RawKpiItem } from './types.js';\n\nconst EMPTY: KpiWidgetModel = { layout: 'empty', cards: [], supporting: [] };\n\nfunction isRawKpiItem(input: unknown): input is RawKpiItem {\n return (\n input != null &&\n typeof input === 'object' &&\n !Array.isArray(input) &&\n ('data' in (input as object) || 'column' in (input as object) || 'type' in (input as object))\n );\n}\n\nfunction isNormalizedModel(input: object): input is KpiWidgetModel {\n return Array.isArray((input as KpiWidgetModel).cards) && 'layout' in input;\n}\n\n/** Client `extractGroupId` — groupName is `{label}-group-kpi-ids-{id}`. */\nexport function extractGroupId(value?: string | null): string {\n return value?.split('-group-kpi-ids-')?.[0] ?? '';\n}\n\nfunction sortItems(items: RawKpiItem[]): RawKpiItem[] {\n return [...items].sort((a, b) => {\n if (isAdvancedKpiItem(a) && !isAdvancedKpiItem(b)) return -1;\n if (!isAdvancedKpiItem(a) && isAdvancedKpiItem(b)) return 1;\n return 0;\n });\n}\n\nfunction footerFrom(items: RawKpiItem[]): Pick<\n KpiWidgetModel,\n 'target' | 'showTimestamp' | 'updatedAt'\n> {\n const first = items[0];\n return {\n target: first?.target,\n showTimestamp: first?.showTimestamp,\n updatedAt: first?.updatedAt,\n };\n}\n\nfunction sectionTitle(\n items: RawKpiItem[],\n advanced: boolean,\n topName?: string,\n): string | undefined {\n if (advanced) return undefined;\n if (items.length === 1) return items[0]?.name;\n const grouped = extractGroupId(items[0]?.groupName);\n if (grouped) return grouped;\n return topName?.trim() || undefined;\n}\n\nfunction buildFromItems(items: RawKpiItem[], topName?: string): KpiWidgetModel {\n if (!items.length) return EMPTY;\n const sorted = sortItems(items);\n const advancedIndex = sorted.findIndex(isAdvancedKpiItem);\n const advanced = advancedIndex >= 0;\n const footer = footerFrom(sorted);\n\n if (advanced) {\n const mainItem = sorted[advancedIndex]!;\n const mainCards = extractCardsFromKpi(mainItem);\n const main = mainCards[0];\n const supporting = sorted\n .filter((_, i) => i !== advancedIndex)\n .flatMap((item) => extractCardsFromKpi(item));\n const viz =\n mainItem.visualisation && typeof mainItem.visualisation === 'object'\n ? (mainItem.visualisation as Record<string, unknown>)\n : null;\n return {\n layout: 'advanced',\n title: sectionTitle(sorted, true, topName),\n cards: main ? [main, ...supporting] : supporting,\n main,\n supporting,\n visualisation: viz,\n ...footer,\n };\n }\n\n const cards = sorted.flatMap((item) => extractCardsFromKpi(item));\n const hideNames = sorted.length === 1 && cards.length >= 1;\n const titledCards = hideNames\n ? cards.map((card) => ({ ...card, hideName: true }))\n : cards;\n const layout: KpiWidgetModel['layout'] =\n titledCards.length === 0 ? 'empty' : titledCards.length === 1 ? 'single' : 'grid';\n\n return {\n layout,\n title: sectionTitle(sorted, false, topName),\n cards: titledCards,\n supporting: [],\n ...footer,\n };\n}\n\n/** Normalize chat / FuseDash KPI payloads into display cards. */\nexport function normalizeKpiData(input: KpiWidgetData): KpiWidgetModel {\n if (!input) return EMPTY;\n\n if (Array.isArray(input)) {\n if (!input.length) return EMPTY;\n return buildFromItems(input);\n }\n\n if (typeof input === 'object') {\n if (isNormalizedModel(input)) return input;\n const topName = typeof (input as { name?: unknown }).name === 'string'\n ? (input as { name: string }).name\n : undefined;\n if (Array.isArray((input as { items?: RawKpiItem[] }).items)) {\n return buildFromItems((input as { items: RawKpiItem[] }).items, topName);\n }\n if (Array.isArray((input as { kpis?: RawKpiItem[] }).kpis)) {\n return buildFromItems((input as { kpis: RawKpiItem[] }).kpis, topName);\n }\n if (isRawKpiItem(input)) {\n return buildFromItems([input], topName);\n }\n }\n\n return EMPTY;\n}\n"],"names":[],"mappings":";AAGA,MAAM,QAAwB,EAAE,QAAQ,SAAS,OAAO,CAAA,GAAI,YAAY,GAAC;AAEzE,SAAS,aAAa,OAAqC;AACzD,SACE,SAAS,QACT,OAAO,UAAU,YACjB,CAAC,MAAM,QAAQ,KAAK,MACnB,UAAW,SAAoB,YAAa,SAAoB,UAAW;AAEhF;AAEA,SAAS,kBAAkB,OAAwC;AACjE,SAAO,MAAM,QAAS,MAAyB,KAAK,KAAK,YAAY;AACvE;AAGO,SAAS,eAAe,OAA+B;;AAC5D,WAAO,oCAAO,MAAM,uBAAb,mBAAkC,OAAM;AACjD;AAEA,SAAS,UAAU,OAAmC;AACpD,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM;AAC/B,QAAI,kBAAkB,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAG,QAAO;AAC1D,QAAI,CAAC,kBAAkB,CAAC,KAAK,kBAAkB,CAAC,EAAG,QAAO;AAC1D,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,WAAW,OAGlB;AACA,QAAM,QAAQ,MAAM,CAAC;AACrB,SAAO;AAAA,IACL,QAAQ,+BAAO;AAAA,IACf,eAAe,+BAAO;AAAA,IACtB,WAAW,+BAAO;AAAA,EAAA;AAEtB;AAEA,SAAS,aACP,OACA,UACA,SACoB;;AACpB,MAAI,SAAU,QAAO;AACrB,MAAI,MAAM,WAAW,EAAG,SAAO,WAAM,CAAC,MAAP,mBAAU;AACzC,QAAM,UAAU,gBAAe,WAAM,CAAC,MAAP,mBAAU,SAAS;AAClD,MAAI,QAAS,QAAO;AACpB,UAAO,mCAAS,WAAU;AAC5B;AAEA,SAAS,eAAe,OAAqB,SAAkC;AAC7E,MAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,QAAM,SAAS,UAAU,KAAK;AAC9B,QAAM,gBAAgB,OAAO,UAAU,iBAAiB;AACxD,QAAM,WAAW,iBAAiB;AAClC,QAAM,SAAS,WAAW,MAAM;AAEhC,MAAI,UAAU;AACZ,UAAM,WAAW,OAAO,aAAa;AACrC,UAAM,YAAY,oBAAoB,QAAQ;AAC9C,UAAM,OAAO,UAAU,CAAC;AACxB,UAAM,aAAa,OAChB,OAAO,CAAC,GAAG,MAAM,MAAM,aAAa,EACpC,QAAQ,CAAC,SAAS,oBAAoB,IAAI,CAAC;AAC9C,UAAM,MACJ,SAAS,iBAAiB,OAAO,SAAS,kBAAkB,WACvD,SAAS,gBACV;AACN,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO,aAAa,QAAQ,MAAM,OAAO;AAAA,MACzC,OAAO,OAAO,CAAC,MAAM,GAAG,UAAU,IAAI;AAAA,MACtC;AAAA,MACA;AAAA,MACA,eAAe;AAAA,MACf,GAAG;AAAA,IAAA;AAAA,EAEP;AAEA,QAAM,QAAQ,OAAO,QAAQ,CAAC,SAAS,oBAAoB,IAAI,CAAC;AAChE,QAAM,YAAY,OAAO,WAAW,KAAK,MAAM,UAAU;AACzD,QAAM,cAAc,YAChB,MAAM,IAAI,CAAC,UAAU,EAAE,GAAG,MAAM,UAAU,KAAA,EAAO,IACjD;AACJ,QAAM,SACJ,YAAY,WAAW,IAAI,UAAU,YAAY,WAAW,IAAI,WAAW;AAE7E,SAAO;AAAA,IACL;AAAA,IACA,OAAO,aAAa,QAAQ,OAAO,OAAO;AAAA,IAC1C,OAAO;AAAA,IACP,YAAY,CAAA;AAAA,IACZ,GAAG;AAAA,EAAA;AAEP;AAGO,SAAS,iBAAiB,OAAsC;AACrE,MAAI,CAAC,MAAO,QAAO;AAEnB,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,QAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,WAAO,eAAe,KAAK;AAAA,EAC7B;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,kBAAkB,KAAK,EAAG,QAAO;AACrC,UAAM,UAAU,OAAQ,MAA6B,SAAS,WACzD,MAA2B,OAC5B;AACJ,QAAI,MAAM,QAAS,MAAmC,KAAK,GAAG;AAC5D,aAAO,eAAgB,MAAkC,OAAO,OAAO;AAAA,IACzE;AACA,QAAI,MAAM,QAAS,MAAkC,IAAI,GAAG;AAC1D,aAAO,eAAgB,MAAiC,MAAM,OAAO;AAAA,IACvE;AACA,QAAI,aAAa,KAAK,GAAG;AACvB,aAAO,eAAe,CAAC,KAAK,GAAG,OAAO;AAAA,IACxC;AAAA,EACF;AAEA,SAAO;AACT;"}
|
|
@@ -2,25 +2,64 @@ export interface KpiValueLabel {
|
|
|
2
2
|
position: 'left' | 'right';
|
|
3
3
|
text: string;
|
|
4
4
|
}
|
|
5
|
+
export type KpiStatusVariant = 'Good' | 'Low' | 'Normal' | 'OnTarget' | 'OffTarget' | 'Mission';
|
|
6
|
+
export interface KpiStatusBadge {
|
|
7
|
+
text: string;
|
|
8
|
+
variant: KpiStatusVariant;
|
|
9
|
+
}
|
|
10
|
+
export type KpiCardRole = 'single' | 'grid' | 'main' | 'supporting';
|
|
5
11
|
export interface KpiCardModel {
|
|
6
12
|
id: string;
|
|
7
13
|
name: string;
|
|
8
14
|
value: string;
|
|
15
|
+
suffix?: string;
|
|
9
16
|
indicator?: string;
|
|
10
17
|
subtitle?: string;
|
|
11
18
|
label?: KpiValueLabel;
|
|
19
|
+
status?: KpiStatusBadge;
|
|
20
|
+
showPercentage?: boolean;
|
|
21
|
+
hideName?: boolean;
|
|
12
22
|
}
|
|
23
|
+
export type KpiWidgetLayout = 'empty' | 'single' | 'grid' | 'advanced';
|
|
13
24
|
export interface KpiWidgetModel {
|
|
25
|
+
layout: KpiWidgetLayout;
|
|
26
|
+
title?: string;
|
|
14
27
|
cards: KpiCardModel[];
|
|
28
|
+
main?: KpiCardModel;
|
|
29
|
+
supporting: KpiCardModel[];
|
|
30
|
+
visualisation?: Record<string, unknown> | null;
|
|
31
|
+
target?: string;
|
|
32
|
+
showTimestamp?: boolean;
|
|
33
|
+
updatedAt?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface RawKpiVisualisation {
|
|
36
|
+
chartType?: string;
|
|
37
|
+
chart_type?: string;
|
|
38
|
+
name?: string;
|
|
39
|
+
data?: unknown[];
|
|
40
|
+
[key: string]: unknown;
|
|
15
41
|
}
|
|
16
42
|
export interface RawKpiItem {
|
|
17
43
|
id?: string;
|
|
18
44
|
name?: string;
|
|
19
45
|
type?: string;
|
|
46
|
+
variant?: string;
|
|
20
47
|
column?: string;
|
|
21
48
|
aggregations?: string;
|
|
22
49
|
groupBy?: string;
|
|
50
|
+
groupName?: string;
|
|
23
51
|
data?: unknown[];
|
|
52
|
+
status?: string;
|
|
53
|
+
target?: string;
|
|
54
|
+
showTimestamp?: boolean;
|
|
55
|
+
showPercentage?: boolean;
|
|
56
|
+
showVisualisation?: boolean;
|
|
57
|
+
supportingKpis?: boolean;
|
|
58
|
+
visualisation?: RawKpiVisualisation | null;
|
|
59
|
+
updatedAt?: string;
|
|
60
|
+
kpiKind?: 'mission' | 'goal' | string;
|
|
61
|
+
targetStatus?: 'on_target' | 'off_target' | string;
|
|
62
|
+
score?: number;
|
|
24
63
|
axisDetails?: Record<string, {
|
|
25
64
|
label?: string;
|
|
26
65
|
measure_unit_type?: string;
|
|
@@ -32,5 +71,7 @@ export type KpiWidgetData = RawKpiItem | RawKpiItem[] | {
|
|
|
32
71
|
items?: RawKpiItem[];
|
|
33
72
|
kpis?: RawKpiItem[];
|
|
34
73
|
chartType?: string;
|
|
74
|
+
name?: string;
|
|
75
|
+
count?: number;
|
|
35
76
|
} | KpiWidgetModel | null | undefined;
|
|
36
77
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/kpi-widget/lib/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/kpi-widget/lib/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ declare const _default: {
|
|
|
2
2
|
"id": "kpi-widget",
|
|
3
3
|
"tag": "ui9000-kpi-widget",
|
|
4
4
|
"title": "KPI Widget",
|
|
5
|
-
"description": "Chat-optimized KPI cards (single_value
|
|
5
|
+
"description": "Chat-optimized KPI cards — client types (single_value, trend, overall, comparison, high/low*) and advanced (nested chart + supporting KPIs). HTML/Lit, no Redux.",
|
|
6
6
|
"chartTypeKeys": ["KPI", "KPIs"],
|
|
7
7
|
"source": "client/libs/shared/components/src/Widgets/CustomWidget/components/KPIWidget/",
|
|
8
8
|
"stack": "lit",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const id = "kpi-widget";
|
|
2
2
|
const tag = "ui9000-kpi-widget";
|
|
3
3
|
const title = "KPI Widget";
|
|
4
|
-
const description = "Chat-optimized KPI cards (single_value
|
|
4
|
+
const description = "Chat-optimized KPI cards — client types (single_value, trend, overall, comparison, high/low*) and advanced (nested chart + supporting KPIs). HTML/Lit, no Redux.";
|
|
5
5
|
const chartTypeKeys = ["KPI", "KPIs"];
|
|
6
6
|
const source = "client/libs/shared/components/src/Widgets/CustomWidget/components/KPIWidget/";
|
|
7
7
|
const stack = "lit";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui9000-map-chart.d.ts","sourceRoot":"","sources":["../../../../src/components/map-chart/element/ui9000-map-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAIzD,OAAO,EAAoB,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"ui9000-map-chart.d.ts","sourceRoot":"","sources":["../../../../src/components/map-chart/element/ui9000-map-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAIzD,OAAO,EAAoB,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAsF7F,qBACa,cAAe,SAAQ,kBAAkB;IACpD,OAAgB,MAAM,4BAAsC;IAG5D,UAAU,UAAQ;IAGlB,WAAW,UAAQ;IAGnB,WAAW,SAAM;IAGjB,cAAc,SAAM;IAGpB,cAAc,SAAc;IAG5B,OAAO,CAAC,MAAM,CAAS;IAGvB,OAAO,CAAC,YAAY,CAAa;IAGjC,OAAO,CAAC,QAAQ,CAAuE;IAGvF,OAAO,CAAC,OAAO,CAAuB;IAGtC,OAAO,CAAC,QAAQ,CAAmC;IAGnD,OAAO,CAAC,aAAa,CAAgB;IAGrC,OAAO,CAAC,WAAW,CAAQ;IAG3B,OAAO,CAAC,UAAU,CAA+B;IAEjD,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,IAAI,CAAmC;IAC/C,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,WAAW,CAAC,CAIlB;IACF,OAAO,CAAC,eAAe,CAAC,CAAiB;IACzC,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,QAAQ,CAAK;IAEZ,iBAAiB,IAAI,IAAI;IAYzB,oBAAoB,IAAI,IAAI;IAU5B,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAM/C,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,KAAK;IAWb,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,UAAU;IAWlB,OAAO,CAAC,IAAI;YAKE,IAAI;IA0FlB,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,cAAc;IA2BtB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,UAAU;IAgBlB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,YAAY;IA4BpB,OAAO,CAAC,iBAAiB;IA4HhB,MAAM;CA0BhB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,kBAAkB,EAAE,cAAc,CAAC;KACpC;CACF;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC"}
|
|
@@ -115,7 +115,7 @@ let Ui9000MapChart = class extends Ui9000ChartElement {
|
|
|
115
115
|
super.disconnectedCallback();
|
|
116
116
|
}
|
|
117
117
|
updated(changed) {
|
|
118
|
-
if (changed.has("dataJson")) this._model = null;
|
|
118
|
+
if (changed.has("dataJson") || changed.has("geojsonBaseUrl")) this._model = null;
|
|
119
119
|
if (changed.has("showTooltip") && !this.showTooltip) this._tooltip = null;
|
|
120
120
|
if (this.shouldRedraw(changed)) this.scheduleDraw();
|
|
121
121
|
}
|
|
@@ -145,6 +145,11 @@ let Ui9000MapChart = class extends Ui9000ChartElement {
|
|
|
145
145
|
const env = __vite_import_meta_env__;
|
|
146
146
|
return ((env == null ? void 0 : env.STORYBOOK_MAPBOX_TOKEN) || (env == null ? void 0 : env.VITE_MAPBOX_TOKEN) || "").trim();
|
|
147
147
|
}
|
|
148
|
+
geojsonUrl() {
|
|
149
|
+
if (this.geojsonBaseUrl.trim()) return this.geojsonBaseUrl.trim();
|
|
150
|
+
const runtime = typeof window !== "undefined" ? window.__RUNTIME_CONFIG__ : void 0;
|
|
151
|
+
return ((runtime == null ? void 0 : runtime.MAP_GEOJSON_BASE_URL) || "").trim();
|
|
152
|
+
}
|
|
148
153
|
pmtilesUrl() {
|
|
149
154
|
if (this.pmtilesBaseUrl.trim()) return this.pmtilesBaseUrl.trim();
|
|
150
155
|
const runtime = typeof window !== "undefined" ? window.__RUNTIME_CONFIG__ : void 0;
|
|
@@ -173,13 +178,16 @@ let Ui9000MapChart = class extends Ui9000ChartElement {
|
|
|
173
178
|
return;
|
|
174
179
|
}
|
|
175
180
|
const needsGeo = model.layers.some((layer) => !layer.features.length);
|
|
176
|
-
|
|
181
|
+
const geoBase = this.geojsonUrl();
|
|
182
|
+
let geoFetchFailed = false;
|
|
183
|
+
if (needsGeo && geoBase) {
|
|
177
184
|
const types = [...new Set(model.layers.map((l) => l.mapType))];
|
|
178
185
|
const loaded = await Promise.all(
|
|
179
|
-
types.map(async (mapType) => [mapType, await fetchMapGeoJson(mapType,
|
|
186
|
+
types.map(async (mapType) => [mapType, await fetchMapGeoJson(mapType, geoBase)])
|
|
180
187
|
);
|
|
181
188
|
if (gen !== this._drawGen) return;
|
|
182
189
|
const byType = Object.fromEntries(loaded.filter((entry) => entry[1]));
|
|
190
|
+
geoFetchFailed = loaded.some((entry) => !entry[1]);
|
|
183
191
|
model = {
|
|
184
192
|
...model,
|
|
185
193
|
layers: model.layers.map(
|
|
@@ -199,7 +207,7 @@ let Ui9000MapChart = class extends Ui9000ChartElement {
|
|
|
199
207
|
}
|
|
200
208
|
const hasMarks = model.layers.some((layer) => layer.features.length > 0);
|
|
201
209
|
this._empty = !hasMarks;
|
|
202
|
-
this._emptyReason = hasMarks ? "No data" : model.layers.some((l) => l.matchTotal > 0 && l.matchHit === 0) ? "No locations matched the map boundaries" : "Map boundaries required";
|
|
210
|
+
this._emptyReason = hasMarks ? "No data" : model.layers.some((l) => l.matchTotal > 0 && l.matchHit === 0) ? "No locations matched the map boundaries" : geoFetchFailed ? "Could not load map boundaries" : "Map boundaries required";
|
|
203
211
|
this._layers = model.layers;
|
|
204
212
|
if (!hasMarks) {
|
|
205
213
|
stopMapChart(root);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui9000-map-chart.js","sources":["../../../../src/components/map-chart/element/ui9000-map-chart.ts"],"sourcesContent":["import { html, nothing, type PropertyValues } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport { CSS_VARS, readCssVar } from '../../../context/widget-context.js';\nimport { chartShellStyles, Ui9000ChartElement } from '../../../element/ui9000-chart-base.js';\nimport { parseJsonAttr } from '../../../utils/chart-helpers.js';\nimport { chartPropsChanged } from '../../../utils/lit-draw.js';\nimport { fetchMapGeoJson } from '../lib/geojson.js';\nimport { joinLayerFeatures } from '../lib/join.js';\nimport {\n DEFAULT_BUBBLES_RADIUS,\n defaultLayerSlider,\n formatAverage,\n formatFieldLabel,\n formatLegendBucket,\n legendLayerOrder,\n legendSpikeHeight,\n MUTED_LEGEND_FILL,\n rangeTrackOffset,\n sanitizeKey,\n slideThumb,\n sliderIndexFromPointer,\n thumbTrackPercent,\n type LayerSlider,\n formatMapValue,\n normalizeMapData,\n type MapChartInput,\n type MapHoverEntry,\n type MapLayerModel,\n type MapModel,\n} from '../lib/index.js';\nimport { renderMapChart, resizeMapChart, stopMapChart, type MapChartController } from '../render/draw.js';\nimport { mapChartStyles } from './styles.js';\n\nconst SPIKE_COLOR = '#939BA7';\n\nfunction renderLegendSpike(index: number, id: string) {\n const h = legendSpikeHeight(index);\n return html`\n <span class=\"legend-spike\">\n <svg width=\"25\" height=${h} viewBox=${`0 0 25 ${h}`} fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <mask\n id=${`mask_${id}`}\n style=\"mask-type:alpha\"\n maskUnits=\"userSpaceOnUse\"\n x=\"6\"\n y=\"0\"\n width=\"13\"\n height=${h}\n >\n <path\n d=${`M18.1992 ${h - 0.75}L12.1992 0.25L6.19922 ${h - 0.75}Z`}\n fill=${`url(#linear_gradient_${id})`}\n />\n </mask>\n <g mask=${`url(#mask_${id})`}>\n <path d=${`M18.1992 ${h - 0.75}L12.1992 0.25L6.19922 ${h - 0.75}Z`} fill=${SPIKE_COLOR} />\n </g>\n <path\n d=${`M22.1992 ${h - 0.75}H19.0291C18.5479 ${h - 0.75} 18.135 ${h - 0.1} 18.0463 ${h - 0.5}L12.1992 0.25L6.35216 ${h - 0.5}C6.26348 ${h - 0.1} 5.85051 ${h - 0.75} 5.36929 ${h - 0.75}H2.19922`}\n stroke=${SPIKE_COLOR}\n fill=${SPIKE_COLOR}\n fill-opacity=\"0\"\n stroke-width=\"1\"\n />\n <defs>\n <linearGradient\n id=${`linear_gradient_${id}`}\n x1=\"12.1992\"\n y1=\"0.25\"\n x2=\"12.1992\"\n y2=${h}\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stop-color=${SPIKE_COLOR} stop-opacity=\"0.7\" />\n <stop offset=\"1\" stop-color=${SPIKE_COLOR} stop-opacity=\"0.2\" />\n </linearGradient>\n </defs>\n </svg>\n </span>\n `;\n}\n\ntype RuntimeConfig = {\n MAPBOX_TOKEN?: string;\n MAPBOX_DARK_TOKEN?: string;\n MAP_PMTILES_BASE_URL?: string;\n};\n\n@customElement('ui9000-map-chart')\nexport class Ui9000MapChart extends Ui9000ChartElement {\n static override styles = [mapChartStyles, chartShellStyles];\n\n @property({ type: Boolean, attribute: 'show-legend' })\n showLegend = true;\n\n @property({ type: Boolean, attribute: 'show-tooltip' })\n showTooltip = true;\n\n @property({ type: String, attribute: 'mapbox-token' })\n mapboxToken = '';\n\n @property({ type: String, attribute: 'geojson-base-url' })\n geojsonBaseUrl = '';\n\n @property({ type: String, attribute: 'pmtiles-base-url' })\n pmtilesBaseUrl = '/pmtiles';\n\n @state()\n private _empty = false;\n\n @state()\n private _emptyReason = 'No data';\n\n @state()\n private _tooltip: { x: number; y: number; title: string; value: string } | null = null;\n\n @state()\n private _layers: MapLayerModel[] = [];\n\n @state()\n private _sliders: Record<string, LayerSlider> = {};\n\n @state()\n private _activeLayers: string[] = [];\n\n @state()\n private _legendOpen = true;\n\n @state()\n private _layerOpen: Record<string, boolean> = {};\n\n private _model: MapModel | null = null;\n private _ctl: MapChartController | null = null;\n private _legendKey = '';\n private _legendDrag?: {\n thumb: HTMLElement;\n move: (e: PointerEvent) => void;\n up: (e: PointerEvent) => void;\n };\n private _resizeObserver?: ResizeObserver;\n private _raf = 0;\n private _drawGen = 0;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._resizeObserver = new ResizeObserver(() => {\n cancelAnimationFrame(this._raf);\n this._raf = requestAnimationFrame(() => {\n const root = this.chartRoot();\n if (root && !resizeMapChart(root)) this.scheduleDraw();\n });\n });\n this._resizeObserver.observe(this);\n }\n\n override disconnectedCallback(): void {\n this._resizeObserver?.disconnect();\n cancelAnimationFrame(this._raf);\n this.stopLegendDrag();\n const root = this.chartRoot();\n if (root) stopMapChart(root);\n this._ctl = null;\n super.disconnectedCallback();\n }\n\n override updated(changed: PropertyValues): void {\n if (changed.has('dataJson')) this._model = null;\n if (changed.has('showTooltip') && !this.showTooltip) this._tooltip = null;\n if (this.shouldRedraw(changed)) this.scheduleDraw();\n }\n\n private shouldRedraw(changed: PropertyValues): boolean {\n if (!chartPropsChanged(changed)) return false;\n for (const key of changed.keys()) {\n if (typeof key !== 'string' || key.startsWith('_')) continue;\n if (key === 'showLegend' || key === 'showTooltip') continue;\n return true;\n }\n return false;\n }\n\n private scheduleDraw(): void {\n cancelAnimationFrame(this._raf);\n this._raf = requestAnimationFrame(() => {\n void this.draw();\n });\n }\n\n private chartRoot(): HTMLElement | null {\n return (this.shadowRoot?.querySelector('.chart-root') as HTMLElement | null) ?? null;\n }\n\n private token(): string {\n if (this.mapboxToken.trim()) return this.mapboxToken.trim();\n const runtime =\n typeof window !== 'undefined'\n ? (window as Window & { __RUNTIME_CONFIG__?: RuntimeConfig }).__RUNTIME_CONFIG__\n : undefined;\n if (runtime?.MAPBOX_TOKEN) return runtime.MAPBOX_TOKEN;\n const env = (import.meta as { env?: Record<string, string | undefined> }).env;\n return (env?.STORYBOOK_MAPBOX_TOKEN || env?.VITE_MAPBOX_TOKEN || '').trim();\n }\n\n private pmtilesUrl(): string {\n if (this.pmtilesBaseUrl.trim()) return this.pmtilesBaseUrl.trim();\n const runtime =\n typeof window !== 'undefined'\n ? (window as Window & { __RUNTIME_CONFIG__?: RuntimeConfig }).__RUNTIME_CONFIG__\n : undefined;\n if (runtime?.MAP_PMTILES_BASE_URL) return runtime.MAP_PMTILES_BASE_URL;\n const env = (import.meta as { env?: Record<string, string | undefined> }).env;\n return (env?.STORYBOOK_MAP_PMTILES_BASE_URL || env?.VITE_MAP_PMTILES_BASE_URL || '/pmtiles').trim();\n }\n\n private mode(): 'light' | 'dark' {\n const value = readCssVar(this, CSS_VARS.mode, 'light');\n return value === 'dark' ? 'dark' : 'light';\n }\n\n private async draw(): Promise<void> {\n const root = this.chartRoot();\n if (!root) return;\n const gen = ++this._drawGen;\n\n const parsed = parseJsonAttr<MapChartInput>(this.dataJson, null);\n let model = this._model ?? normalizeMapData(parsed);\n this._model = model;\n\n if (!model.layers.length) {\n this._empty = true;\n this._emptyReason = 'No data';\n this._layers = [];\n stopMapChart(root);\n this._ctl = null;\n return;\n }\n\n const needsGeo = model.layers.some((layer) => !layer.features.length);\n if (needsGeo && this.geojsonBaseUrl) {\n const types = [...new Set(model.layers.map((l) => l.mapType))];\n const loaded = await Promise.all(\n types.map(async (mapType) => [mapType, await fetchMapGeoJson(mapType, this.geojsonBaseUrl)] as const),\n );\n if (gen !== this._drawGen) return;\n const byType = Object.fromEntries(loaded.filter((entry) => entry[1]));\n model = {\n ...model,\n layers: model.layers.map((layer) =>\n layer.features.length ? layer : joinLayerFeatures(layer, byType[layer.mapType] ?? undefined),\n ),\n };\n this._model = model;\n }\n\n const token = this.token();\n if (!token) {\n this._empty = true;\n this._emptyReason = 'Mapbox token required';\n this._layers = model.layers;\n stopMapChart(root);\n this._ctl = null;\n return;\n }\n\n const hasMarks = model.layers.some((layer) => layer.features.length > 0);\n this._empty = !hasMarks;\n this._emptyReason = hasMarks\n ? 'No data'\n : model.layers.some((l) => l.matchTotal > 0 && l.matchHit === 0)\n ? 'No locations matched the map boundaries'\n : 'Map boundaries required';\n this._layers = model.layers;\n if (!hasMarks) {\n stopMapChart(root);\n this._ctl = null;\n return;\n }\n this.syncLegendState(model.layers);\n\n const ctl = await renderMapChart(root, {\n model,\n token,\n mode: this.mode(),\n showTooltip: this.showTooltip,\n pmtilesBaseUrl: this.pmtilesUrl(),\n activeLayerIds: this._activeLayers,\n sliders: this._sliders,\n year: model.layers.find((layer) => layer.selectedYear)?.selectedYear,\n onHover: this.showTooltip\n ? (entry) => this.setTooltip(entry)\n : undefined,\n });\n if (gen !== this._drawGen) {\n ctl?.destroy();\n return;\n }\n this._ctl = ctl;\n if (!this._ctl) {\n this._empty = true;\n this._emptyReason = 'Mapbox GL failed to load';\n stopMapChart(root);\n }\n }\n\n private syncLegendState(layers: MapLayerModel[]): void {\n const ids = layers.map((layer) => layer.layerId);\n const key = ids.join('\\0');\n if (key !== this._legendKey) {\n this._legendKey = key;\n this._sliders = Object.fromEntries(\n layers.map((layer) => [layer.layerId, defaultLayerSlider(layer.colorRanges.length)]),\n );\n this._activeLayers = ids;\n this._layerOpen = {};\n return;\n }\n const sliders = { ...this._sliders };\n let slidersChanged = false;\n for (const layer of layers) {\n if (!sliders[layer.layerId]) {\n sliders[layer.layerId] = defaultLayerSlider(layer.colorRanges.length);\n slidersChanged = true;\n }\n }\n if (slidersChanged) this._sliders = sliders;\n }\n\n private pushLegend(): void {\n this._ctl?.applyLegend(this._activeLayers, this._sliders);\n }\n\n private toggleLayer(layerId: string): void {\n const on = this._activeLayers.includes(layerId);\n this._activeLayers = on\n ? this._activeLayers.filter((id) => id !== layerId)\n : [...this._activeLayers, layerId];\n this.pushLegend();\n }\n\n private toggleLayerOpen(layerId: string): void {\n this._layerOpen = { ...this._layerOpen, [layerId]: this._layerOpen[layerId] === false };\n }\n\n private setSlider(layerId: string, edge: 'leftSlider' | 'rightSlider', raw: number): void {\n const layer = this._layers.find((item) => item.layerId === layerId);\n const rangeCount = layer?.colorRanges.length ?? 1;\n const current = this._sliders[layerId] ?? defaultLayerSlider(rangeCount);\n const next = slideThumb(current, edge, raw, rangeCount);\n if (next.leftSlider === current.leftSlider && next.rightSlider === current.rightSlider) return;\n this._sliders = { ...this._sliders, [layerId]: next };\n this.pushLegend();\n }\n\n private startThumbDrag(layerId: string, edge: 'leftSlider' | 'rightSlider', e: PointerEvent): void {\n const thumb = e.currentTarget;\n if (!(thumb instanceof HTMLElement)) return;\n const track = thumb.parentElement;\n if (!track) return;\n e.preventDefault();\n e.stopPropagation();\n thumb.setPointerCapture(e.pointerId);\n this.stopLegendDrag();\n\n const move = (ev: PointerEvent) => {\n const layer = this._layers.find((item) => item.layerId === layerId);\n const max = layer?.colorRanges.length ?? 1;\n const index = sliderIndexFromPointer(ev.clientX, track.getBoundingClientRect(), max);\n this.setSlider(layerId, edge, index);\n };\n const up = (ev: PointerEvent) => {\n if (thumb.hasPointerCapture(ev.pointerId)) thumb.releasePointerCapture(ev.pointerId);\n this.stopLegendDrag();\n };\n thumb.addEventListener('pointermove', move);\n thumb.addEventListener('pointerup', up);\n thumb.addEventListener('pointercancel', up);\n this._legendDrag = { thumb, move, up };\n move(e);\n }\n\n private stopLegendDrag(): void {\n const drag = this._legendDrag;\n if (!drag) return;\n drag.thumb.removeEventListener('pointermove', drag.move);\n drag.thumb.removeEventListener('pointerup', drag.up);\n drag.thumb.removeEventListener('pointercancel', drag.up);\n this._legendDrag = undefined;\n }\n\n private setTooltip(entry: MapHoverEntry | null): void {\n if (!entry) {\n this._tooltip = null;\n return;\n }\n const root = this.chartRoot();\n const x = entry.point?.x ?? (root?.clientWidth ?? 0) / 2;\n const y = entry.point?.y ?? 48;\n this._tooltip = {\n x,\n y,\n title: entry.regionName,\n value: `${entry.valueKey}: ${formatMapValue(entry.value)}`,\n };\n }\n\n private matchNotice(): string | null {\n const total = this._layers.reduce((sum, l) => sum + l.matchTotal, 0);\n const hit = this._layers.reduce((sum, l) => sum + l.matchHit, 0);\n if (total > 0 && hit === 0) {\n return `0 of ${total} ${total === 1 ? 'location' : 'locations'} matched the map boundaries`;\n }\n return null;\n }\n\n private renderLegend() {\n if (!this.showLegend || this._empty) return nothing;\n const layers = legendLayerOrder(this._layers.filter((layer) => layer.features.length > 0));\n if (!layers.length) return nothing;\n\n return html`\n <div class=\"map-legend\" part=\"legend\">\n <div class=\"legend-panel-header\">\n <p class=\"legend-kicker\">Legend</p>\n <button\n type=\"button\"\n class=\"legend-chevron\"\n aria-expanded=${this._legendOpen}\n aria-label=${this._legendOpen ? 'Collapse legend' : 'Expand legend'}\n @click=${() => {\n this._legendOpen = !this._legendOpen;\n }}\n ></button>\n </div>\n ${this._legendOpen\n ? html`<div class=\"legend-layers\">\n ${layers.map((layer) => this.renderLegendLayer(layer))}\n </div>`\n : nothing}\n </div>\n `;\n }\n\n private renderLegendLayer(layer: MapLayerModel) {\n const active = this._activeLayers.includes(layer.layerId);\n const open = this._layerOpen[layer.layerId] !== false;\n const slider = this._sliders[layer.layerId] ?? defaultLayerSlider(layer.colorRanges.length);\n const ranges = layer.colorRanges;\n const isBubble = layer.visualisationType === 'bubbles';\n const isSpike = layer.visualisationType === 'spike';\n const isMarkers = layer.visualisationType === 'markers';\n const showRamp = ranges.length > 0;\n\n return html`\n <div class=\"legend-layer\">\n <div class=\"legend-layer-header\">\n <label class=\"legend-check\">\n <input\n type=\"checkbox\"\n .checked=${active}\n @change=${(e: Event) => {\n e.stopPropagation();\n this.toggleLayer(layer.layerId);\n }}\n />\n <span>${layer.layerName}</span>\n </label>\n <button\n type=\"button\"\n class=\"legend-chevron\"\n aria-expanded=${open}\n aria-label=${open ? `Collapse ${layer.layerName}` : `Expand ${layer.layerName}`}\n @click=${() => this.toggleLayerOpen(layer.layerId)}\n ></button>\n </div>\n ${open\n ? html`\n <div class=\"legend-details\">\n <p class=\"legend-stat\">\n <span class=\"legend-avg\">${formatAverage(layer.average)}</span>\n ${formatFieldLabel(layer.valueKey)}\n </p>\n ${showRamp\n ? html`\n <div class=\"legend-scale\" data-kind=${layer.visualisationType}>\n <div\n class=\"legend-colors\"\n ?data-qualitative=${isBubble || isSpike}\n >\n <div class=\"legend-range\">\n <div\n class=\"legend-range-track\"\n style=\"left:${rangeTrackOffset('left', slider.leftSlider, ranges.length)}\"\n >\n <button\n type=\"button\"\n class=\"legend-thumb\"\n aria-label=\"Lowest ${layer.layerName} range\"\n style=\"left:${thumbTrackPercent(slider.leftSlider, ranges.length)}\"\n @pointerdown=${(e: PointerEvent) =>\n this.startThumbDrag(layer.layerId, 'leftSlider', e)}\n ></button>\n </div>\n <div\n class=\"legend-range-track\"\n style=\"right:${rangeTrackOffset('right', slider.rightSlider, ranges.length)}\"\n >\n <button\n type=\"button\"\n class=\"legend-thumb\"\n aria-label=\"Highest ${layer.layerName} range\"\n style=\"left:${thumbTrackPercent(slider.rightSlider, ranges.length)}\"\n @pointerdown=${(e: PointerEvent) =>\n this.startThumbDrag(layer.layerId, 'rightSlider', e)}\n ></button>\n </div>\n </div>\n <div class=\"legend-buckets\">\n ${ranges.map((range, index) => {\n const inRange =\n slider.leftSlider <= index && index < slider.rightSlider;\n const fill =\n isBubble || isSpike\n ? MUTED_LEGEND_FILL\n : inRange\n ? range.color\n : MUTED_LEGEND_FILL;\n const bubble = isBubble ? (DEFAULT_BUBBLES_RADIUS[index] ?? 12) : 0;\n const inner = bubble - 15 > 0 ? bubble - 15 : 0;\n return html`<span\n class=\"legend-bucket\"\n ?data-bubble=${isBubble}\n ?data-inner=${inner > 0}\n ?data-qualitative=${isBubble || isSpike}\n style=\"background:${fill};--bubble-size:${bubble}px;--inner-size:${inner}px\"\n ></span>`;\n })}\n </div>\n ${isSpike\n ? html`<div class=\"legend-spikes\">\n ${ranges.map((_range, index) =>\n renderLegendSpike(\n index,\n `${sanitizeKey(layer.layerId)}_${index}`,\n ),\n )}\n </div>`\n : nothing}\n </div>\n ${isMarkers\n ? nothing\n : html`<div class=\"legend-values\">\n ${ranges.map(\n (range) =>\n html`<span class=\"legend-value\">${formatLegendBucket(range.start, 2)}</span>`,\n )}\n </div>`}\n </div>\n `\n : nothing}\n </div>\n `\n : nothing}\n </div>\n `;\n }\n\n override render() {\n const title = this.headerTitle();\n const notice = this.matchNotice();\n return html`\n <div class=\"widget-shell\" part=\"shell\">\n ${this.renderShellHeader(title)}\n <div class=\"widget-body\">\n <div class=\"chart-root\" part=\"chart\" ?hidden=${this._empty}></div>\n ${this._empty ? html`<div class=\"empty\" part=\"empty\">${this._emptyReason}</div>` : nothing}\n ${this.renderLegend()}\n ${notice && !this._empty ? html`<div class=\"match-notice\">${notice}</div>` : nothing}\n ${this._tooltip\n ? html`<div\n class=\"tooltip\"\n part=\"tooltip\"\n style=\"left:${this._tooltip.x}px;top:${this._tooltip.y}px\"\n >\n <div>${this._tooltip.title}</div>\n <div>${this._tooltip.value}</div>\n </div>`\n : nothing}\n ${this.renderShellLabelTooltip()}\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ui9000-map-chart': Ui9000MapChart;\n }\n}\n\nexport function registerMapChart(): void {\n if (!customElements.get('ui9000-map-chart')) {\n customElements.define('ui9000-map-chart', Ui9000MapChart);\n }\n}\n\nregisterMapChart();\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ui9000-map-chart.js","sources":["../../../../src/components/map-chart/element/ui9000-map-chart.ts"],"sourcesContent":["import { html, nothing, type PropertyValues } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport { CSS_VARS, readCssVar } from '../../../context/widget-context.js';\nimport { chartShellStyles, Ui9000ChartElement } from '../../../element/ui9000-chart-base.js';\nimport { parseJsonAttr } from '../../../utils/chart-helpers.js';\nimport { chartPropsChanged } from '../../../utils/lit-draw.js';\nimport { fetchMapGeoJson } from '../lib/geojson.js';\nimport { joinLayerFeatures } from '../lib/join.js';\nimport {\n DEFAULT_BUBBLES_RADIUS,\n defaultLayerSlider,\n formatAverage,\n formatFieldLabel,\n formatLegendBucket,\n legendLayerOrder,\n legendSpikeHeight,\n MUTED_LEGEND_FILL,\n rangeTrackOffset,\n sanitizeKey,\n slideThumb,\n sliderIndexFromPointer,\n thumbTrackPercent,\n type LayerSlider,\n formatMapValue,\n normalizeMapData,\n type MapChartInput,\n type MapHoverEntry,\n type MapLayerModel,\n type MapModel,\n} from '../lib/index.js';\nimport { renderMapChart, resizeMapChart, stopMapChart, type MapChartController } from '../render/draw.js';\nimport { mapChartStyles } from './styles.js';\n\nconst SPIKE_COLOR = '#939BA7';\n\nfunction renderLegendSpike(index: number, id: string) {\n const h = legendSpikeHeight(index);\n return html`\n <span class=\"legend-spike\">\n <svg width=\"25\" height=${h} viewBox=${`0 0 25 ${h}`} fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <mask\n id=${`mask_${id}`}\n style=\"mask-type:alpha\"\n maskUnits=\"userSpaceOnUse\"\n x=\"6\"\n y=\"0\"\n width=\"13\"\n height=${h}\n >\n <path\n d=${`M18.1992 ${h - 0.75}L12.1992 0.25L6.19922 ${h - 0.75}Z`}\n fill=${`url(#linear_gradient_${id})`}\n />\n </mask>\n <g mask=${`url(#mask_${id})`}>\n <path d=${`M18.1992 ${h - 0.75}L12.1992 0.25L6.19922 ${h - 0.75}Z`} fill=${SPIKE_COLOR} />\n </g>\n <path\n d=${`M22.1992 ${h - 0.75}H19.0291C18.5479 ${h - 0.75} 18.135 ${h - 0.1} 18.0463 ${h - 0.5}L12.1992 0.25L6.35216 ${h - 0.5}C6.26348 ${h - 0.1} 5.85051 ${h - 0.75} 5.36929 ${h - 0.75}H2.19922`}\n stroke=${SPIKE_COLOR}\n fill=${SPIKE_COLOR}\n fill-opacity=\"0\"\n stroke-width=\"1\"\n />\n <defs>\n <linearGradient\n id=${`linear_gradient_${id}`}\n x1=\"12.1992\"\n y1=\"0.25\"\n x2=\"12.1992\"\n y2=${h}\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stop-color=${SPIKE_COLOR} stop-opacity=\"0.7\" />\n <stop offset=\"1\" stop-color=${SPIKE_COLOR} stop-opacity=\"0.2\" />\n </linearGradient>\n </defs>\n </svg>\n </span>\n `;\n}\n\ntype RuntimeConfig = {\n MAPBOX_TOKEN?: string;\n MAPBOX_DARK_TOKEN?: string;\n MAP_PMTILES_BASE_URL?: string;\n MAP_GEOJSON_BASE_URL?: string;\n};\n\n@customElement('ui9000-map-chart')\nexport class Ui9000MapChart extends Ui9000ChartElement {\n static override styles = [mapChartStyles, chartShellStyles];\n\n @property({ type: Boolean, attribute: 'show-legend' })\n showLegend = true;\n\n @property({ type: Boolean, attribute: 'show-tooltip' })\n showTooltip = true;\n\n @property({ type: String, attribute: 'mapbox-token' })\n mapboxToken = '';\n\n @property({ type: String, attribute: 'geojson-base-url' })\n geojsonBaseUrl = '';\n\n @property({ type: String, attribute: 'pmtiles-base-url' })\n pmtilesBaseUrl = '/pmtiles';\n\n @state()\n private _empty = false;\n\n @state()\n private _emptyReason = 'No data';\n\n @state()\n private _tooltip: { x: number; y: number; title: string; value: string } | null = null;\n\n @state()\n private _layers: MapLayerModel[] = [];\n\n @state()\n private _sliders: Record<string, LayerSlider> = {};\n\n @state()\n private _activeLayers: string[] = [];\n\n @state()\n private _legendOpen = true;\n\n @state()\n private _layerOpen: Record<string, boolean> = {};\n\n private _model: MapModel | null = null;\n private _ctl: MapChartController | null = null;\n private _legendKey = '';\n private _legendDrag?: {\n thumb: HTMLElement;\n move: (e: PointerEvent) => void;\n up: (e: PointerEvent) => void;\n };\n private _resizeObserver?: ResizeObserver;\n private _raf = 0;\n private _drawGen = 0;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._resizeObserver = new ResizeObserver(() => {\n cancelAnimationFrame(this._raf);\n this._raf = requestAnimationFrame(() => {\n const root = this.chartRoot();\n if (root && !resizeMapChart(root)) this.scheduleDraw();\n });\n });\n this._resizeObserver.observe(this);\n }\n\n override disconnectedCallback(): void {\n this._resizeObserver?.disconnect();\n cancelAnimationFrame(this._raf);\n this.stopLegendDrag();\n const root = this.chartRoot();\n if (root) stopMapChart(root);\n this._ctl = null;\n super.disconnectedCallback();\n }\n\n override updated(changed: PropertyValues): void {\n if (changed.has('dataJson') || changed.has('geojsonBaseUrl')) this._model = null;\n if (changed.has('showTooltip') && !this.showTooltip) this._tooltip = null;\n if (this.shouldRedraw(changed)) this.scheduleDraw();\n }\n\n private shouldRedraw(changed: PropertyValues): boolean {\n if (!chartPropsChanged(changed)) return false;\n for (const key of changed.keys()) {\n if (typeof key !== 'string' || key.startsWith('_')) continue;\n if (key === 'showLegend' || key === 'showTooltip') continue;\n return true;\n }\n return false;\n }\n\n private scheduleDraw(): void {\n cancelAnimationFrame(this._raf);\n this._raf = requestAnimationFrame(() => {\n void this.draw();\n });\n }\n\n private chartRoot(): HTMLElement | null {\n return (this.shadowRoot?.querySelector('.chart-root') as HTMLElement | null) ?? null;\n }\n\n private token(): string {\n if (this.mapboxToken.trim()) return this.mapboxToken.trim();\n const runtime =\n typeof window !== 'undefined'\n ? (window as Window & { __RUNTIME_CONFIG__?: RuntimeConfig }).__RUNTIME_CONFIG__\n : undefined;\n if (runtime?.MAPBOX_TOKEN) return runtime.MAPBOX_TOKEN;\n const env = (import.meta as { env?: Record<string, string | undefined> }).env;\n return (env?.STORYBOOK_MAPBOX_TOKEN || env?.VITE_MAPBOX_TOKEN || '').trim();\n }\n\n private geojsonUrl(): string {\n if (this.geojsonBaseUrl.trim()) return this.geojsonBaseUrl.trim();\n const runtime =\n typeof window !== 'undefined'\n ? (window as Window & { __RUNTIME_CONFIG__?: RuntimeConfig }).__RUNTIME_CONFIG__\n : undefined;\n return (runtime?.MAP_GEOJSON_BASE_URL || '').trim();\n }\n\n private pmtilesUrl(): string {\n if (this.pmtilesBaseUrl.trim()) return this.pmtilesBaseUrl.trim();\n const runtime =\n typeof window !== 'undefined'\n ? (window as Window & { __RUNTIME_CONFIG__?: RuntimeConfig }).__RUNTIME_CONFIG__\n : undefined;\n if (runtime?.MAP_PMTILES_BASE_URL) return runtime.MAP_PMTILES_BASE_URL;\n const env = (import.meta as { env?: Record<string, string | undefined> }).env;\n return (env?.STORYBOOK_MAP_PMTILES_BASE_URL || env?.VITE_MAP_PMTILES_BASE_URL || '/pmtiles').trim();\n }\n\n private mode(): 'light' | 'dark' {\n const value = readCssVar(this, CSS_VARS.mode, 'light');\n return value === 'dark' ? 'dark' : 'light';\n }\n\n private async draw(): Promise<void> {\n const root = this.chartRoot();\n if (!root) return;\n const gen = ++this._drawGen;\n\n const parsed = parseJsonAttr<MapChartInput>(this.dataJson, null);\n let model = this._model ?? normalizeMapData(parsed);\n this._model = model;\n\n if (!model.layers.length) {\n this._empty = true;\n this._emptyReason = 'No data';\n this._layers = [];\n stopMapChart(root);\n this._ctl = null;\n return;\n }\n\n const needsGeo = model.layers.some((layer) => !layer.features.length);\n const geoBase = this.geojsonUrl();\n let geoFetchFailed = false;\n if (needsGeo && geoBase) {\n const types = [...new Set(model.layers.map((l) => l.mapType))];\n const loaded = await Promise.all(\n types.map(async (mapType) => [mapType, await fetchMapGeoJson(mapType, geoBase)] as const),\n );\n if (gen !== this._drawGen) return;\n const byType = Object.fromEntries(loaded.filter((entry) => entry[1]));\n geoFetchFailed = loaded.some((entry) => !entry[1]);\n model = {\n ...model,\n layers: model.layers.map((layer) =>\n layer.features.length ? layer : joinLayerFeatures(layer, byType[layer.mapType] ?? undefined),\n ),\n };\n this._model = model;\n }\n\n const token = this.token();\n if (!token) {\n this._empty = true;\n this._emptyReason = 'Mapbox token required';\n this._layers = model.layers;\n stopMapChart(root);\n this._ctl = null;\n return;\n }\n\n const hasMarks = model.layers.some((layer) => layer.features.length > 0);\n this._empty = !hasMarks;\n this._emptyReason = hasMarks\n ? 'No data'\n : model.layers.some((l) => l.matchTotal > 0 && l.matchHit === 0)\n ? 'No locations matched the map boundaries'\n : geoFetchFailed\n ? 'Could not load map boundaries'\n : 'Map boundaries required';\n this._layers = model.layers;\n if (!hasMarks) {\n stopMapChart(root);\n this._ctl = null;\n return;\n }\n this.syncLegendState(model.layers);\n\n const ctl = await renderMapChart(root, {\n model,\n token,\n mode: this.mode(),\n showTooltip: this.showTooltip,\n pmtilesBaseUrl: this.pmtilesUrl(),\n activeLayerIds: this._activeLayers,\n sliders: this._sliders,\n year: model.layers.find((layer) => layer.selectedYear)?.selectedYear,\n onHover: this.showTooltip\n ? (entry) => this.setTooltip(entry)\n : undefined,\n });\n if (gen !== this._drawGen) {\n ctl?.destroy();\n return;\n }\n this._ctl = ctl;\n if (!this._ctl) {\n this._empty = true;\n this._emptyReason = 'Mapbox GL failed to load';\n stopMapChart(root);\n }\n }\n\n private syncLegendState(layers: MapLayerModel[]): void {\n const ids = layers.map((layer) => layer.layerId);\n const key = ids.join('\\0');\n if (key !== this._legendKey) {\n this._legendKey = key;\n this._sliders = Object.fromEntries(\n layers.map((layer) => [layer.layerId, defaultLayerSlider(layer.colorRanges.length)]),\n );\n this._activeLayers = ids;\n this._layerOpen = {};\n return;\n }\n const sliders = { ...this._sliders };\n let slidersChanged = false;\n for (const layer of layers) {\n if (!sliders[layer.layerId]) {\n sliders[layer.layerId] = defaultLayerSlider(layer.colorRanges.length);\n slidersChanged = true;\n }\n }\n if (slidersChanged) this._sliders = sliders;\n }\n\n private pushLegend(): void {\n this._ctl?.applyLegend(this._activeLayers, this._sliders);\n }\n\n private toggleLayer(layerId: string): void {\n const on = this._activeLayers.includes(layerId);\n this._activeLayers = on\n ? this._activeLayers.filter((id) => id !== layerId)\n : [...this._activeLayers, layerId];\n this.pushLegend();\n }\n\n private toggleLayerOpen(layerId: string): void {\n this._layerOpen = { ...this._layerOpen, [layerId]: this._layerOpen[layerId] === false };\n }\n\n private setSlider(layerId: string, edge: 'leftSlider' | 'rightSlider', raw: number): void {\n const layer = this._layers.find((item) => item.layerId === layerId);\n const rangeCount = layer?.colorRanges.length ?? 1;\n const current = this._sliders[layerId] ?? defaultLayerSlider(rangeCount);\n const next = slideThumb(current, edge, raw, rangeCount);\n if (next.leftSlider === current.leftSlider && next.rightSlider === current.rightSlider) return;\n this._sliders = { ...this._sliders, [layerId]: next };\n this.pushLegend();\n }\n\n private startThumbDrag(layerId: string, edge: 'leftSlider' | 'rightSlider', e: PointerEvent): void {\n const thumb = e.currentTarget;\n if (!(thumb instanceof HTMLElement)) return;\n const track = thumb.parentElement;\n if (!track) return;\n e.preventDefault();\n e.stopPropagation();\n thumb.setPointerCapture(e.pointerId);\n this.stopLegendDrag();\n\n const move = (ev: PointerEvent) => {\n const layer = this._layers.find((item) => item.layerId === layerId);\n const max = layer?.colorRanges.length ?? 1;\n const index = sliderIndexFromPointer(ev.clientX, track.getBoundingClientRect(), max);\n this.setSlider(layerId, edge, index);\n };\n const up = (ev: PointerEvent) => {\n if (thumb.hasPointerCapture(ev.pointerId)) thumb.releasePointerCapture(ev.pointerId);\n this.stopLegendDrag();\n };\n thumb.addEventListener('pointermove', move);\n thumb.addEventListener('pointerup', up);\n thumb.addEventListener('pointercancel', up);\n this._legendDrag = { thumb, move, up };\n move(e);\n }\n\n private stopLegendDrag(): void {\n const drag = this._legendDrag;\n if (!drag) return;\n drag.thumb.removeEventListener('pointermove', drag.move);\n drag.thumb.removeEventListener('pointerup', drag.up);\n drag.thumb.removeEventListener('pointercancel', drag.up);\n this._legendDrag = undefined;\n }\n\n private setTooltip(entry: MapHoverEntry | null): void {\n if (!entry) {\n this._tooltip = null;\n return;\n }\n const root = this.chartRoot();\n const x = entry.point?.x ?? (root?.clientWidth ?? 0) / 2;\n const y = entry.point?.y ?? 48;\n this._tooltip = {\n x,\n y,\n title: entry.regionName,\n value: `${entry.valueKey}: ${formatMapValue(entry.value)}`,\n };\n }\n\n private matchNotice(): string | null {\n const total = this._layers.reduce((sum, l) => sum + l.matchTotal, 0);\n const hit = this._layers.reduce((sum, l) => sum + l.matchHit, 0);\n if (total > 0 && hit === 0) {\n return `0 of ${total} ${total === 1 ? 'location' : 'locations'} matched the map boundaries`;\n }\n return null;\n }\n\n private renderLegend() {\n if (!this.showLegend || this._empty) return nothing;\n const layers = legendLayerOrder(this._layers.filter((layer) => layer.features.length > 0));\n if (!layers.length) return nothing;\n\n return html`\n <div class=\"map-legend\" part=\"legend\">\n <div class=\"legend-panel-header\">\n <p class=\"legend-kicker\">Legend</p>\n <button\n type=\"button\"\n class=\"legend-chevron\"\n aria-expanded=${this._legendOpen}\n aria-label=${this._legendOpen ? 'Collapse legend' : 'Expand legend'}\n @click=${() => {\n this._legendOpen = !this._legendOpen;\n }}\n ></button>\n </div>\n ${this._legendOpen\n ? html`<div class=\"legend-layers\">\n ${layers.map((layer) => this.renderLegendLayer(layer))}\n </div>`\n : nothing}\n </div>\n `;\n }\n\n private renderLegendLayer(layer: MapLayerModel) {\n const active = this._activeLayers.includes(layer.layerId);\n const open = this._layerOpen[layer.layerId] !== false;\n const slider = this._sliders[layer.layerId] ?? defaultLayerSlider(layer.colorRanges.length);\n const ranges = layer.colorRanges;\n const isBubble = layer.visualisationType === 'bubbles';\n const isSpike = layer.visualisationType === 'spike';\n const isMarkers = layer.visualisationType === 'markers';\n const showRamp = ranges.length > 0;\n\n return html`\n <div class=\"legend-layer\">\n <div class=\"legend-layer-header\">\n <label class=\"legend-check\">\n <input\n type=\"checkbox\"\n .checked=${active}\n @change=${(e: Event) => {\n e.stopPropagation();\n this.toggleLayer(layer.layerId);\n }}\n />\n <span>${layer.layerName}</span>\n </label>\n <button\n type=\"button\"\n class=\"legend-chevron\"\n aria-expanded=${open}\n aria-label=${open ? `Collapse ${layer.layerName}` : `Expand ${layer.layerName}`}\n @click=${() => this.toggleLayerOpen(layer.layerId)}\n ></button>\n </div>\n ${open\n ? html`\n <div class=\"legend-details\">\n <p class=\"legend-stat\">\n <span class=\"legend-avg\">${formatAverage(layer.average)}</span>\n ${formatFieldLabel(layer.valueKey)}\n </p>\n ${showRamp\n ? html`\n <div class=\"legend-scale\" data-kind=${layer.visualisationType}>\n <div\n class=\"legend-colors\"\n ?data-qualitative=${isBubble || isSpike}\n >\n <div class=\"legend-range\">\n <div\n class=\"legend-range-track\"\n style=\"left:${rangeTrackOffset('left', slider.leftSlider, ranges.length)}\"\n >\n <button\n type=\"button\"\n class=\"legend-thumb\"\n aria-label=\"Lowest ${layer.layerName} range\"\n style=\"left:${thumbTrackPercent(slider.leftSlider, ranges.length)}\"\n @pointerdown=${(e: PointerEvent) =>\n this.startThumbDrag(layer.layerId, 'leftSlider', e)}\n ></button>\n </div>\n <div\n class=\"legend-range-track\"\n style=\"right:${rangeTrackOffset('right', slider.rightSlider, ranges.length)}\"\n >\n <button\n type=\"button\"\n class=\"legend-thumb\"\n aria-label=\"Highest ${layer.layerName} range\"\n style=\"left:${thumbTrackPercent(slider.rightSlider, ranges.length)}\"\n @pointerdown=${(e: PointerEvent) =>\n this.startThumbDrag(layer.layerId, 'rightSlider', e)}\n ></button>\n </div>\n </div>\n <div class=\"legend-buckets\">\n ${ranges.map((range, index) => {\n const inRange =\n slider.leftSlider <= index && index < slider.rightSlider;\n const fill =\n isBubble || isSpike\n ? MUTED_LEGEND_FILL\n : inRange\n ? range.color\n : MUTED_LEGEND_FILL;\n const bubble = isBubble ? (DEFAULT_BUBBLES_RADIUS[index] ?? 12) : 0;\n const inner = bubble - 15 > 0 ? bubble - 15 : 0;\n return html`<span\n class=\"legend-bucket\"\n ?data-bubble=${isBubble}\n ?data-inner=${inner > 0}\n ?data-qualitative=${isBubble || isSpike}\n style=\"background:${fill};--bubble-size:${bubble}px;--inner-size:${inner}px\"\n ></span>`;\n })}\n </div>\n ${isSpike\n ? html`<div class=\"legend-spikes\">\n ${ranges.map((_range, index) =>\n renderLegendSpike(\n index,\n `${sanitizeKey(layer.layerId)}_${index}`,\n ),\n )}\n </div>`\n : nothing}\n </div>\n ${isMarkers\n ? nothing\n : html`<div class=\"legend-values\">\n ${ranges.map(\n (range) =>\n html`<span class=\"legend-value\">${formatLegendBucket(range.start, 2)}</span>`,\n )}\n </div>`}\n </div>\n `\n : nothing}\n </div>\n `\n : nothing}\n </div>\n `;\n }\n\n override render() {\n const title = this.headerTitle();\n const notice = this.matchNotice();\n return html`\n <div class=\"widget-shell\" part=\"shell\">\n ${this.renderShellHeader(title)}\n <div class=\"widget-body\">\n <div class=\"chart-root\" part=\"chart\" ?hidden=${this._empty}></div>\n ${this._empty ? html`<div class=\"empty\" part=\"empty\">${this._emptyReason}</div>` : nothing}\n ${this.renderLegend()}\n ${notice && !this._empty ? html`<div class=\"match-notice\">${notice}</div>` : nothing}\n ${this._tooltip\n ? html`<div\n class=\"tooltip\"\n part=\"tooltip\"\n style=\"left:${this._tooltip.x}px;top:${this._tooltip.y}px\"\n >\n <div>${this._tooltip.title}</div>\n <div>${this._tooltip.value}</div>\n </div>`\n : nothing}\n ${this.renderShellLabelTooltip()}\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ui9000-map-chart': Ui9000MapChart;\n }\n}\n\nexport function registerMapChart(): void {\n if (!customElements.get('ui9000-map-chart')) {\n customElements.define('ui9000-map-chart', Ui9000MapChart);\n }\n}\n\nregisterMapChart();\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geojson.d.ts","sourceRoot":"","sources":["../../../../src/components/map-chart/lib/geojson.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAI3D,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,wBAAwB,CAIrF;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"geojson.d.ts","sourceRoot":"","sources":["../../../../src/components/map-chart/lib/geojson.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAI3D,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,wBAAwB,CAIrF;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAqB1C;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAevD"}
|
|
@@ -21,7 +21,9 @@ async function fetchMapGeoJson(mapType, baseUrl) {
|
|
|
21
21
|
}
|
|
22
22
|
})();
|
|
23
23
|
cache.set(url, pending);
|
|
24
|
-
|
|
24
|
+
const result = await pending;
|
|
25
|
+
if (!result) cache.delete(url);
|
|
26
|
+
return result;
|
|
25
27
|
}
|
|
26
28
|
function geoJsonFileName(mapType) {
|
|
27
29
|
switch (mapType) {
|
|
@@ -1 +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
|
|
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 const result = await pending;\n if (!result) cache.delete(url);\n return result;\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,QAAM,SAAS,MAAM;AACrB,MAAI,CAAC,OAAQ,OAAM,OAAO,GAAG;AAC7B,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;"}
|