Skip to content

Commit 799e0be

Browse files
committed
bfs: fix comparing chart configs
1 parent 6ac69e7 commit 799e0be

File tree

4 files changed

+122
-16
lines changed

4 files changed

+122
-16
lines changed

superset-frontend/plugins/plugin-chart-cartodiagram/src/components/ChartLayer.tsx

+2-8
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,7 @@ export class ChartLayer extends Layer {
179179

180180
const chartComponent = createChartComponent(
181181
this.chartVizType,
182-
// Seems like the registered chart components change some
183-
// props in-place, which leads to unwanted side effects. Therefore,
184-
// we only pass a copy.
185-
JSON.parse(JSON.stringify(feature)),
182+
feature,
186183
chartWidth,
187184
chartHeight,
188185
this.theme,
@@ -217,10 +214,7 @@ export class ChartLayer extends Layer {
217214

218215
const chartComponent = createChartComponent(
219216
this.chartVizType,
220-
// Seems like the registered chart components change some
221-
// props in-place, which leads to unwanted side effects. Therefore,
222-
// we only pass a copy.
223-
JSON.parse(JSON.stringify(chart.feature)),
217+
chart.feature,
224218
chartWidth,
225219
chartHeight,
226220
this.theme,

superset-frontend/plugins/plugin-chart-cartodiagram/src/components/OlChartMap.tsx

+3-7
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
MapViewConfigs,
3434
OlChartMapProps,
3535
} from '../types';
36+
import { isChartConfigEqual } from '../util/chartUtil';
3637

3738
/** The name to reference the chart layer */
3839
const CHART_LAYER_NAME = 'openlayers-chart-layer';
@@ -83,9 +84,7 @@ export const OlChartMap = (props: OlChartMapProps) => {
8384
*/
8485
useEffect(() => {
8586
setCurrentChartConfigs(oldCurrentChartConfigs => {
86-
if (
87-
JSON.stringify(chartConfigs) === JSON.stringify(oldCurrentChartConfigs)
88-
) {
87+
if (isChartConfigEqual(chartConfigs, oldCurrentChartConfigs)) {
8988
return oldCurrentChartConfigs;
9089
}
9190
return chartConfigs;
@@ -370,10 +369,7 @@ export const OlChartMap = (props: OlChartMapProps) => {
370369
chartLayer.setChartVizType(chartVizType, true);
371370
recreateCharts = true;
372371
}
373-
if (
374-
JSON.stringify(currentChartConfigs) !==
375-
JSON.stringify(chartLayer.chartConfigs)
376-
) {
372+
if (!isChartConfigEqual(currentChartConfigs, chartLayer.chartConfigs)) {
377373
chartLayer.setChartConfig(currentChartConfigs, true);
378374
recreateCharts = true;
379375
}

superset-frontend/plugins/plugin-chart-cartodiagram/src/util/chartUtil.tsx

+40-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import React from 'react';
2020

2121
import { SupersetTheme } from '@superset-ui/core';
22-
import { ChartConfigFeature } from '../types';
22+
import { ChartConfig, ChartConfigFeature } from '../types';
2323
import ChartWrapper from '../components/ChartWrapper';
2424

2525
/**
@@ -47,3 +47,42 @@ export const createChartComponent = (
4747
theme={chartTheme}
4848
/>
4949
);
50+
51+
/**
52+
* Simplifies a chart configuration by removing
53+
* non-serializable properties.
54+
*
55+
* @param config The chart configuration to simplify.
56+
* @returns The simplified chart configuration.
57+
*/
58+
export const simplifyConfig = (config: ChartConfig) => {
59+
const simplifiedConfig: ChartConfig = {
60+
type: config.type,
61+
features: config.features.map(f => ({
62+
type: f.type,
63+
geometry: f.geometry,
64+
properties: Object.keys(f.properties)
65+
.filter(k => k !== 'refs')
66+
.reduce((prev, cur) => ({ ...prev, [cur]: f.properties[cur] }), {}),
67+
})),
68+
};
69+
return simplifiedConfig;
70+
};
71+
72+
/**
73+
* Check if two chart configurations are equal (deep equality).
74+
*
75+
* @param configA The first chart config for comparison.
76+
* @param configB The second chart config for comparison.
77+
* @returns True, if configurations are equal. False otherwise.
78+
*/
79+
export const isChartConfigEqual = (
80+
configA: ChartConfig,
81+
configB: ChartConfig,
82+
) => {
83+
const simplifiedConfigA = simplifyConfig(configA);
84+
const simplifiedConfigB = simplifyConfig(configB);
85+
return (
86+
JSON.stringify(simplifiedConfigA) === JSON.stringify(simplifiedConfigB)
87+
);
88+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import { ChartConfig } from '../../src/types';
21+
import { isChartConfigEqual, simplifyConfig } from '../../src/util/chartUtil';
22+
23+
describe('chartUtil', () => {
24+
const configA: ChartConfig = {
25+
type: 'FeatureCollection',
26+
features: [
27+
{
28+
type: 'Feature',
29+
geometry: {
30+
type: 'Point',
31+
coordinates: [],
32+
},
33+
properties: {
34+
refs: 'foo',
35+
},
36+
},
37+
],
38+
};
39+
40+
const configB: ChartConfig = {
41+
type: 'FeatureCollection',
42+
features: [
43+
{
44+
type: 'Feature',
45+
geometry: {
46+
type: 'Point',
47+
coordinates: [],
48+
},
49+
properties: {
50+
refs: 'foo',
51+
foo: 'bar',
52+
},
53+
},
54+
],
55+
};
56+
57+
describe('simplifyConfig', () => {
58+
it('removes the refs property from a feature', () => {
59+
const simplifiedConfig = simplifyConfig(configA);
60+
const propKeys = Object.keys(simplifiedConfig.features[0].properties);
61+
62+
expect(propKeys).toHaveLength(0);
63+
});
64+
});
65+
66+
describe('isChartConfigEqual', () => {
67+
it('returns true, if configurations are equal', () => {
68+
const isEqual = isChartConfigEqual(configA, structuredClone(configA));
69+
expect(isEqual).toBe(true);
70+
});
71+
72+
it('returns false if configurations are not equal', () => {
73+
const isEqual = isChartConfigEqual(configA, configB);
74+
expect(isEqual).toBe(false);
75+
});
76+
});
77+
});

0 commit comments

Comments
 (0)