@gooddata/sdk-ui-geo 11.65.0-alpha.0 → 11.65.0-alpha.10
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/LICENSE +26 -4
- package/NOTICE +72077 -0
- package/esm/core/geoChart/GeoChartOptionsWrapper.d.ts.map +1 -1
- package/esm/core/geoChart/GeoChartOptionsWrapper.js +15 -8
- package/esm/core/geoChart/geoChartColor.d.ts +2 -2
- package/esm/core/geoChart/geoChartColor.d.ts.map +1 -1
- package/esm/core/geoChart/geoChartColor.js +7 -6
- package/esm/core/geoChart/geoChartDataSource.js +1 -1
- package/esm/core/geoChart/helpers/geoChart/data.d.ts.map +1 -1
- package/esm/core/geoChart/helpers/geoChart/data.js +12 -5
- package/esm/core/geoChart/helpers/geoChart/drilling.d.ts.map +1 -1
- package/esm/core/geoChart/helpers/geoChart/drilling.js +13 -2
- package/esm/next/hooks/layers/useLayersPrepare.d.ts +7 -1
- package/esm/next/hooks/layers/useLayersPrepare.d.ts.map +1 -1
- package/esm/next/hooks/layers/useLayersPrepare.js +19 -4
- package/esm/next/hooks/pushData/useGeoPushData.d.ts.map +1 -1
- package/esm/next/hooks/pushData/useGeoPushData.js +1 -0
- package/esm/next/layers/area/coloring/palette.d.ts +2 -2
- package/esm/next/layers/area/coloring/palette.js +4 -4
- package/esm/next/layers/area/data/transformation.d.ts.map +1 -1
- package/esm/next/layers/area/data/transformation.js +2 -1
- package/esm/next/layers/area/source.js +3 -3
- package/esm/next/layers/common/computeLegend.d.ts.map +1 -1
- package/esm/next/layers/common/computeLegend.js +12 -4
- package/esm/next/layers/common/formatAttributeValues.d.ts +8 -0
- package/esm/next/layers/common/formatAttributeValues.d.ts.map +1 -0
- package/esm/next/layers/common/formatAttributeValues.js +9 -0
- package/esm/next/layers/common/headerItemUtils.d.ts +4 -1
- package/esm/next/layers/common/headerItemUtils.d.ts.map +1 -1
- package/esm/next/layers/common/headerItemUtils.js +11 -3
- package/esm/next/layers/pushpin/coloring/palette.d.ts +3 -3
- package/esm/next/layers/pushpin/coloring/palette.d.ts.map +1 -1
- package/esm/next/layers/pushpin/coloring/palette.js +10 -8
- package/esm/next/layers/pushpin/data/transformation.d.ts.map +1 -1
- package/esm/next/layers/pushpin/data/transformation.js +5 -1
- package/esm/next/layers/pushpin/source.d.ts.map +1 -1
- package/esm/next/layers/pushpin/source.js +3 -2
- package/package.json +14 -13
- package/styles/css/main.css +19 -19
- package/styles/scss/_variables.scss +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GeoChartOptionsWrapper.d.ts","sourceRoot":"","sources":["../../../src/core/geoChart/GeoChartOptionsWrapper.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GeoChartOptionsWrapper.d.ts","sourceRoot":"","sources":["../../../src/core/geoChart/GeoChartOptionsWrapper.tsx"],"names":[],"mappings":"AAmBA,OAAO,EACH,KAAK,cAAc,EACnB,KAAK,0BAA0B,EAElC,MAAM,8BAA8B,CAAC;AAMtC,OAAO,EAA6C,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AA8CzG,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,mBAAmB,kDA6EhE;AAED,wBAAgB,yBAAyB,CACrC,aAAa,EAAE,cAAc,EAC7B,iBAAiB,EAAE,MAAM,EACzB,gBAAgB,EAAE,MAAM,GACzB,0BAA0B,EAAE,CAmB9B"}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useCallback, useMemo } from "react";
|
|
4
4
|
import { invariant } from "ts-invariant";
|
|
5
5
|
import { isResultAttributeHeader } from "@gooddata/sdk-model";
|
|
6
|
-
import { DataViewFacade, ErrorComponent as DefaultErrorComponent, LoadingComponent as DefaultLoadingComponent, ErrorCodes, VisualizationTypes, newErrorMapping, } from "@gooddata/sdk-ui";
|
|
6
|
+
import { DataViewFacade, ErrorComponent as DefaultErrorComponent, LoadingComponent as DefaultLoadingComponent, ErrorCodes, VisualizationTypes, createNumberFormatter, formatAttributeHeaderValues, getAttributeHeaderItemName, newErrorMapping, } from "@gooddata/sdk-ui";
|
|
7
7
|
import { getValidColorPalette, } from "@gooddata/sdk-ui-vis-commons";
|
|
8
8
|
import { getColorStrategy } from "./colorStrategy/geoChart.js";
|
|
9
9
|
import { DEFAULT_DATA_POINTS_LIMIT } from "./constants/geoChart.js";
|
|
@@ -46,13 +46,18 @@ export function GeoChartOptionsWrapper(props) {
|
|
|
46
46
|
const nullHeaderString = useMemo(() => props.intl.formatMessage({ id: "visualization.emptyValue" }), // TODO: RAIL-4360 replace by proper null header string id when available
|
|
47
47
|
[props.intl]);
|
|
48
48
|
const errorMap = useMemo(() => newErrorMapping(props.intl), [props.intl]);
|
|
49
|
+
// element values of attributes with a number format get their formatted name once, here, so the
|
|
50
|
+
// location, segment, tooltip and legend texts built below all show it
|
|
51
|
+
const { dataView: rawDataView, config } = props;
|
|
52
|
+
const formattedDataView = useMemo(() => rawDataView &&
|
|
53
|
+
formatAttributeHeaderValues(rawDataView, createNumberFormatter(config?.separators)), [rawDataView, config?.separators]);
|
|
49
54
|
const getCategoryLegendItems = useCallback((colorStrategy) => {
|
|
50
55
|
return createCategoryLegendItems(colorStrategy, emptyHeaderString, nullHeaderString);
|
|
51
56
|
}, [emptyHeaderString, nullHeaderString]);
|
|
52
57
|
const buildGeoChartOptions = useCallback((geoData, props) => {
|
|
53
58
|
const { segment } = geoData;
|
|
54
|
-
const { config: { colors = [], colorPalette = [], colorMapping = [] } = {}
|
|
55
|
-
const dv = DataViewFacade.for(
|
|
59
|
+
const { config: { colors = [], colorPalette = [], colorMapping = [] } = {} } = props;
|
|
60
|
+
const dv = DataViewFacade.for(formattedDataView);
|
|
56
61
|
const palette = getValidColorPalette(colors, colorPalette);
|
|
57
62
|
const colorStrategy = getColorStrategy(palette, colorMapping, geoData, dv);
|
|
58
63
|
const categoryItems = segment ? getCategoryLegendItems(colorStrategy) : [];
|
|
@@ -62,10 +67,9 @@ export function GeoChartOptionsWrapper(props) {
|
|
|
62
67
|
colorStrategy,
|
|
63
68
|
colorPalette: palette,
|
|
64
69
|
};
|
|
65
|
-
}, [getCategoryLegendItems]);
|
|
70
|
+
}, [getCategoryLegendItems, formattedDataView]);
|
|
66
71
|
const renderVisualization = useCallback(() => {
|
|
67
|
-
const
|
|
68
|
-
const dv = DataViewFacade.for(dataView);
|
|
72
|
+
const dv = DataViewFacade.for(formattedDataView);
|
|
69
73
|
const geoData = getGeoData(dv, emptyHeaderString, nullHeaderString);
|
|
70
74
|
const validationResult = validateGeoData(geoData, props);
|
|
71
75
|
if (validationResult?.isDataTooLarge) {
|
|
@@ -74,7 +78,7 @@ export function GeoChartOptionsWrapper(props) {
|
|
|
74
78
|
}
|
|
75
79
|
const geoChartOptions = buildGeoChartOptions(geoData, props);
|
|
76
80
|
return _jsx(GeoChartInner, { ...props, geoChartOptions: geoChartOptions });
|
|
77
|
-
}, [buildGeoChartOptions, emptyHeaderString, nullHeaderString, props]);
|
|
81
|
+
}, [formattedDataView, buildGeoChartOptions, emptyHeaderString, nullHeaderString, props]);
|
|
78
82
|
const { dataView, error, isLoading } = props;
|
|
79
83
|
const ErrorComponent = resolveOptionalComponent(props.ErrorComponent, DefaultErrorComponent);
|
|
80
84
|
const LoadingComponent = resolveOptionalComponent(props.LoadingComponent, DefaultLoadingComponent);
|
|
@@ -91,7 +95,10 @@ export function createCategoryLegendItems(colorStrategy, emptyHeaderString, null
|
|
|
91
95
|
const colorAssignment = colorStrategy.getColorAssignment();
|
|
92
96
|
return colorAssignment.map((item, legendIndex) => {
|
|
93
97
|
const { name, uri } = isResultAttributeHeader(item.headerItem)
|
|
94
|
-
?
|
|
98
|
+
? {
|
|
99
|
+
name: getAttributeHeaderItemName(item.headerItem.attributeHeaderItem),
|
|
100
|
+
uri: item.headerItem.attributeHeaderItem.uri,
|
|
101
|
+
}
|
|
95
102
|
: { name: emptyHeaderString, uri: emptyHeaderString };
|
|
96
103
|
const color = colorStrategy.getColorByIndex(legendIndex);
|
|
97
104
|
return {
|
|
@@ -6,7 +6,7 @@ type ColorPaletteMapping = {
|
|
|
6
6
|
};
|
|
7
7
|
export declare function getColorPaletteMapping(colorStrategy: IColorStrategy): ColorPaletteMapping;
|
|
8
8
|
/**
|
|
9
|
-
* Return RGB border and background colors base on color and segment
|
|
9
|
+
* Return RGB border and background colors base on color and segment element URIs
|
|
10
10
|
*
|
|
11
11
|
* Example:
|
|
12
12
|
* ```
|
|
@@ -16,7 +16,7 @@ export declare function getColorPaletteMapping(colorStrategy: IColorStrategy): C
|
|
|
16
16
|
* }]
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
|
-
export declare function getPushpinColors(colorValues: Array<number | null>, segmentValues: string
|
|
19
|
+
export declare function getPushpinColors(colorValues: Array<number | null>, segmentValues: Array<string | null> | undefined, colorStrategy: IColorStrategy): IPushpinColor[];
|
|
20
20
|
export declare function generateLegendColorData(colorSeries: number[], colorString: string): IColorLegendItem[];
|
|
21
21
|
export {};
|
|
22
22
|
//# sourceMappingURL=geoChartColor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geoChartColor.d.ts","sourceRoot":"","sources":["../../../src/core/geoChart/geoChartColor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE1F,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAavD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAiB7F;AAED,KAAK,mBAAmB,GAAG;IAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAAE,CAAC;AAE5D,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,cAAc,GAAG,mBAAmB,
|
|
1
|
+
{"version":3,"file":"geoChartColor.d.ts","sourceRoot":"","sources":["../../../src/core/geoChart/geoChartColor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE1F,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAavD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAiB7F;AAED,KAAK,mBAAmB,GAAG;IAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAAE,CAAC;AAE5D,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,cAAc,GAAG,mBAAmB,CAqBzF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC5B,WAAW,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,EACjC,aAAa,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,YAAK,EACxC,aAAa,EAAE,cAAc,GAC9B,aAAa,EAAE,CAkDjB;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,gBAAgB,EAAE,CA0BtG"}
|
|
@@ -32,16 +32,17 @@ export function getColorPaletteMapping(colorStrategy) {
|
|
|
32
32
|
[DEFAULT_SEGMENT_ITEM]: colorPalette,
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
-
// color base on SegmentBy
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
// color base on SegmentBy, keyed by the raw element identity: formatted names of distinct
|
|
36
|
+
// elements can be equal (e.g. two numbers rounded by the number format)
|
|
37
|
+
const key = isResultAttributeHeader(item.headerItem)
|
|
38
|
+
? (item.headerItem.attributeHeaderItem.uri ?? DEFAULT_SEGMENT_ITEM)
|
|
38
39
|
: DEFAULT_SEGMENT_ITEM;
|
|
39
|
-
result[
|
|
40
|
+
result[key] = colorPalette;
|
|
40
41
|
return result;
|
|
41
42
|
}, {});
|
|
42
43
|
}
|
|
43
44
|
/**
|
|
44
|
-
* Return RGB border and background colors base on color and segment
|
|
45
|
+
* Return RGB border and background colors base on color and segment element URIs
|
|
45
46
|
*
|
|
46
47
|
* Example:
|
|
47
48
|
* ```
|
|
@@ -66,7 +67,7 @@ export function getPushpinColors(colorValues, segmentValues = [], colorStrategy)
|
|
|
66
67
|
const colorPaletteMapping = getColorPaletteMapping(colorStrategy);
|
|
67
68
|
if (!colorValues.length) {
|
|
68
69
|
return segmentNames.map((name) => {
|
|
69
|
-
const palette = colorPaletteMapping[name];
|
|
70
|
+
const palette = colorPaletteMapping[name ?? DEFAULT_SEGMENT_ITEM];
|
|
70
71
|
return {
|
|
71
72
|
border: DEFAULT_PUSHPIN_BORDER_COLOR_VALUE,
|
|
72
73
|
background: palette[DEFAULT_COLOR_INDEX_IN_PALETTE],
|
|
@@ -26,7 +26,7 @@ function transformPushpinDataSource({ config, geoData, colorStrategy, }) {
|
|
|
26
26
|
const colorData = color?.data ?? [];
|
|
27
27
|
const sizeFormat = size?.format ?? "";
|
|
28
28
|
const colorFormat = color?.format ?? "";
|
|
29
|
-
const pushpinColors = getPushpinColors(colorData,
|
|
29
|
+
const pushpinColors = getPushpinColors(colorData, segmentUris, colorStrategy);
|
|
30
30
|
return locationData.reduce((result, coordinates, index) => {
|
|
31
31
|
if (!coordinates || !Number.isFinite(coordinates.lat) || !Number.isFinite(coordinates.lng)) {
|
|
32
32
|
return result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../../../src/core/geoChart/helpers/geoChart/data.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,oBAAoB,EAGzB,KAAK,aAAa,EAWrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAe,KAAK,cAAc,
|
|
1
|
+
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../../../src/core/geoChart/helpers/geoChart/data.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,oBAAoB,EAGzB,KAAK,aAAa,EAWrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAe,KAAK,cAAc,EAA8B,MAAM,kBAAkB,CAAC;AAChG,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE/E,OAAO,EACH,KAAK,iBAAiB,EAEtB,KAAK,QAAQ,EAIhB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAoBvE,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,UAAU,GAAG,IAAI,CAepE;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAexE;AAYD,wBAAgB,UAAU,CACtB,EAAE,EAAE,cAAc,EAClB,iBAAiB,EAAE,MAAM,EACzB,gBAAgB,EAAE,MAAM,GACzB,QAAQ,CAwEV;AA2KD,wBAAgB,mBAAmB,CAC/B,aAAa,EAAE,0BAA0B,EAAE,EAC3C,OAAO,EAAE,QAAQ,GAClB,iBAAiB,CAenB;AAUD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,OAAO,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAQnG;AAED,MAAM,MAAM,aAAa,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,GAAG;IAClE,KAAK,EAAE,aAAa,EAAE,CAAC;CAC1B,CAAC;AACF,MAAM,WAAW,yBAAyB;IACtC,iBAAiB,EAAE,aAAa,CAAC;IACjC,kBAAkB,EAAE,aAAa,GAAG,SAAS,CAAC;IAC9C,oBAAoB,EAAE,aAAa,GAAG,SAAS,CAAC;CACnD;AAED,wBAAgB,4BAA4B,CACxC,EAAE,EAAE,cAAc,EAClB,OAAO,EAAE,QAAQ,GAClB,yBAAyB,CAkC3B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// (C) 2020-2026 GoodData Corporation
|
|
2
2
|
import { attributeDisplayFormRef, attributeLocalId, isAttribute, isIdentifierRef, isResultAttributeHeader, measureItem, measureLocalId, resultHeaderName, } from "@gooddata/sdk-model";
|
|
3
|
-
import { BucketNames } from "@gooddata/sdk-ui";
|
|
3
|
+
import { BucketNames, getAttributeHeaderItemName } from "@gooddata/sdk-ui";
|
|
4
4
|
import { dataValueAsFloat, getFormatFromExecutionResponse, getGeoAttributeHeaderItems, getMinMax, } from "./common.js";
|
|
5
5
|
export function getLocation(latlng) {
|
|
6
6
|
if (!latlng) {
|
|
@@ -58,7 +58,7 @@ export function getGeoData(dv, emptyHeaderString, nullHeaderString) {
|
|
|
58
58
|
geoData[BucketNames.SEGMENT].uris = uris;
|
|
59
59
|
}
|
|
60
60
|
if (tooltipTextIndex !== undefined) {
|
|
61
|
-
geoData[BucketNames.TOOLTIP_TEXT].data = getAttributeData(attributeHeaderItems, tooltipTextIndex, emptyHeaderString, nullHeaderString);
|
|
61
|
+
geoData[BucketNames.TOOLTIP_TEXT].data = getAttributeData(attributeHeaderItems, tooltipTextIndex, emptyHeaderString, nullHeaderString, true);
|
|
62
62
|
}
|
|
63
63
|
if (sizeIndex !== undefined) {
|
|
64
64
|
geoData[BucketNames.SIZE].data = getMeasureData(dv, sizeIndex);
|
|
@@ -74,7 +74,8 @@ function getSegmentDataAndUris(attributeHeaderItems, dataIndex, nullHeaderString
|
|
|
74
74
|
const headerItems = attributeHeaderItems[dataIndex];
|
|
75
75
|
return headerItems.reduce((result, headerItem) => {
|
|
76
76
|
if (headerItem && isResultAttributeHeader(headerItem)) {
|
|
77
|
-
const { uri
|
|
77
|
+
const { uri } = headerItem.attributeHeaderItem;
|
|
78
|
+
const name = getAttributeHeaderItemName(headerItem.attributeHeaderItem);
|
|
78
79
|
return { uris: [...result.uris, uri], data: [...result.data, name ?? nullHeaderString] };
|
|
79
80
|
}
|
|
80
81
|
return result;
|
|
@@ -85,10 +86,16 @@ function getMeasureData(dv, dataIndex) {
|
|
|
85
86
|
const measureValues = twoDimData[dataIndex];
|
|
86
87
|
return measureValues.map(dataValueAsFloat);
|
|
87
88
|
}
|
|
88
|
-
|
|
89
|
+
/**
|
|
90
|
+
* @param useFormattedName - read the formatted element value (for values shown to the user); pass false
|
|
91
|
+
* for values that get parsed, e.g. coordinates
|
|
92
|
+
*/
|
|
93
|
+
function getAttributeData(attributeHeaderItems, dataIndex, emptyHeaderString, nullHeaderString, useFormattedName = false) {
|
|
89
94
|
const headerItems = attributeHeaderItems[dataIndex];
|
|
90
95
|
return headerItems.map((i) => {
|
|
91
|
-
const name =
|
|
96
|
+
const name = useFormattedName && isResultAttributeHeader(i)
|
|
97
|
+
? getAttributeHeaderItemName(i.attributeHeaderItem)
|
|
98
|
+
: resultHeaderName(i);
|
|
92
99
|
if (name) {
|
|
93
100
|
return name;
|
|
94
101
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drilling.d.ts","sourceRoot":"","sources":["../../../../../src/core/geoChart/helpers/geoChart/drilling.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"drilling.d.ts","sourceRoot":"","sources":["../../../../../src/core/geoChart/helpers/geoChart/drilling.ts"],"names":[],"mappings":"AASA,OAAO,EACH,KAAK,cAAc,EACnB,KAAK,YAAY,EAGjB,KAAK,gBAAgB,EAIxB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,KAAK,QAAQ,EAAuB,MAAM,yBAAyB,CAAC;AA4F7E,wBAAgB,0BAA0B,CACtC,cAAc,EAAE,gBAAgB,EAAE,EAClC,WAAW,EAAE,YAAY,EACzB,EAAE,EAAE,cAAc,EAClB,OAAO,EAAE,QAAQ,EACjB,aAAa,EAAE,OAAO,CAAC,iBAAiB,EACxC,cAAc,EAAE,MAAM,EAAE,EACxB,MAAM,EAAE,WAAW,EACnB,UAAU,CAAC,EAAE,UAAU,GACxB,IAAI,CAoDN"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// (C) 2020-2026 GoodData Corporation
|
|
2
2
|
import { omit, without } from "lodash-es";
|
|
3
|
+
import { isResultAttributeHeader, } from "@gooddata/sdk-model";
|
|
3
4
|
import { getDrillIntersection, isSomeHeaderPredicateMatched, } from "@gooddata/sdk-ui";
|
|
4
5
|
import { findGeoAttributesInDimension, parseGeoProperties } from "./data.js";
|
|
5
6
|
function getDrillIntersectionForGeoChart(drillableItems, dv, geoData, locationIndex) {
|
|
@@ -44,6 +45,15 @@ function getAttributeHeader(attribute, dataIndex) {
|
|
|
44
45
|
attributeHeaderItem: undefined,
|
|
45
46
|
};
|
|
46
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* The drill event carries the raw element value, while the pin properties hold the value shown in the
|
|
50
|
+
* tooltip, which can be number-formatted. Empty and null elements keep the placeholder from the properties.
|
|
51
|
+
*/
|
|
52
|
+
function getRawDrillValue(attribute, dataIndex, shownValue) {
|
|
53
|
+
const item = attribute?.items[dataIndex];
|
|
54
|
+
const rawValue = item && isResultAttributeHeader(item) ? item.attributeHeaderItem.name : undefined;
|
|
55
|
+
return rawValue || shownValue;
|
|
56
|
+
}
|
|
47
57
|
export function handleGeoPushpinDrillEvent(drillableItems, drillConfig, dv, geoData, pinProperties, pinCoordinates, target, clickEvent) {
|
|
48
58
|
const { locationIndex } = pinProperties || {};
|
|
49
59
|
const drillIntersection = getDrillIntersectionForGeoChart(drillableItems, dv, geoData, locationIndex);
|
|
@@ -53,14 +63,15 @@ export function handleGeoPushpinDrillEvent(drillableItems, drillConfig, dv, geoD
|
|
|
53
63
|
const { onDrill } = drillConfig;
|
|
54
64
|
const [lng, lat] = pinCoordinates;
|
|
55
65
|
const { locationName: { value: locationNameValue }, color: { value: colorValue }, segment: { value: segmentByValue }, size: { value: sizeValue }, } = parseGeoProperties(pinProperties) || {};
|
|
66
|
+
const { segmentByAttribute, tooltipTextAttribute } = findGeoAttributesInDimension(dv, geoData);
|
|
56
67
|
const drillContext = {
|
|
57
68
|
element: "pushpin",
|
|
58
69
|
intersection: drillIntersection,
|
|
59
70
|
type: "pushpin",
|
|
60
71
|
color: colorValue,
|
|
61
72
|
location: { lat, lng },
|
|
62
|
-
locationName: locationNameValue,
|
|
63
|
-
segmentBy: segmentByValue,
|
|
73
|
+
locationName: getRawDrillValue(tooltipTextAttribute, locationIndex, locationNameValue),
|
|
74
|
+
segmentBy: getRawDrillValue(segmentByAttribute, locationIndex, segmentByValue),
|
|
64
75
|
size: sizeValue,
|
|
65
76
|
};
|
|
66
77
|
const drillEventExtended = {
|
|
@@ -2,7 +2,7 @@ import type { IntlShape } from "react-intl";
|
|
|
2
2
|
import type { IAnalyticalBackend } from "@gooddata/sdk-backend-spi";
|
|
3
3
|
import type { IExecutionConfig } from "@gooddata/sdk-model";
|
|
4
4
|
import { type DataViewFacade, type GoodDataSdkError, type UseCancelablePromiseStatus } from "@gooddata/sdk-ui";
|
|
5
|
-
import type { IGeoLayerOutput } from "../../layers/registry/adapterTypes.js";
|
|
5
|
+
import type { IGeoAdapterContext, IGeoLayerOutput } from "../../layers/registry/adapterTypes.js";
|
|
6
6
|
import type { IGeoChartConfig } from "../../types/config/unified.js";
|
|
7
7
|
import type { ILayerExecutionRecord } from "../../types/props/geoChart/internal.js";
|
|
8
8
|
/**
|
|
@@ -61,6 +61,12 @@ export interface ILayersPrepareContext {
|
|
|
61
61
|
execConfig?: IExecutionConfig;
|
|
62
62
|
intl: IntlShape;
|
|
63
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Prepares a single layer using its adapter.
|
|
66
|
+
*
|
|
67
|
+
* @internal
|
|
68
|
+
*/
|
|
69
|
+
export declare function prepareSingleLayer(layerExecution: ILayerExecutionRecord, layerDataViews: Map<string, DataViewFacade>, adapterContext: IGeoAdapterContext): Promise<ILayerPreparedData>;
|
|
64
70
|
/**
|
|
65
71
|
* Hook that prepares all layer outputs in parallel once dataViews are available.
|
|
66
72
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLayersPrepare.d.ts","sourceRoot":"","sources":["../../../../src/next/hooks/layers/useLayersPrepare.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACH,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAErB,KAAK,0BAA0B,EAElC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"useLayersPrepare.d.ts","sourceRoot":"","sources":["../../../../src/next/hooks/layers/useLayersPrepare.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACH,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAErB,KAAK,0BAA0B,EAElC,MAAM,kBAAkB,CAAC;AAI1B,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AAMpF;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAC/B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,cAAc,CAAC;IAEzB;;;OAGG;IACH,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;CAClC;AAOD;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACjC;;;OAGG;IACH,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAE9C;;;;;;OAMG;IACH,MAAM,EAAE,0BAA0B,CAAC;IAEnC;;OAEG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IAClC,OAAO,EAAE,kBAAkB,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,IAAI,EAAE,SAAS,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACpC,cAAc,EAAE,qBAAqB,EACrC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,EAC3C,cAAc,EAAE,kBAAkB,GACnC,OAAO,CAAC,kBAAkB,CAAC,CAiB7B;AAgCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC5B,eAAe,EAAE,qBAAqB,EAAE,EACxC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,EAC3C,UAAU,EAAE,0BAA0B,EACtC,OAAO,EAAE,qBAAqB,GAC/B,oBAAoB,CA0FtB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// (C) 2025-2026 GoodData Corporation
|
|
2
2
|
import { useCallback, useMemo } from "react";
|
|
3
3
|
import { UnexpectedSdkError, useCancelablePromise, } from "@gooddata/sdk-ui";
|
|
4
|
+
import { formatAttributeValues } from "../../layers/common/formatAttributeValues.js";
|
|
4
5
|
import { getLayerAdapter } from "../../layers/registry/adapterRegistry.js";
|
|
5
6
|
import { resolveLayerColorConfig } from "../../utils/color/resolveLayerColorConfig.js";
|
|
6
7
|
import { createDataViewsFingerprint, createLayersStructureFingerprint } from "../../utils/fingerprint.js";
|
|
@@ -10,12 +11,17 @@ import { processSettledLayerResults } from "./processSettledLayerResults.js";
|
|
|
10
11
|
*
|
|
11
12
|
* @internal
|
|
12
13
|
*/
|
|
13
|
-
async function prepareSingleLayer(layerExecution, layerDataViews, adapterContext) {
|
|
14
|
+
export async function prepareSingleLayer(layerExecution, layerDataViews, adapterContext) {
|
|
14
15
|
const { layerId, layer } = layerExecution;
|
|
15
|
-
const
|
|
16
|
-
if (!
|
|
16
|
+
const rawDataView = layerDataViews.get(layerId);
|
|
17
|
+
if (!rawDataView) {
|
|
17
18
|
throw new UnexpectedSdkError(`No dataView found for layer ${layerId}`);
|
|
18
19
|
}
|
|
20
|
+
// Element values of attributes with a number format get their formatted name here, once, and the
|
|
21
|
+
// formatted view is the one every later step reads (geo data, color strategy, legend, pushed color
|
|
22
|
+
// assignments, map sync and click handling), so all of them display the same formatted text. Segments
|
|
23
|
+
// are still keyed, sorted and drilled by their raw name and uri, which the formatted view keeps.
|
|
24
|
+
const dataView = formatAttributeValues(rawDataView, adapterContext);
|
|
19
25
|
const adapter = getLayerAdapter(layer);
|
|
20
26
|
const output = await adapter.prepareLayer(layer, dataView, adapterContext);
|
|
21
27
|
return { layerId, dataView, output };
|
|
@@ -84,7 +90,16 @@ export function useLayersPrepare(layerExecutions, layerDataViews, dataStatus, co
|
|
|
84
90
|
promise: dataStatus === "success" && layerExecutionsWithDataViews.length > 0
|
|
85
91
|
? () => prepareAllLayers(layerExecutionsWithDataViews, layerDataViews, createAdapterContext)
|
|
86
92
|
: undefined,
|
|
87
|
-
}, [
|
|
93
|
+
}, [
|
|
94
|
+
backend,
|
|
95
|
+
workspace,
|
|
96
|
+
dataViewsFingerprint,
|
|
97
|
+
layersStructureFingerprint,
|
|
98
|
+
intl,
|
|
99
|
+
// element values are number-formatted with the separators while preparing
|
|
100
|
+
config?.separators?.thousand,
|
|
101
|
+
config?.separators?.decimal,
|
|
102
|
+
]);
|
|
88
103
|
const layerOutputs = useMemo(() => {
|
|
89
104
|
const map = new Map();
|
|
90
105
|
if (result) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGeoPushData.d.ts","sourceRoot":"","sources":["../../../../src/next/hooks/pushData/useGeoPushData.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiC,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAEH,KAAK,gBAAgB,EACrB,KAAK,SAAS,EAGjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAKnE,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAKhE,UAAU,cAAc;IACpB,gBAAgB,EAAE,iBAAiB,CAAC;IACpC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CACpC;AAED;;;;GAIG;AACH,UAAU,cAAc;IACpB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CACxC;AAED,UAAU,qBAAqB,CAAC,MAAM,SAAS,cAAc,EAAE,cAAc,SAAS,cAAc;IAChG,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,cAAc,CAAC;IACvC,YAAY,EAAE,YAAY,CAAC;CAC9B;AAOD,wBAAgB,kCAAkC,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"useGeoPushData.d.ts","sourceRoot":"","sources":["../../../../src/next/hooks/pushData/useGeoPushData.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiC,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAEH,KAAK,gBAAgB,EACrB,KAAK,SAAS,EAGjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAKnE,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAKhE,UAAU,cAAc;IACpB,gBAAgB,EAAE,iBAAiB,CAAC;IACpC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CACpC;AAED;;;;GAIG;AACH,UAAU,cAAc;IACpB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CACxC;AAED,UAAU,qBAAqB,CAAC,MAAM,SAAS,cAAc,EAAE,cAAc,SAAS,cAAc;IAChG,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,cAAc,CAAC;IACvC,YAAY,EAAE,YAAY,CAAC;CAC9B;AAOD,wBAAgB,kCAAkC,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAiB3G;AA+BD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,SAAS,cAAc,EAAE,cAAc,SAAS,cAAc,EAC/F,aAAa,EAAE,cAAc,GAAG,IAAI,EACpC,YAAY,EAAE,aAAa,EAC3B,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,EAAE,qBAAqB,CAAC,MAAM,EAAE,cAAc,CAAC,GAC5F,IAAI,CA2EN"}
|
|
@@ -15,6 +15,7 @@ export function sortColorAssignmentsAlphabetically(colorAssignments) {
|
|
|
15
15
|
.map((assignment, index) => ({
|
|
16
16
|
assignment,
|
|
17
17
|
index,
|
|
18
|
+
// sorted by the raw element value, number-formatted values do not sort as numbers
|
|
18
19
|
name: getMappingHeaderName(assignment.headerItem) ?? "",
|
|
19
20
|
}))
|
|
20
21
|
.sort((left, right) => {
|
|
@@ -18,11 +18,11 @@ export interface IAreaAreaColor {
|
|
|
18
18
|
* If segments exist, uses segment-based coloring. Otherwise, uses color measure values for gradients.
|
|
19
19
|
*
|
|
20
20
|
* @param colorData - Array of color measure values
|
|
21
|
-
* @param
|
|
21
|
+
* @param segmentUris - Array of segment element URIs
|
|
22
22
|
* @param colorStrategy - Color strategy to use
|
|
23
23
|
* @returns Array of area colors matching the data
|
|
24
24
|
*
|
|
25
25
|
* @internal
|
|
26
26
|
*/
|
|
27
|
-
export declare function getAreaAreaColors(colorData: number[],
|
|
27
|
+
export declare function getAreaAreaColors(colorData: number[], segmentUris: string[], colorStrategy: IColorStrategy | null): IAreaAreaColor[];
|
|
28
28
|
//# sourceMappingURL=palette.d.ts.map
|
|
@@ -17,19 +17,19 @@ function mapPushpinColorsToAreas(pushpinColors) {
|
|
|
17
17
|
* If segments exist, uses segment-based coloring. Otherwise, uses color measure values for gradients.
|
|
18
18
|
*
|
|
19
19
|
* @param colorData - Array of color measure values
|
|
20
|
-
* @param
|
|
20
|
+
* @param segmentUris - Array of segment element URIs
|
|
21
21
|
* @param colorStrategy - Color strategy to use
|
|
22
22
|
* @returns Array of area colors matching the data
|
|
23
23
|
*
|
|
24
24
|
* @internal
|
|
25
25
|
*/
|
|
26
|
-
export function getAreaAreaColors(colorData,
|
|
26
|
+
export function getAreaAreaColors(colorData, segmentUris, colorStrategy) {
|
|
27
27
|
if (!colorStrategy) {
|
|
28
28
|
return [{ fill: DEFAULT_AREA_FILL_COLOR }];
|
|
29
29
|
}
|
|
30
|
-
if (
|
|
30
|
+
if (segmentUris.length > 0) {
|
|
31
31
|
// Segment-based coloring should provide a stable color per category.
|
|
32
|
-
const pushpinColors = getPushpinColors([],
|
|
32
|
+
const pushpinColors = getPushpinColors([], segmentUris, colorStrategy);
|
|
33
33
|
return mapPushpinColorsToAreas(pushpinColors);
|
|
34
34
|
}
|
|
35
35
|
if (colorData.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformation.d.ts","sourceRoot":"","sources":["../../../../../src/next/layers/area/data/transformation.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,oBAAoB,EAGzB,KAAK,aAAa,EAKrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGpE,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAC/F,OAAO,EAAE,KAAK,YAAY,EAAqB,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"transformation.d.ts","sourceRoot":"","sources":["../../../../../src/next/layers/area/data/transformation.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,oBAAoB,EAGzB,KAAK,aAAa,EAKrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGpE,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAC/F,OAAO,EAAE,KAAK,YAAY,EAAqB,MAAM,gCAAgC,CAAC;AAuRtF;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC7B,EAAE,EAAE,cAAc,EAClB,iBAAiB,EAAE,MAAM,EACzB,gBAAgB,EAAE,MAAM,GACzB,YAAY,CAmCd;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACnC,aAAa,EAAE,cAAc,EAAE,EAC/B,OAAO,EAAE,YAAY,GACtB,iBAAiB,CAWnB;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,GAAG;IACvE,KAAK,EAAE,aAAa,EAAE,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACvC,aAAa,EAAE,kBAAkB,CAAC;IAClC,kBAAkB,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACnD,oBAAoB,EAAE,kBAAkB,GAAG,SAAS,CAAC;CACxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CACzC,EAAE,EAAE,cAAc,EAClB,OAAO,EAAE,YAAY,GACtB,0BAA0B,CAkC5B"}
|
|
@@ -110,7 +110,8 @@ function processAreaBucket(ctx) {
|
|
|
110
110
|
if (areaIndex === undefined || !areaBucket) {
|
|
111
111
|
return undefined;
|
|
112
112
|
}
|
|
113
|
-
|
|
113
|
+
// area identifiers are matched against map features, so they keep the raw element value
|
|
114
|
+
const { data, uris } = getAttributeDataAndUris(attributeHeaderItems, areaIndex, emptyHeaderString, nullHeaderString, false);
|
|
114
115
|
return {
|
|
115
116
|
index: areaBucket.index,
|
|
116
117
|
name: areaBucket.name,
|
|
@@ -175,9 +175,9 @@ export function applyCurrentColorsToAreaOutputSource(output, dataView, context)
|
|
|
175
175
|
const colorStrategy = getAreaColorStrategy(colorPalette, colorMapping, output.geoData, dataView);
|
|
176
176
|
const areaIdentifiers = output.geoData.area?.data ?? [];
|
|
177
177
|
const areaUris = output.geoData.area?.uris ?? [];
|
|
178
|
-
const
|
|
178
|
+
const segmentUris = (output.geoData.segment?.uris ?? []).map((uri) => uri ?? EMPTY_SEGMENT_VALUE);
|
|
179
179
|
const colorData = output.geoData.color?.data ?? [];
|
|
180
|
-
const areaColors = getAreaAreaColors(colorData,
|
|
180
|
+
const areaColors = getAreaAreaColors(colorData, segmentUris, colorStrategy);
|
|
181
181
|
const fillByKey = new Map();
|
|
182
182
|
for (let i = 0; i < areaIdentifiers.length; i++) {
|
|
183
183
|
const areaIdentifier = areaIdentifiers[i];
|
|
@@ -245,7 +245,7 @@ function createAreaFeatures({ geoData, colorStrategy, features, tooltipAttrIds,
|
|
|
245
245
|
const segmentUris = (segment?.uris ?? []).map((uri) => uri ?? EMPTY_SEGMENT_VALUE);
|
|
246
246
|
const colorData = color?.data ?? [];
|
|
247
247
|
const colorFormat = color?.format ?? "";
|
|
248
|
-
const areaColors = getAreaAreaColors(colorData,
|
|
248
|
+
const areaColors = getAreaAreaColors(colorData, segmentUris, colorStrategy);
|
|
249
249
|
const featureIndex = buildFeatureIndex(features);
|
|
250
250
|
// Aggregate by unique area to prevent geometry duplication
|
|
251
251
|
const aggregatedAreas = aggregateByUniqueArea(areaIdentifiers, areaUris, segmentData, segmentUris, colorData, tooltipTextData, tooltipTextUris, areaColors, segmentTitle);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"computeLegend.d.ts","sourceRoot":"","sources":["../../../../src/next/layers/common/computeLegend.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"computeLegend.d.ts","sourceRoot":"","sources":["../../../../src/next/layers/common/computeLegend.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AA4BpE;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IAClC;;OAEG;IACH,SAAS,EAAE,SAAS,GAAG,MAAM,CAAC;IAE9B;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CACzB,OAAO,EAAE,cAAc,EACvB,aAAa,EAAE,cAAc,EAC7B,OAAO,EAAE,qBAAqB,GAC/B,gBAAgB,CA6ClB"}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
// (C) 2025-2026 GoodData Corporation
|
|
2
2
|
import { isResultAttributeHeader } from "@gooddata/sdk-model";
|
|
3
3
|
import { compareAlphabetically, compareLexicographically } from "../../utils/alphabeticalSorting.js";
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Sorts legend items by their raw element value: the displayed name can be number-formatted, and such
|
|
6
|
+
* values do not sort as numbers ("1,000" would go before "200").
|
|
7
|
+
*/
|
|
8
|
+
function sortLegendItemsAlphabetically(items, rawNameByUri) {
|
|
9
|
+
// empty and null elements have no raw value to sort by, they sort by their displayed placeholder
|
|
10
|
+
const sortName = (item) => rawNameByUri.get(item.uri) || item.name;
|
|
5
11
|
return [...items].sort((left, right) => {
|
|
6
|
-
const nameComparison = compareAlphabetically(left
|
|
12
|
+
const nameComparison = compareAlphabetically(sortName(left), sortName(right));
|
|
7
13
|
if (nameComparison !== 0) {
|
|
8
14
|
return nameComparison;
|
|
9
15
|
}
|
|
@@ -33,11 +39,13 @@ export function computeLegend(geoData, colorStrategy, options) {
|
|
|
33
39
|
let items = [];
|
|
34
40
|
if (geoData.segment) {
|
|
35
41
|
const assignmentIndexByUri = new Map();
|
|
42
|
+
const rawNameByUri = new Map();
|
|
36
43
|
colorStrategy.getColorAssignment().forEach((assignment, assignmentIndex) => {
|
|
37
44
|
if (isResultAttributeHeader(assignment.headerItem)) {
|
|
38
|
-
const uri = assignment.headerItem.attributeHeaderItem
|
|
45
|
+
const { uri, name } = assignment.headerItem.attributeHeaderItem;
|
|
39
46
|
if (uri && !assignmentIndexByUri.has(uri)) {
|
|
40
47
|
assignmentIndexByUri.set(uri, assignmentIndex);
|
|
48
|
+
rawNameByUri.set(uri, name);
|
|
41
49
|
}
|
|
42
50
|
}
|
|
43
51
|
});
|
|
@@ -59,7 +67,7 @@ export function computeLegend(geoData, colorStrategy, options) {
|
|
|
59
67
|
isVisible: true,
|
|
60
68
|
};
|
|
61
69
|
});
|
|
62
|
-
items = sortLegendItemsAlphabetically(items);
|
|
70
|
+
items = sortLegendItemsAlphabetically(items, rawNameByUri);
|
|
63
71
|
}
|
|
64
72
|
const available = {
|
|
65
73
|
hasCategoryLegend: items.length > 0,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { DataViewFacade } from "@gooddata/sdk-ui";
|
|
2
|
+
import { type IGeoAdapterContext } from "../registry/adapterTypes.js";
|
|
3
|
+
/**
|
|
4
|
+
* Gives element values of attributes with a number format (numeric computed attributes) their formatted
|
|
5
|
+
* name, so that location, segment, tooltip and legend texts derived from the data view show it.
|
|
6
|
+
*/
|
|
7
|
+
export declare function formatAttributeValues(dataView: DataViewFacade, context: IGeoAdapterContext): DataViewFacade;
|
|
8
|
+
//# sourceMappingURL=formatAttributeValues.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatAttributeValues.d.ts","sourceRoot":"","sources":["../../../../src/next/layers/common/formatAttributeValues.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAsD,MAAM,kBAAkB,CAAC;AAEtG,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEtE;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,kBAAkB,GAAG,cAAc,CAI3G"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// (C) 2026 GoodData Corporation
|
|
2
|
+
import { DataViewFacade, createNumberFormatter, formatAttributeHeaderValues } from "@gooddata/sdk-ui";
|
|
3
|
+
/**
|
|
4
|
+
* Gives element values of attributes with a number format (numeric computed attributes) their formatted
|
|
5
|
+
* name, so that location, segment, tooltip and legend texts derived from the data view show it.
|
|
6
|
+
*/
|
|
7
|
+
export function formatAttributeValues(dataView, context) {
|
|
8
|
+
return DataViewFacade.for(formatAttributeHeaderValues(dataView.dataView, createNumberFormatter(context.config?.separators)));
|
|
9
|
+
}
|
|
@@ -12,6 +12,9 @@ export declare function getSegmentDataAndUris(attributeHeaderItems: IResultHeade
|
|
|
12
12
|
* Extracts attribute data and raw URIs from attribute header items.
|
|
13
13
|
* Unlike `getSegmentDataAndUris`, this preserves raw URI values without
|
|
14
14
|
* substituting `EMPTY_SEGMENT_VALUE` for nulls.
|
|
15
|
+
*
|
|
16
|
+
* @param useFormattedName - read the formatted element value (for values shown to the user); pass false
|
|
17
|
+
* for values used to identify something, e.g. area identifiers matched against map features
|
|
15
18
|
*/
|
|
16
|
-
export declare function getAttributeDataAndUris(attributeHeaderItems: IResultHeader[][], dataIndex: number, emptyHeaderString: string, nullHeaderString: string): ISegmentData;
|
|
19
|
+
export declare function getAttributeDataAndUris(attributeHeaderItems: IResultHeader[][], dataIndex: number, emptyHeaderString: string, nullHeaderString: string, useFormattedName?: boolean): ISegmentData;
|
|
17
20
|
//# sourceMappingURL=headerItemUtils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headerItemUtils.d.ts","sourceRoot":"","sources":["../../../../src/next/layers/common/headerItemUtils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAA2B,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"headerItemUtils.d.ts","sourceRoot":"","sources":["../../../../src/next/layers/common/headerItemUtils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAA2B,MAAM,qBAAqB,CAAC;AAKlF,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACjC,oBAAoB,EAAE,aAAa,EAAE,EAAE,EACvC,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,gBAAgB,EAAE,MAAM,GACzB,YAAY,CAkBd;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACnC,oBAAoB,EAAE,aAAa,EAAE,EAAE,EACvC,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,gBAAgB,EAAE,MAAM,EACxB,gBAAgB,UAAO,GACxB,YAAY,CAoBd"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// (C) 2025-2026 GoodData Corporation
|
|
2
2
|
import { isResultAttributeHeader } from "@gooddata/sdk-model";
|
|
3
|
+
import { getAttributeHeaderItemName } from "@gooddata/sdk-ui";
|
|
3
4
|
import { EMPTY_SEGMENT_VALUE } from "../pushpin/constants.js";
|
|
4
5
|
/**
|
|
5
6
|
* Extracts segment data and URIs from attribute header items.
|
|
@@ -9,7 +10,8 @@ export function getSegmentDataAndUris(attributeHeaderItems, dataIndex, emptyHead
|
|
|
9
10
|
const headerItems = attributeHeaderItems[dataIndex];
|
|
10
11
|
return headerItems.reduce((result, headerItem) => {
|
|
11
12
|
if (headerItem && isResultAttributeHeader(headerItem)) {
|
|
12
|
-
const { uri
|
|
13
|
+
const { uri } = headerItem.attributeHeaderItem;
|
|
14
|
+
const name = getAttributeHeaderItemName(headerItem.attributeHeaderItem);
|
|
13
15
|
const displayName = name ?? nullHeaderString;
|
|
14
16
|
const finalName = name === "" ? emptyHeaderString : displayName;
|
|
15
17
|
return {
|
|
@@ -24,12 +26,18 @@ export function getSegmentDataAndUris(attributeHeaderItems, dataIndex, emptyHead
|
|
|
24
26
|
* Extracts attribute data and raw URIs from attribute header items.
|
|
25
27
|
* Unlike `getSegmentDataAndUris`, this preserves raw URI values without
|
|
26
28
|
* substituting `EMPTY_SEGMENT_VALUE` for nulls.
|
|
29
|
+
*
|
|
30
|
+
* @param useFormattedName - read the formatted element value (for values shown to the user); pass false
|
|
31
|
+
* for values used to identify something, e.g. area identifiers matched against map features
|
|
27
32
|
*/
|
|
28
|
-
export function getAttributeDataAndUris(attributeHeaderItems, dataIndex, emptyHeaderString, nullHeaderString) {
|
|
33
|
+
export function getAttributeDataAndUris(attributeHeaderItems, dataIndex, emptyHeaderString, nullHeaderString, useFormattedName = true) {
|
|
29
34
|
const headerItems = attributeHeaderItems[dataIndex];
|
|
30
35
|
return headerItems.reduce((result, headerItem) => {
|
|
31
36
|
if (headerItem && isResultAttributeHeader(headerItem)) {
|
|
32
|
-
const { uri
|
|
37
|
+
const { uri } = headerItem.attributeHeaderItem;
|
|
38
|
+
const name = useFormattedName
|
|
39
|
+
? getAttributeHeaderItemName(headerItem.attributeHeaderItem)
|
|
40
|
+
: headerItem.attributeHeaderItem.name;
|
|
33
41
|
const displayName = name ?? nullHeaderString;
|
|
34
42
|
const finalName = name === "" ? emptyHeaderString : displayName;
|
|
35
43
|
return {
|
|
@@ -42,10 +42,10 @@ type ColorPaletteMapping = {
|
|
|
42
42
|
[itemName: string]: string[];
|
|
43
43
|
};
|
|
44
44
|
/**
|
|
45
|
-
* Creates a mapping of segment
|
|
45
|
+
* Creates a mapping of segment element URIs to color palettes
|
|
46
46
|
*
|
|
47
47
|
* @param colorStrategy - Color strategy from visualization
|
|
48
|
-
* @returns Map of segment
|
|
48
|
+
* @returns Map of segment element URIs to color palettes
|
|
49
49
|
*
|
|
50
50
|
* @internal
|
|
51
51
|
*/
|
|
@@ -60,7 +60,7 @@ export declare function getColorPaletteMapping(colorStrategy: IColorStrategy): C
|
|
|
60
60
|
* - Color strategy
|
|
61
61
|
*
|
|
62
62
|
* @param colorValues - Array of color measure values (can be null)
|
|
63
|
-
* @param segmentValues - Array of segment
|
|
63
|
+
* @param segmentValues - Array of segment element URIs
|
|
64
64
|
* @param colorStrategy - Color strategy for palette generation
|
|
65
65
|
* @returns Array of pushpin color configurations
|
|
66
66
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palette.d.ts","sourceRoot":"","sources":["../../../../../src/next/layers/pushpin/coloring/palette.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,cAAc,EAAkD,MAAM,qBAAqB,CAAC;AAC1G,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE1F,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAuEvE;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,EAAE,OAAO,SAAI,GAAG,MAAM,EAAE,CAOzF;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,SAAI,GAAG,MAAM,CAG5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAiB7F;AAED;;GAEG;AACH,KAAK,mBAAmB,GAAG;IAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAAE,CAAC;AAE5D;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,cAAc,GAAG,mBAAmB,
|
|
1
|
+
{"version":3,"file":"palette.d.ts","sourceRoot":"","sources":["../../../../../src/next/layers/pushpin/coloring/palette.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,cAAc,EAAkD,MAAM,qBAAqB,CAAC;AAC1G,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE1F,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAuEvE;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,EAAE,OAAO,SAAI,GAAG,MAAM,EAAE,CAOzF;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,SAAI,GAAG,MAAM,CAG5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAiB7F;AAED;;GAEG;AACH,KAAK,mBAAmB,GAAG;IAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAAE,CAAC;AAE5D;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,cAAc,GAAG,mBAAmB,CAwBzF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC5B,WAAW,EAAE,aAAa,CAAC,MAAM,GAAG,IAAI,CAAC,EACzC,aAAa,EAAE,MAAM,EAAE,YAAK,EAC5B,aAAa,EAAE,cAAc,GAC9B,aAAa,EAAE,CA8DjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAwBtG"}
|