@gooddata/sdk-ui-geo 11.53.0-alpha.0 → 11.53.0-alpha.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.
@@ -1 +1 @@
1
- {"version":3,"file":"CoreGeoChart.d.ts","sourceRoot":"","sources":["../../src/core/CoreGeoChart.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAKxD,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAatE;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,kBAAkB,GAAG,qBAAqB,2CAM7E"}
1
+ {"version":3,"file":"CoreGeoChart.d.ts","sourceRoot":"","sources":["../../src/core/CoreGeoChart.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAKxD,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAStE;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,kBAAkB,GAAG,qBAAqB,2CAM7E"}
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { withEntireDataView } from "@gooddata/sdk-ui";
3
- import { ThemeContextProvider, withTheme } from "@gooddata/sdk-ui-theme-provider";
3
+ import { ThemeContextProvider } from "@gooddata/sdk-ui-theme-provider";
4
4
  import { GeoChartOptionsWrapper } from "./geoChart/GeoChartOptionsWrapper.js";
5
5
  import { geoValidatorHOC } from "./geoChart/GeoValidatorHOC.js";
6
6
  import { withMapboxToken } from "./MapboxTokenProvider.js";
7
- const WrappedCoreGeoChart = withTheme(withMapboxToken(geoValidatorHOC(withEntireDataView(GeoChartOptionsWrapper))));
7
+ const WrappedCoreGeoChart = withMapboxToken(geoValidatorHOC(withEntireDataView(GeoChartOptionsWrapper)));
8
8
  /**
9
9
  * @internal
10
10
  */
@@ -1,4 +1,4 @@
1
- import { PureComponent, type ReactElement } from "react";
1
+ import { type ReactElement } from "react";
2
2
  import { type WrappedComponentProps } from "react-intl";
3
3
  import { type IColorPalette, type ITheme } from "@gooddata/sdk-model";
4
4
  import { type IColorAssignment, type IDataVisualizationProps, type ILoadingInjectedProps } from "@gooddata/sdk-ui";
@@ -40,30 +40,20 @@ export interface IGeoChartInnerOptions {
40
40
  colorPalette: IColorPalette;
41
41
  }
42
42
  /**
43
- * Geo Chart react component
43
+ * Geo Chart react component.
44
+ *
45
+ * Renders the map itself (through `chartRenderer`) together with its legend (through `legendRenderer`),
46
+ * laid out according to the resolved legend position, and keeps the visibility of the individual legend
47
+ * items in sync with the chart. It is the innermost piece of the core geo chart: it expects an already
48
+ * resolved data view and the derived {@link IGeoChartInnerOptions} in its props, so it neither triggers
49
+ * an execution nor validates the data on its own.
50
+ *
51
+ * @param props - {@link IGeoChartInnerProps}; on top of the core geo chart props (`config`, `dataView`,
52
+ * `height`, `documentObj`, `chartRenderer`, `legendRenderer`, the `onCenterPositionChanged` /
53
+ * `onZoomChanged` / `onDrill` / `pushData` callbacks) it requires `geoChartOptions` prepared by
54
+ * `GeoChartOptionsWrapper` and `intl` injected by the wrapping HOC.
55
+ *
56
+ * @internal
44
57
  */
45
- export declare class GeoChartInner extends PureComponent<IGeoChartInnerProps, IGeoChartInnerState> {
46
- static getDerivedStateFromProps(nextProps: IGeoChartInnerProps, prevState: IGeoChartInnerState): Partial<IGeoChartInnerState> | null;
47
- private readonly throttledOnWindowResize;
48
- private readonly containerId;
49
- constructor(props: IGeoChartInnerProps);
50
- componentDidMount(): void;
51
- componentDidUpdate(): void;
52
- componentWillUnmount(): void;
53
- render(): ReactElement;
54
- private renderVisualizationContent;
55
- private syncWithLegendItemStates;
56
- private getContainerClassName;
57
- private getFlexDirection;
58
- private isFluidLegend;
59
- private onLegendItemClick;
60
- private getLegendPosition;
61
- private getLegendDetails;
62
- private getLegendProps;
63
- private getChartProps;
64
- private renderChart;
65
- private renderLegend;
66
- private onWindowResize;
67
- private updateConfigurationPanel;
68
- }
58
+ export declare function GeoChartInner(props: IGeoChartInnerProps): ReactElement;
69
59
  //# sourceMappingURL=GeoChartInner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GeoChartInner.d.ts","sourceRoot":"","sources":["../../../src/core/geoChart/GeoChartInner.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GeoChartInner.d.ts","sourceRoot":"","sources":["../../../src/core/geoChart/GeoChartInner.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAA+C,MAAM,OAAO,CAAC;AAKvF,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAKxD,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EACH,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAE5B,KAAK,qBAAqB,EAK7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACH,KAAK,cAAc,EAGnB,KAAK,0BAA0B,EAMlC,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAEjE,OAAO,EAA0B,KAAK,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AACxG,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAoCpE;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,uBAAuB;IAC/D,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,YAAY,CAAC;IAChE,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,4BAA4B,KAAK,YAAY,CAAC;IACvE,uBAAuB,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IACvD,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,eAAe,CAAC,EAAE,qBAAqB,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,GAAG,qBAAqB,GAAG,qBAAqB,CAAC;AAErG,MAAM,WAAW,mBAAmB;IAChC,kBAAkB,EAAE,OAAO,EAAE,CAAC;IAC9B,eAAe,EAAE,OAAO,CAAC;IACzB,mBAAmB,EAAE,gBAAgB,EAAE,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,OAAO,EAAE,QAAQ,CAAC;IAClB,aAAa,EAAE,0BAA0B,EAAE,CAAC;IAC5C,aAAa,EAAE,cAAc,CAAC;IAC9B,YAAY,EAAE,aAAa,CAAC;CAC/B;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,CA4UtE"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // (C) 2020-2026 GoodData Corporation
3
- import { PureComponent, Suspense, lazy } from "react";
3
+ import { Suspense, lazy, useEffect, useRef, useState } from "react";
4
4
  import cx from "classnames";
5
5
  import { defaultImport } from "default-import";
6
6
  import { throttle } from "lodash-es";
@@ -20,83 +20,102 @@ const GeoChartRendererLazy = lazy(() => import("./GeoChartRenderer.js").then((mo
20
20
  // In ESM, default exports of CJS modules are wrapped in default properties instead of being exposed directly.
21
21
  // https://github.com/microsoft/TypeScript/issues/52086#issuecomment-1385978414
22
22
  const Measure = defaultImport(ReactMeasure);
23
- function renderChart(props) {
23
+ function defaultChartRenderer(props) {
24
24
  return (_jsx(Suspense, { fallback: null, children: _jsx(GeoChartRendererLazy, { ...props }) }));
25
25
  }
26
- function renderLegend(props) {
26
+ function defaultLegendRenderer(props) {
27
27
  return (_jsx(IntlWrapper, { locale: props.locale, children: _jsx(IntlTranslationsProvider, { children: (translationProps) => (_jsx(GeoChartLegendRenderer, { ...props, numericSymbols: translationProps.numericSymbols })) }) }));
28
28
  }
29
29
  const DefaultGeoConfig = {
30
30
  mapboxToken: "",
31
31
  };
32
32
  /**
33
- * Geo Chart react component
33
+ * Geo Chart react component.
34
+ *
35
+ * Renders the map itself (through `chartRenderer`) together with its legend (through `legendRenderer`),
36
+ * laid out according to the resolved legend position, and keeps the visibility of the individual legend
37
+ * items in sync with the chart. It is the innermost piece of the core geo chart: it expects an already
38
+ * resolved data view and the derived {@link IGeoChartInnerOptions} in its props, so it neither triggers
39
+ * an execution nor validates the data on its own.
40
+ *
41
+ * @param props - {@link IGeoChartInnerProps}; on top of the core geo chart props (`config`, `dataView`,
42
+ * `height`, `documentObj`, `chartRenderer`, `legendRenderer`, the `onCenterPositionChanged` /
43
+ * `onZoomChanged` / `onDrill` / `pushData` callbacks) it requires `geoChartOptions` prepared by
44
+ * `GeoChartOptionsWrapper` and `intl` injected by the wrapping HOC.
45
+ *
46
+ * @internal
34
47
  */
35
- export class GeoChartInner extends PureComponent {
36
- static getDerivedStateFromProps(nextProps, prevState) {
37
- const { geoChartOptions } = nextProps;
38
- if (!geoChartOptions) {
39
- return null;
40
- }
41
- const { categoryItems, colorStrategy } = geoChartOptions;
48
+ export function GeoChartInner(props) {
49
+ const { config, geoChartOptions: geoChartOptionsProp, height } = props;
50
+ // lazily initialized so that v4() is called just once per instance and not on every render
51
+ const [containerId] = useState(() => `geo-${v4()}`);
52
+ // keeps the latest documentObj available to the throttled resize handler without re-creating it;
53
+ // written in an effect so that a render discarded by React cannot mutate it
54
+ const documentObjRef = useRef(props.documentObj);
55
+ useEffect(() => {
56
+ documentObjRef.current = props.documentObj;
57
+ });
58
+ const [state, setState] = useState(() => ({
59
+ enabledLegendItems: [],
60
+ showFluidLegend: shouldShowFluid(props.documentObj ?? document),
61
+ colorAssignmentItem: [],
62
+ }));
63
+ // replacement of getDerivedStateFromProps: adjusting the state during render is the sanctioned way
64
+ // of keeping the state in sync with the props; the value merged here is used by this very render
65
+ let currentState = state;
66
+ if (geoChartOptionsProp) {
67
+ const { categoryItems, colorStrategy } = geoChartOptionsProp;
42
68
  const colorAssignmentItem = colorStrategy.getColorAssignment();
43
- if (!isColorAssignmentItemChanged(prevState.colorAssignmentItem, colorAssignmentItem)) {
44
- return null;
69
+ if (isColorAssignmentItemChanged(state.colorAssignmentItem, colorAssignmentItem)) {
70
+ const enabledLegendItems = new Array(categoryItems.length).fill(true);
71
+ currentState = { ...state, enabledLegendItems, colorAssignmentItem };
72
+ setState((prev) => ({ ...prev, enabledLegendItems, colorAssignmentItem }));
45
73
  }
46
- return {
47
- enabledLegendItems: new Array(categoryItems.length).fill(true),
48
- colorAssignmentItem,
49
- };
50
74
  }
51
- throttledOnWindowResize;
52
- containerId = `geo-${v4()}`;
53
- constructor(props) {
54
- super(props);
55
- const { documentObj = document } = this.props;
56
- this.state = {
57
- enabledLegendItems: [],
58
- showFluidLegend: shouldShowFluid(documentObj),
59
- colorAssignmentItem: [],
75
+ const { enabledLegendItems, showFluidLegend } = currentState;
76
+ const updateConfigurationPanel = (geoChartOptions) => {
77
+ invariant(geoChartOptions, "illegal state - updating config with no geo options");
78
+ const { pushData } = props;
79
+ const { categoryItems, geoData, colorStrategy, colorPalette } = geoChartOptions;
80
+ const { hasCategoryLegend, hasColorLegend, hasSizeLegend } = getAvailableLegends(categoryItems, geoData);
81
+ const isLegendVisible = hasCategoryLegend || hasColorLegend || hasSizeLegend;
82
+ pushData?.({
83
+ propertiesMeta: {
84
+ // toggle legend section
85
+ legend_enabled: isLegendVisible,
86
+ },
87
+ colors: {
88
+ colorAssignments: colorStrategy.getColorAssignment(),
89
+ colorPalette,
90
+ },
91
+ });
92
+ };
93
+ // runs after every commit, matching the original componentDidMount + componentDidUpdate
94
+ useEffect(() => {
95
+ updateConfigurationPanel(geoChartOptionsProp);
96
+ });
97
+ // the throttled handler is created inside the effect so that it is guaranteed to live exactly as long as
98
+ // the registered listener does - unlike a useMemo cache, which React may throw away at any time
99
+ useEffect(() => {
100
+ const throttledOnWindowResize = throttle(() => {
101
+ setState((prev) => ({
102
+ ...prev,
103
+ showFluidLegend: shouldShowFluid(documentObjRef.current ?? document),
104
+ }));
105
+ }, 100);
106
+ window.addEventListener("resize", throttledOnWindowResize);
107
+ return () => {
108
+ throttledOnWindowResize.cancel();
109
+ window.removeEventListener("resize", throttledOnWindowResize);
60
110
  };
61
- this.throttledOnWindowResize = throttle(this.onWindowResize, 100);
62
- }
63
- componentDidMount() {
64
- this.updateConfigurationPanel(this.props.geoChartOptions);
65
- window.addEventListener("resize", this.throttledOnWindowResize);
66
- }
67
- componentDidUpdate() {
68
- this.updateConfigurationPanel(this.props.geoChartOptions);
69
- }
70
- componentWillUnmount() {
71
- this.throttledOnWindowResize.cancel();
72
- window.removeEventListener("resize", this.throttledOnWindowResize);
73
- }
74
- render() {
75
- const { height, config } = this.props;
76
- if (height !== undefined && !isAutoPositionWithPopup(config?.legend?.responsive)) {
77
- return this.renderVisualizationContent(undefined, height);
78
- }
79
- return (_jsx(Measure, { client: true, children: ({ measureRef, contentRect }) => {
80
- const { client: contentRectClient } = contentRect;
81
- return this.renderVisualizationContent(measureRef, contentRectClient?.height ?? 0, contentRect);
82
- } }));
83
- }
84
- renderVisualizationContent(measureRef, height, contentRect) {
85
- const { geoChartOptions: geoChartOptionsProp } = this.props;
86
- const geoChartOptions = this.syncWithLegendItemStates(geoChartOptionsProp);
87
- const legendDetails = this.getLegendDetails(this.getLegendPosition(), contentRect);
88
- const position = legendDetails ? legendDetails.position : LegendPosition["TOP"];
89
- const classes = this.getContainerClassName(position);
90
- const isLegendRenderedFirst = position === LegendPosition["TOP"] ||
91
- (position === LegendPosition["LEFT"] &&
92
- (!this.state.showFluidLegend || !!this.props.config?.respectLegendPosition));
93
- const legendComponent = this.renderLegend(height, position, geoChartOptions, contentRect);
94
- return (_jsxs("div", { className: classes, ref: measureRef, children: [isLegendRenderedFirst ? legendComponent : null, this.renderChart(geoChartOptions), isLegendRenderedFirst ? null : legendComponent] }));
95
- }
96
- syncWithLegendItemStates(geoChartOptions) {
111
+ }, []);
112
+ const responsiveInfo = getResponsiveInfo(config?.legend?.responsive);
113
+ const isFluidLegend = isAutoPositionWithPopup(responsiveInfo)
114
+ ? false
115
+ : isFluidLegendEnabled(responsiveInfo, showFluidLegend);
116
+ const syncWithLegendItemStates = (geoChartOptions) => {
97
117
  invariant(geoChartOptions, "illegal state - trying to sync legend with no geo options");
98
118
  const { categoryItems } = geoChartOptions;
99
- const { enabledLegendItems } = this.state;
100
119
  const withLegendItemStates = categoryItems.map((item, index) => ({
101
120
  ...item,
102
121
  isVisible: enabledLegendItems[index],
@@ -105,63 +124,53 @@ export class GeoChartInner extends PureComponent {
105
124
  ...geoChartOptions,
106
125
  categoryItems: withLegendItemStates,
107
126
  };
108
- }
109
- getContainerClassName(position) {
110
- const responsive = getResponsiveInfo(this.props?.config?.legend?.responsive) === true;
111
- const flexDirection = this.getFlexDirection(position);
127
+ };
128
+ const getFlexDirection = (position) => {
129
+ if (position === LegendPosition["TOP"] || position === LegendPosition["BOTTOM"] || isFluidLegend) {
130
+ return "column";
131
+ }
132
+ return "row";
133
+ };
134
+ const getContainerClassName = (position) => {
135
+ const responsive = getResponsiveInfo(config?.legend?.responsive) === true;
136
+ const flexDirection = getFlexDirection(position);
112
137
  return cx("viz-line-family-chart-wrap", "gd-geo-component", "s-gd-geo-component", {
113
138
  "responsive-legend": responsive,
114
139
  "non-responsive-legend": !responsive,
115
140
  [`flex-direction-${flexDirection}`]: true,
116
141
  "legend-position-bottom": position === LegendPosition["BOTTOM"],
117
- }, this.containerId);
118
- }
119
- getFlexDirection(position) {
120
- const isFluidLegend = this.isFluidLegend();
121
- if (position === LegendPosition["TOP"] || position === LegendPosition["BOTTOM"] || isFluidLegend) {
122
- return "column";
123
- }
124
- return "row";
125
- }
126
- isFluidLegend() {
127
- const { showFluidLegend } = this.state;
128
- const responsive = getResponsiveInfo(this.props?.config?.legend?.responsive);
129
- return isAutoPositionWithPopup(responsive)
130
- ? false
131
- : isFluidLegendEnabled(responsive, showFluidLegend);
132
- }
133
- onLegendItemClick = (item) => {
134
- const enabledLegendItems = this.state.enabledLegendItems.map((legendItem, index) => {
135
- if (index === item.legendIndex) {
136
- return !legendItem;
137
- }
138
- return legendItem;
139
- });
140
- this.setState({ enabledLegendItems });
142
+ }, containerId);
143
+ };
144
+ const onLegendItemClick = (item) => {
145
+ setState((prev) => ({
146
+ ...prev,
147
+ enabledLegendItems: prev.enabledLegendItems.map((legendItem, index) => {
148
+ if (index === item.legendIndex) {
149
+ return !legendItem;
150
+ }
151
+ return legendItem;
152
+ }),
153
+ }));
141
154
  };
142
- getLegendPosition() {
143
- const position = this.props.config?.legend?.position ?? LegendPosition["TOP"];
155
+ const getLegendPosition = () => {
156
+ const position = config?.legend?.position ?? LegendPosition["TOP"];
144
157
  const isSupportedLegend = SupportedLegendPositions.indexOf(position) > -1;
145
158
  return isSupportedLegend ? position : LegendPosition["TOP"];
146
- }
147
- getLegendDetails(position, contentRect) {
148
- const { geoChartOptions: geoChartOptionsProp, config } = this.props;
149
- const geoChartOptions = this.syncWithLegendItemStates(geoChartOptionsProp);
159
+ };
160
+ const getLegendDetails = (position, contentRect) => {
161
+ const geoChartOptions = syncWithLegendItemStates(geoChartOptionsProp);
150
162
  const { geoData } = geoChartOptions;
151
163
  const legendLabel = geoData?.segment?.name;
152
- const isFluidLegend = this.isFluidLegend();
153
164
  const legendDetailOptions = {
154
165
  showFluidLegend: isFluidLegend,
155
166
  contentRect,
156
167
  legendLabel,
157
168
  };
158
169
  return getCommonVisLegendDetails(position, getResponsiveInfo(config?.legend?.responsive), legendDetailOptions, config?.respectLegendPosition);
159
- }
160
- getLegendProps(height, position, geoChartOptions, contentRect) {
161
- const responsive = this.props.config?.legend?.responsive;
162
- const { locale } = this.props;
163
- const { enabledLegendItems } = this.state;
164
- const isFluidLegend = this.isFluidLegend();
170
+ };
171
+ const getLegendProps = (height, position, geoChartOptions, contentRect) => {
172
+ const responsive = config?.legend?.responsive;
173
+ const { locale } = props;
165
174
  const { geoData, colorStrategy, categoryItems } = geoChartOptions;
166
175
  const { segment } = geoData;
167
176
  const colorFormat = geoData.color?.format;
@@ -171,16 +180,16 @@ export class GeoChartInner extends PureComponent {
171
180
  geoData,
172
181
  };
173
182
  const colorLegendValue = colorStrategy.getColorByIndex(0);
174
- const legendDetails = this.getLegendDetails(position, contentRect);
183
+ const legendDetails = getLegendDetails(position, contentRect);
175
184
  let legendProps = {
176
185
  height,
177
186
  locale,
178
187
  position,
179
188
  responsive,
180
189
  isFluidLegend,
181
- onItemClick: this.onLegendItemClick,
190
+ onItemClick: onLegendItemClick,
182
191
  contentRect,
183
- containerId: this.containerId,
192
+ containerId,
184
193
  };
185
194
  if (legendDetails) {
186
195
  legendProps = {
@@ -203,9 +212,9 @@ export class GeoChartInner extends PureComponent {
203
212
  ...propsFromData,
204
213
  colorLegendValue,
205
214
  };
206
- }
207
- getChartProps(geoChartOptions) {
208
- const { config = DefaultGeoConfig, dataView, drillableItems = [], afterRender = () => { }, onCenterPositionChanged = () => { }, onDrill = () => { }, onZoomChanged = () => { }, intl, onError, } = this.props;
215
+ };
216
+ const getChartProps = (geoChartOptions) => {
217
+ const { config: configWithDefault = DefaultGeoConfig, dataView, drillableItems = [], afterRender = () => { }, onCenterPositionChanged = () => { }, onDrill = () => { }, onZoomChanged = () => { }, intl, onError, } = props;
209
218
  invariant(dataView, "invalid state - trying to render geo chart but there is no data to visualize");
210
219
  const { geoData, colorStrategy, categoryItems } = geoChartOptions;
211
220
  const segmentIndex = geoChartOptions.geoData.segment?.index;
@@ -213,7 +222,7 @@ export class GeoChartInner extends PureComponent {
213
222
  const drillConfig = { dataView, onDrill };
214
223
  const chartProps = {
215
224
  colorStrategy,
216
- config,
225
+ config: configWithDefault,
217
226
  dataView,
218
227
  drillableItems: drillablePredicates,
219
228
  drillConfig,
@@ -230,46 +239,40 @@ export class GeoChartInner extends PureComponent {
230
239
  .map((item) => item.uri);
231
240
  return {
232
241
  ...chartProps,
233
- config: { ...config, selectedSegmentItems },
242
+ config: { ...configWithDefault, selectedSegmentItems },
234
243
  };
235
244
  }
236
245
  return chartProps;
237
- }
238
- renderChart = (geoChartOptions) => {
239
- const { chartRenderer = renderChart } = this.props;
240
- const chartProps = this.getChartProps(geoChartOptions);
246
+ };
247
+ const renderChart = (geoChartOptions) => {
248
+ const { chartRenderer = defaultChartRenderer } = props;
249
+ const chartProps = getChartProps(geoChartOptions);
241
250
  return chartRenderer(chartProps);
242
251
  };
243
- renderLegend = (height, position, geoChartOptions, contentRect) => {
244
- const enabled = this.props.config?.legend?.enabled ?? true;
245
- const { legendRenderer = renderLegend } = this.props;
252
+ const renderLegend = (height, position, geoChartOptions, contentRect) => {
253
+ const enabled = config?.legend?.enabled ?? true;
254
+ const { legendRenderer = defaultLegendRenderer } = props;
246
255
  if (!enabled) {
247
256
  return null;
248
257
  }
249
- const legendProps = this.getLegendProps(height, position, geoChartOptions, contentRect);
258
+ const legendProps = getLegendProps(height, position, geoChartOptions, contentRect);
250
259
  return legendRenderer(legendProps);
251
260
  };
252
- onWindowResize = () => {
253
- const { documentObj = document } = this.props;
254
- this.setState({
255
- showFluidLegend: shouldShowFluid(documentObj),
256
- });
261
+ const renderVisualizationContent = (measureRef, height, contentRect) => {
262
+ const geoChartOptions = syncWithLegendItemStates(geoChartOptionsProp);
263
+ const legendDetails = getLegendDetails(getLegendPosition(), contentRect);
264
+ const position = legendDetails ? legendDetails.position : LegendPosition["TOP"];
265
+ const classes = getContainerClassName(position);
266
+ const isLegendRenderedFirst = position === LegendPosition["TOP"] ||
267
+ (position === LegendPosition["LEFT"] && (!showFluidLegend || !!config?.respectLegendPosition));
268
+ const legendComponent = renderLegend(height, position, geoChartOptions, contentRect);
269
+ return (_jsxs("div", { className: classes, ref: measureRef, children: [isLegendRenderedFirst ? legendComponent : null, renderChart(geoChartOptions), isLegendRenderedFirst ? null : legendComponent] }));
257
270
  };
258
- updateConfigurationPanel(geoChartOptions) {
259
- invariant(geoChartOptions, "illegal state - updating config with no geo options");
260
- const { pushData } = this.props;
261
- const { categoryItems, geoData, colorStrategy, colorPalette } = geoChartOptions;
262
- const { hasCategoryLegend, hasColorLegend, hasSizeLegend } = getAvailableLegends(categoryItems, geoData);
263
- const isLegendVisible = hasCategoryLegend || hasColorLegend || hasSizeLegend;
264
- pushData?.({
265
- propertiesMeta: {
266
- // toggle legend section
267
- legend_enabled: isLegendVisible,
268
- },
269
- colors: {
270
- colorAssignments: colorStrategy.getColorAssignment(),
271
- colorPalette,
272
- },
273
- });
271
+ if (height !== undefined && !isAutoPositionWithPopup(config?.legend?.responsive)) {
272
+ return renderVisualizationContent(undefined, height);
274
273
  }
274
+ return (_jsx(Measure, { client: true, children: ({ measureRef, contentRect }) => {
275
+ const { client: contentRectClient } = contentRect;
276
+ return renderVisualizationContent(measureRef, contentRectClient?.height ?? 0, contentRect);
277
+ } }));
275
278
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gooddata/sdk-ui-geo",
3
- "version": "11.53.0-alpha.0",
3
+ "version": "11.53.0-alpha.2",
4
4
  "description": "GoodData.UI SDK - Geo Charts",
5
5
  "license": "MIT",
6
6
  "author": "GoodData Corporation",
@@ -43,12 +43,12 @@
43
43
  "ts-invariant": "0.10.3",
44
44
  "tslib": "2.8.1",
45
45
  "uuid": "11.1.1",
46
- "@gooddata/sdk-model": "11.53.0-alpha.0",
47
- "@gooddata/sdk-backend-spi": "11.53.0-alpha.0",
48
- "@gooddata/sdk-ui": "11.53.0-alpha.0",
49
- "@gooddata/sdk-ui-kit": "11.53.0-alpha.0",
50
- "@gooddata/sdk-ui-theme-provider": "11.53.0-alpha.0",
51
- "@gooddata/sdk-ui-vis-commons": "11.53.0-alpha.0"
46
+ "@gooddata/sdk-backend-spi": "11.53.0-alpha.2",
47
+ "@gooddata/sdk-model": "11.53.0-alpha.2",
48
+ "@gooddata/sdk-ui": "11.53.0-alpha.2",
49
+ "@gooddata/sdk-ui-kit": "11.53.0-alpha.2",
50
+ "@gooddata/sdk-ui-theme-provider": "11.53.0-alpha.2",
51
+ "@gooddata/sdk-ui-vis-commons": "11.53.0-alpha.2"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@microsoft/api-documenter": "^7.17.0",
@@ -91,10 +91,10 @@
91
91
  "typescript": "5.9.3",
92
92
  "vitest": "4.1.8",
93
93
  "vitest-dom": "0.1.1",
94
- "@gooddata/eslint-config": "11.53.0-alpha.0",
95
- "@gooddata/oxlint-config": "11.53.0-alpha.0",
96
- "@gooddata/sdk-backend-mockingbird": "11.53.0-alpha.0",
97
- "@gooddata/stylelint-config": "11.53.0-alpha.0"
94
+ "@gooddata/eslint-config": "11.53.0-alpha.2",
95
+ "@gooddata/sdk-backend-mockingbird": "11.53.0-alpha.2",
96
+ "@gooddata/stylelint-config": "11.53.0-alpha.2",
97
+ "@gooddata/oxlint-config": "11.53.0-alpha.2"
98
98
  },
99
99
  "peerDependencies": {
100
100
  "react": "^18.0.0 || ^19.0.0",