This is an automated email from the ASF dual-hosted git repository.
diegopucci pushed a commit to branch geido/fix/color-consistency-race-conditions
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to
refs/heads/geido/fix/color-consistency-race-conditions by this push:
new 0cc680f1ba chore(Dashboard): Store only shared label name references
0cc680f1ba is described below
commit 0cc680f1baab5abd8e0f878faf9445571b431538
Author: Diego Pucci <[email protected]>
AuthorDate: Wed Nov 6 18:33:13 2024 +0200
chore(Dashboard): Store only shared label name references
---
.../cypress/e2e/dashboard/editmode.test.ts | 2 +-
.../e2e/dashboard/shared_dashboard_functions.ts | 2 +-
.../src/shared-controls/sharedControls.tsx | 4 +-
.../test/color/CategoricalColorScale.test.ts | 5 +-
.../test/color/LabelsColorMapSingleton.test.ts | 43 ++++++++++--
.../plugins/legacy-plugin-chart-chord/src/Chord.js | 13 ++--
.../src/CountryMap.js | 7 +-
.../src/Histogram.jsx | 5 +-
.../legacy-plugin-chart-partition/src/Partition.js | 5 +-
.../plugins/legacy-plugin-chart-rose/src/Rose.js | 5 +-
.../src/SankeyLoop.js | 5 +-
.../legacy-plugin-chart-sankey/src/Sankey.js | 5 +-
.../legacy-preset-chart-nvd3/src/NVD3Vis.js | 4 +-
.../src/Gauge/transformProps.ts | 3 +-
.../src/chart/WordCloud.tsx | 8 +--
.../src/configureEncodable.ts | 3 +-
.../spec/fixtures/mockDashboardFormData.ts | 5 +-
.../spec/fixtures/mockDashboardState.js | 2 +-
.../src/dashboard/actions/dashboardState.js | 39 +++++------
.../dashboard/components/PropertiesModal/index.tsx | 6 +-
.../components/SyncDashboardState/index.tsx | 5 +-
.../FilterBarSettings/FilterBarSettings.test.tsx | 4 +-
.../FiltersConfigForm/FilterScope/utils.test.ts | 20 +++---
.../src/dashboard/containers/Chart.jsx | 12 ++--
superset-frontend/src/dashboard/types.ts | 4 +-
.../util/charts/getFormDataWithExtraFilters.ts | 15 ++---
.../ColorSchemeControl/ColorSchemeControl.test.tsx | 6 +-
.../controls/ColorSchemeControl/index.tsx | 8 +--
.../getFormDataFromDashboardContext.test.ts | 6 +-
superset-frontend/src/pages/Chart/index.tsx | 4 +-
.../src/types/DashboardContextForExplore.ts | 2 +-
superset-frontend/src/utils/colorScheme.ts | 77 +++++++++++++---------
superset/daos/dashboard.py | 4 +-
superset/dashboards/schemas.py | 4 +-
tests/integration_tests/dashboards/api_tests.py | 2 +-
tests/unit_tests/fixtures/assets_configs.py | 8 +--
tests/unit_tests/security/manager_test.py | 4 +-
37 files changed, 206 insertions(+), 150 deletions(-)
diff --git
a/superset-frontend/cypress-base/cypress/e2e/dashboard/editmode.test.ts
b/superset-frontend/cypress-base/cypress/e2e/dashboard/editmode.test.ts
index 9a42320d94..54d15a5562 100644
--- a/superset-frontend/cypress-base/cypress/e2e/dashboard/editmode.test.ts
+++ b/superset-frontend/cypress-base/cypress/e2e/dashboard/editmode.test.ts
@@ -110,7 +110,7 @@ function resetTabbedDashboard(go = false) {
...metadata,
color_scheme: '',
label_colors: {},
- shared_label_colors: {},
+ shared_label_colors: [],
});
cy.updateDashboard(r.id, {
certification_details: r.certification_details,
diff --git
a/superset-frontend/cypress-base/cypress/e2e/dashboard/shared_dashboard_functions.ts
b/superset-frontend/cypress-base/cypress/e2e/dashboard/shared_dashboard_functions.ts
index ad47116d34..b0f7853e94 100644
---
a/superset-frontend/cypress-base/cypress/e2e/dashboard/shared_dashboard_functions.ts
+++
b/superset-frontend/cypress-base/cypress/e2e/dashboard/shared_dashboard_functions.ts
@@ -91,7 +91,7 @@ export function prepareDashboardFilters(
refresh_frequency: 0,
color_scheme: '',
label_colors: {},
- shared_label_colors: {},
+ shared_label_colors: [],
color_scheme_domain: [],
cross_filters_enabled: false,
positions: {
diff --git
a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/sharedControls.tsx
b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/sharedControls.tsx
index 90e162aade..078d37a056 100644
---
a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/sharedControls.tsx
+++
b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/sharedControls.tsx
@@ -150,7 +150,7 @@ const linear_color_scheme:
SharedControlConfig<'ColorSchemeControl'> = {
hasDashboardColorScheme: dashboardId && !!state?.form_data?.color_scheme,
hasCustomLabelsColor:
Object.keys(state?.form_data?.label_colors || {}).length > 0,
- sharedLabelsColor: state?.form_data?.shared_label_colors || {},
+ sharedLabelsColors: state?.form_data?.shared_label_colors || [],
};
},
};
@@ -349,7 +349,7 @@ const color_scheme:
SharedControlConfig<'ColorSchemeControl'> = {
hasDashboardColorScheme: dashboardId && !!state?.form_data?.color_scheme,
hasCustomLabelsColor:
Object.keys(state?.form_data?.label_colors || {}).length > 0,
- sharedLabelsColor: state?.form_data?.shared_label_colors || {},
+ sharedLabelsColors: state?.form_data?.shared_label_colors || [],
};
},
};
diff --git
a/superset-frontend/packages/superset-ui-core/test/color/CategoricalColorScale.test.ts
b/superset-frontend/packages/superset-ui-core/test/color/CategoricalColorScale.test.ts
index 6a44a73298..96ae5ac753 100644
---
a/superset-frontend/packages/superset-ui-core/test/color/CategoricalColorScale.test.ts
+++
b/superset-frontend/packages/superset-ui-core/test/color/CategoricalColorScale.test.ts
@@ -29,7 +29,7 @@ describe('CategoricalColorScale', () => {
expect(CategoricalColorScale !== undefined).toBe(true);
});
- describe('new CategoricalColorScale(colors, forcedColors)', () => {
+ describe('new CategoricalColorScale(colors, forcedColors, colorScheme,
originalScheme)', () => {
it('can create new scale when forcedColors is not given', () => {
const scale = new CategoricalColorScale(['blue', 'red', 'green']);
expect(scale).toBeInstanceOf(CategoricalColorScale);
@@ -156,7 +156,7 @@ describe('CategoricalColorScale', () => {
expect(scale.chartLabelsColorMap.has(value)).toBe(false);
- scale.getColor(value, sliceId, colorScheme);
+ scale.getColor(value, sliceId, colorScheme, 'originalColorScheme');
expect(scale.chartLabelsColorMap.has(value)).toBe(true);
expect(scale.chartLabelsColorMap.get(value)).toBeDefined();
@@ -166,6 +166,7 @@ describe('CategoricalColorScale', () => {
expect.any(String),
sliceId,
colorScheme,
+ 'originalColorScheme',
);
const expectedColor = scale.chartLabelsColorMap.get(value);
diff --git
a/superset-frontend/packages/superset-ui-core/test/color/LabelsColorMapSingleton.test.ts
b/superset-frontend/packages/superset-ui-core/test/color/LabelsColorMapSingleton.test.ts
index b93a416e7f..1b42dd7484 100644
---
a/superset-frontend/packages/superset-ui-core/test/color/LabelsColorMapSingleton.test.ts
+++
b/superset-frontend/packages/superset-ui-core/test/color/LabelsColorMapSingleton.test.ts
@@ -92,11 +92,17 @@ describe('LabelsColorMap', () => {
expect(Object.fromEntries(colorMap)).toEqual({ b: 'green' });
});
- it('should do nothing when source is not dashboard', () => {
+ it('should set a new color only when source is dashboard', () => {
const labelsColorMap = getLabelsColorMap();
labelsColorMap.source = LabelsColorMapSource.Explore;
labelsColorMap.addSlice('a', 'red', 1);
- expect(Object.fromEntries(labelsColorMap.chartsLabelsMap)).toEqual({});
+ const colorMap = labelsColorMap.getColorMap();
+ expect(Object.fromEntries(colorMap)).toEqual({});
+
+ labelsColorMap.source = LabelsColorMapSource.Dashboard;
+ labelsColorMap.addSlice('a', 'red', 1);
+ const colorMap2 = labelsColorMap.getColorMap();
+ expect(Object.fromEntries(colorMap2)).toEqual({ a: 'red' });
});
});
@@ -126,7 +132,7 @@ describe('LabelsColorMap', () => {
});
});
- describe('.updateColorMap(namespace, scheme)', () => {
+ describe('.updateColorMap(namespace, scheme, merge)', () => {
let categoricalNamespace: any;
let mockedNamespace: any;
let labelsColorMap: any;
@@ -141,6 +147,18 @@ describe('LabelsColorMap', () => {
};
});
+ it('should clear color map when not merge', () => {
+ labelsColorMap.addSlice('a', 'red', 1);
+ labelsColorMap.updateColorMap(mockedNamespace, 'testColors2', false);
+ expect(labelsColorMap.colorMap).toEqual(new Map([['a', 'mockColor']]));
+ });
+
+ it('should not clear color map when merge', () => {
+ labelsColorMap.addSlice('a', 'red', 1);
+ labelsColorMap.updateColorMap(mockedNamespace, 'testColors2', true);
+ expect(labelsColorMap.colorMap).not.toEqual(new Map());
+ });
+
it('should use provided color scheme', () => {
labelsColorMap.addSlice('a', 'red', 1);
labelsColorMap.updateColorMap(mockedNamespace, 'testColors2');
@@ -148,7 +166,7 @@ describe('LabelsColorMap', () => {
});
it('should fallback to original chart color scheme if no color scheme is
provided', () => {
- labelsColorMap.addSlice('a', 'red', 1, 'originalScheme');
+ labelsColorMap.addSlice('a', 'red', 1, 'currentScheme',
'originalScheme');
labelsColorMap.updateColorMap(mockedNamespace);
expect(mockedNamespace.getScale).toHaveBeenCalledWith('originalScheme');
});
@@ -181,6 +199,23 @@ describe('LabelsColorMap', () => {
});
});
+ it('should update only new labels in the color map when merge', () => {
+ labelsColorMap.colorMap = new Map();
+
+ labelsColorMap.addSlice('a', 'yellow', 1);
+ labelsColorMap.addSlice('b', 'green', 1);
+ labelsColorMap.addSlice('c', 'purple', 1);
+
+ labelsColorMap.updateColorMap(categoricalNamespace, 'testColors2', true);
+
+ const mergedColorMap = labelsColorMap.getColorMap();
+ expect(Object.fromEntries(mergedColorMap)).toEqual({
+ a: 'yellow',
+ b: 'green',
+ c: 'purple',
+ });
+ });
+
it('should use recycle colors', () => {
window.featureFlags = {
[FeatureFlag.UseAnalagousColors]: false,
diff --git a/superset-frontend/plugins/legacy-plugin-chart-chord/src/Chord.js
b/superset-frontend/plugins/legacy-plugin-chart-chord/src/Chord.js
index dc20f3d15f..bf3db9579d 100644
--- a/superset-frontend/plugins/legacy-plugin-chart-chord/src/Chord.js
+++ b/superset-frontend/plugins/legacy-plugin-chart-chord/src/Chord.js
@@ -54,7 +54,10 @@ function Chord(element, props) {
const { nodes, matrix } = data;
const f = getNumberFormatter(numberFormat);
const appliedScheme = colorScheme || ownColorScheme;
- const colorFn = CategoricalColorNamespace.getScale(appliedScheme,
ownColorScheme);
+ const colorFn = CategoricalColorNamespace.getScale(
+ appliedScheme,
+ ownColorScheme,
+ );
const outerRadius = Math.min(width, height) / 2 - 10;
const innerRadius = outerRadius - 24;
@@ -103,9 +106,7 @@ function Chord(element, props) {
.append('path')
.attr('id', (d, i) => `group${i}`)
.attr('d', arc)
- .style('fill', (d, i) =>
- colorFn(nodes[i], sliceId),
- );
+ .style('fill', (d, i) => colorFn(nodes[i], sliceId));
// Add a text label.
const groupText = group.append('text').attr('x', 6).attr('dy', 15);
@@ -133,9 +134,7 @@ function Chord(element, props) {
.on('mouseover', d => {
chord.classed('fade', p => p !== d);
})
- .style('fill', d =>
- colorFn(nodes[d.source.index], sliceId),
- )
+ .style('fill', d => colorFn(nodes[d.source.index], sliceId))
.attr('d', path);
// Add an elaborate mouseover title for each chord.
diff --git
a/superset-frontend/plugins/legacy-plugin-chart-country-map/src/CountryMap.js
b/superset-frontend/plugins/legacy-plugin-chart-country-map/src/CountryMap.js
index cbbbde8dfe..94b7b3f68a 100644
---
a/superset-frontend/plugins/legacy-plugin-chart-country-map/src/CountryMap.js
+++
b/superset-frontend/plugins/legacy-plugin-chart-country-map/src/CountryMap.js
@@ -17,7 +17,7 @@
* under the License.
*/
/* eslint-disable react/sort-prop-types */
-import d3, { color } from 'd3';
+import d3 from 'd3';
import PropTypes from 'prop-types';
import { extent as d3Extent } from 'd3-array';
import {
@@ -65,7 +65,10 @@ function CountryMap(element, props) {
.get(linearColorScheme)
.createLinearScale(d3Extent(data, v => v.metric));
const appliedScheme = colorScheme || ownColorScheme;
- const colorScale = CategoricalColorNamespace.getScale(appliedScheme,
ownColorScheme);
+ const colorScale = CategoricalColorNamespace.getScale(
+ appliedScheme,
+ ownColorScheme,
+ );
const colorMap = {};
data.forEach(d => {
diff --git
a/superset-frontend/plugins/legacy-plugin-chart-histogram/src/Histogram.jsx
b/superset-frontend/plugins/legacy-plugin-chart-histogram/src/Histogram.jsx
index 8edc544cce..ff35d8701c 100644
--- a/superset-frontend/plugins/legacy-plugin-chart-histogram/src/Histogram.jsx
+++ b/superset-frontend/plugins/legacy-plugin-chart-histogram/src/Histogram.jsx
@@ -77,7 +77,10 @@ class CustomHistogram extends PureComponent {
sliceId,
} = this.props;
const appliedScheme = colorScheme || ownColorScheme;
- const colorFn = CategoricalColorNamespace.getScale(appliedScheme,
ownColorScheme);
+ const colorFn = CategoricalColorNamespace.getScale(
+ appliedScheme,
+ ownColorScheme,
+ );
const keys = data.map(d => d.key);
const colorScale = scaleOrdinal({
domain: keys,
diff --git
a/superset-frontend/plugins/legacy-plugin-chart-partition/src/Partition.js
b/superset-frontend/plugins/legacy-plugin-chart-partition/src/Partition.js
index c58b0746c9..fdbbd813c1 100644
--- a/superset-frontend/plugins/legacy-plugin-chart-partition/src/Partition.js
+++ b/superset-frontend/plugins/legacy-plugin-chart-partition/src/Partition.js
@@ -132,7 +132,10 @@ function Icicle(element, props) {
const format = getNumberFormatter(numberFormat);
const timeFormat = getTimeFormatter(dateTimeFormat);
const appliedScheme = colorScheme || ownColorScheme;
- const colorFn = CategoricalColorNamespace.getScale(appliedScheme,
ownColorScheme);
+ const colorFn = CategoricalColorNamespace.getScale(
+ appliedScheme,
+ ownColorScheme,
+ );
div.selectAll('*').remove();
const tooltip = div.append('div').classed('partition-tooltip', true);
diff --git a/superset-frontend/plugins/legacy-plugin-chart-rose/src/Rose.js
b/superset-frontend/plugins/legacy-plugin-chart-rose/src/Rose.js
index 668e13445d..aa6acfa440 100644
--- a/superset-frontend/plugins/legacy-plugin-chart-rose/src/Rose.js
+++ b/superset-frontend/plugins/legacy-plugin-chart-rose/src/Rose.js
@@ -93,7 +93,10 @@ function Rose(element, props) {
const format = getNumberFormatter(numberFormat);
const timeFormat = getTimeFormatter(dateTimeFormat);
const appliedScheme = colorScheme || ownColorScheme;
- const colorFn = CategoricalColorNamespace.getScale(appliedScheme,
ownColorScheme);
+ const colorFn = CategoricalColorNamespace.getScale(
+ appliedScheme,
+ ownColorScheme,
+ );
d3.select('.nvtooltip').remove();
div.selectAll('*').remove();
diff --git
a/superset-frontend/plugins/legacy-plugin-chart-sankey-loop/src/SankeyLoop.js
b/superset-frontend/plugins/legacy-plugin-chart-sankey-loop/src/SankeyLoop.js
index 7eaa6a9629..24a6747296 100644
---
a/superset-frontend/plugins/legacy-plugin-chart-sankey-loop/src/SankeyLoop.js
+++
b/superset-frontend/plugins/legacy-plugin-chart-sankey-loop/src/SankeyLoop.js
@@ -85,7 +85,10 @@ function computeGraph(links) {
function SankeyLoop(element, props) {
const { data, width, height, colorScheme, ownColorScheme, sliceId } = props;
const appliedScheme = colorScheme || ownColorScheme;
- const colorFn = CategoricalColorNamespace.getScale(appliedScheme,
ownColorScheme);
+ const colorFn = CategoricalColorNamespace.getScale(
+ appliedScheme,
+ ownColorScheme,
+ );
const margin = { ...defaultMargin, ...props.margin };
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
diff --git a/superset-frontend/plugins/legacy-plugin-chart-sankey/src/Sankey.js
b/superset-frontend/plugins/legacy-plugin-chart-sankey/src/Sankey.js
index 6797d50f61..2e075d92af 100644
--- a/superset-frontend/plugins/legacy-plugin-chart-sankey/src/Sankey.js
+++ b/superset-frontend/plugins/legacy-plugin-chart-sankey/src/Sankey.js
@@ -69,7 +69,10 @@ function Sankey(element, props) {
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
const appliedScheme = colorScheme || ownColorScheme;
- const colorFn = CategoricalColorNamespace.getScale(appliedScheme,
ownColorScheme);
+ const colorFn = CategoricalColorNamespace.getScale(
+ appliedScheme,
+ ownColorScheme,
+ );
const sankey = d3Sankey()
.nodeWidth(15)
diff --git a/superset-frontend/plugins/legacy-preset-chart-nvd3/src/NVD3Vis.js
b/superset-frontend/plugins/legacy-preset-chart-nvd3/src/NVD3Vis.js
index 39f2f7cd91..293957f17a 100644
--- a/superset-frontend/plugins/legacy-preset-chart-nvd3/src/NVD3Vis.js
+++ b/superset-frontend/plugins/legacy-preset-chart-nvd3/src/NVD3Vis.js
@@ -660,9 +660,7 @@ function nvd3Vis(element, props) {
} else if (vizType !== 'bullet') {
const colorFn = getScale(appliedScheme, ownColorScheme);
chart.color(
- d =>
- d.color ||
- colorFn(cleanColorInput(d[colorKey]), sliceId),
+ d => d.color || colorFn(cleanColorInput(d[colorKey]), sliceId),
);
}
diff --git
a/superset-frontend/plugins/plugin-chart-echarts/src/Gauge/transformProps.ts
b/superset-frontend/plugins/plugin-chart-echarts/src/Gauge/transformProps.ts
index b624119148..9878705a15 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Gauge/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Gauge/transformProps.ts
@@ -171,6 +171,7 @@ export default function transformProps(
const name = groupbyLabels
.map(column => `${verboseMap[column] || column}:
${data_point[column]}`)
.join(', ');
+ const colorLabel = groupbyLabels.map(col => data_point[col] as string);
columnsLabelMap.set(
name,
groupbyLabels.map(col => data_point[col] as string),
@@ -179,7 +180,7 @@ export default function transformProps(
value: data_point[metricLabel] as number,
name,
itemStyle: {
- color: colorFn(index, sliceId),
+ color: colorFn(colorLabel, sliceId),
},
title: {
offsetCenter: [
diff --git
a/superset-frontend/plugins/plugin-chart-word-cloud/src/chart/WordCloud.tsx
b/superset-frontend/plugins/plugin-chart-word-cloud/src/chart/WordCloud.tsx
index 53bf98fe90..883ef5efe3 100644
--- a/superset-frontend/plugins/plugin-chart-word-cloud/src/chart/WordCloud.tsx
+++ b/superset-frontend/plugins/plugin-chart-word-cloud/src/chart/WordCloud.tsx
@@ -222,7 +222,7 @@ class WordCloud extends PureComponent<FullWordCloudProps,
WordCloudState> {
render() {
const { scaleFactor } = this.state;
- const { width, height, encoding, sliceId, colorScheme } = this.props;
+ const { width, height, encoding, sliceId } = this.props;
const { words } = this.state;
// @ts-ignore
@@ -250,11 +250,7 @@ class WordCloud extends PureComponent<FullWordCloudProps,
WordCloudState> {
fontSize={`${w.size}px`}
fontWeight={w.weight}
fontFamily={w.font}
- fill={colorFn(
- getValueFromDatum(w) as string,
- sliceId,
- colorScheme,
- )}
+ fill={colorFn(getValueFromDatum(w) as string, sliceId)}
textAnchor="middle"
transform={`translate(${w.x}, ${w.y}) rotate(${w.rotate})`}
>
diff --git
a/superset-frontend/plugins/plugin-chart-word-cloud/src/configureEncodable.ts
b/superset-frontend/plugins/plugin-chart-word-cloud/src/configureEncodable.ts
index 05a2041286..c18072d33c 100644
---
a/superset-frontend/plugins/plugin-chart-word-cloud/src/configureEncodable.ts
+++
b/superset-frontend/plugins/plugin-chart-word-cloud/src/configureEncodable.ts
@@ -72,8 +72,9 @@ const colorSchemeResolver: ColorSchemeResolver = ({
const colorScaleResolver: CategoricalColorScaleResolver = ({
name,
+ colorScheme,
namespace,
-} = {}) => CategoricalColorNamespace.getScale(name, namespace);
+} = {}) => CategoricalColorNamespace.getScale(name, colorScheme, namespace);
export default function configureEncodable() {
Encodable.setNumberFormatResolver(getNumberFormatter)
diff --git a/superset-frontend/spec/fixtures/mockDashboardFormData.ts
b/superset-frontend/spec/fixtures/mockDashboardFormData.ts
index a1adb18a7e..3f08980250 100644
--- a/superset-frontend/spec/fixtures/mockDashboardFormData.ts
+++ b/superset-frontend/spec/fixtures/mockDashboardFormData.ts
@@ -26,10 +26,7 @@ export const getDashboardFormData = (overrides: JsonObject =
{}) => ({
girl: '#FF69B4',
boy: '#ADD8E6',
},
- shared_label_colors: {
- boy: '#ADD8E6',
- girl: '#FF69B4',
- },
+ shared_label_colors: ['boy', 'girl'],
color_scheme: 'd3Category20b',
extra_filters: [
{
diff --git a/superset-frontend/spec/fixtures/mockDashboardState.js
b/superset-frontend/spec/fixtures/mockDashboardState.js
index 737e38aef5..42360cdc71 100644
--- a/superset-frontend/spec/fixtures/mockDashboardState.js
+++ b/superset-frontend/spec/fixtures/mockDashboardState.js
@@ -113,6 +113,6 @@ export const overwriteConfirmMetadata = {
slug: null,
owners: [],
json_metadata:
-
'{"timed_refresh_immune_slices":[],"expanded_slices":{},"refresh_frequency":0,"default_filters":"{}","color_scheme":"supersetColors","label_colors":{"0":"#FCC700","1":"#A868B7","15":"#3CCCCB","30":"#A38F79","45":"#8FD3E4","age":"#1FA8C9","Yes,":"#1FA8C9","Female":"#454E7C","Prefer":"#5AC189","No,":"#FF7F44","Male":"#666666","Prefer
not to say":"#E04355","Ph.D.":"#FCC700","associate\'s
degree":"#A868B7","bachelor\'s degree":"#3CCCCB","high school diploma or
equivalent (GED)":"#A38F7 [...]
+
'{"timed_refresh_immune_slices":[],"expanded_slices":{},"refresh_frequency":0,"default_filters":"{}","color_scheme":"supersetColors","label_colors":{"0":"#FCC700","1":"#A868B7","15":"#3CCCCB","30":"#A38F79","45":"#8FD3E4","age":"#1FA8C9","Yes,":"#1FA8C9","Female":"#454E7C","Prefer":"#5AC189","No,":"#FF7F44","Male":"#666666","Prefer
not to say":"#E04355","Ph.D.":"#FCC700","associate\'s
degree":"#A868B7","bachelor\'s degree":"#3CCCCB","high school diploma or
equivalent (GED)":"#A38F7 [...]
},
};
diff --git a/superset-frontend/src/dashboard/actions/dashboardState.js
b/superset-frontend/src/dashboard/actions/dashboardState.js
index f6b14f446e..95b6bf929c 100644
--- a/superset-frontend/src/dashboard/actions/dashboardState.js
+++ b/superset-frontend/src/dashboard/actions/dashboardState.js
@@ -55,7 +55,6 @@ import { getActiveFilters } from
'src/dashboard/util/activeDashboardFilters';
import { safeStringify } from 'src/utils/safeStringify';
import { logEvent } from 'src/logger/actions';
import { LOG_ACTIONS_CONFIRM_OVERWRITE_DASHBOARD_METADATA } from
'src/logger/LogUtils';
-import { areObjectsEqual } from 'src/reduxUtils';
import { UPDATE_COMPONENTS_PARENTS_LIST } from './dashboardLayout';
import {
saveChartConfiguration,
@@ -69,9 +68,10 @@ import getOverwriteItems from '../util/getOverwriteItems';
import {
applyColors,
isLabelsColorMapSynced,
- getLabelsColorMapEntries,
getColorSchemeDomain,
getColorNamespace,
+ getLabelsColorMapEntries,
+ getSharedLabels,
} from '../../utils/colorScheme';
export const SET_UNSAVED_CHANGES = 'SET_UNSAVED_CHANGES';
@@ -278,8 +278,8 @@ export function saveDashboardRequest(data, id, saveType) {
: [],
expanded_slices: data.metadata?.expanded_slices || {},
label_colors: data.metadata?.label_colors || {},
- shared_label_colors: getLabelsColorMapEntries(true),
- full_label_colors: getLabelsColorMapEntries(),
+ shared_label_colors: getSharedLabels(),
+ map_label_colors: getLabelsColorMapEntries(),
refresh_frequency: data.metadata?.refresh_frequency || 0,
timed_refresh_immune_slices:
data.metadata?.timed_refresh_immune_slices || [],
@@ -704,11 +704,19 @@ export const updateDashboardLabelsColor = () => async
(dispatch, getState) => {
const defaultScheme = categoricalSchemes.defaultKey;
const fallbackScheme = defaultScheme?.toString() || 'supersetColors';
const colorSchemeDomain = metadata?.color_scheme_domain || [];
+ const sharedLabels = metadata?.shared_label_colors;
+ let requiresUpdate = false;
try {
const updatedMetadata = { ...metadata };
let updatedScheme = metadata?.color_scheme;
+ // sanitize shared labels color map for backward compatibility
+ if (!Array.isArray(sharedLabels) && Object.keys(sharedLabels).length > 0) {
+ updatedMetadata.shared_label_colors = getSharedLabels();
+ requiresUpdate = true;
+ }
+
// Color scheme does not exist anymore, fallback to default
if (colorScheme && !colorSchemeRegistry) {
updatedScheme = fallbackScheme;
@@ -718,6 +726,7 @@ export const updateDashboardLabelsColor = () => async
(dispatch, getState) => {
dispatch(setColorScheme(updatedScheme));
// must re-apply colors from fresh labels color map
applyColors(updatedMetadata, true);
+ requiresUpdate = true;
}
// stored labels color map and applied might differ
@@ -729,8 +738,9 @@ export const updateDashboardLabelsColor = () => async
(dispatch, getState) => {
// re-apply the color map first
applyColors(updatedMetadata, false, true, !colorScheme);
// store the just applied labels color map
- updatedMetadata.shared_label_colors = getLabelsColorMapEntries(true);
- updatedMetadata.full_label_colors = getLabelsColorMapEntries();
+ updatedMetadata.shared_label_colors = getSharedLabels();
+ updatedMetadata.map_label_colors = getLabelsColorMapEntries();
+ requiresUpdate = true;
}
// the stored color domain registry and fresh might differ at this point
@@ -741,23 +751,10 @@ export const updateDashboardLabelsColor = () => async
(dispatch, getState) => {
if (!isRegistrySynced) {
updatedMetadata.color_scheme_domain = freshColorSchemeDomain;
+ requiresUpdate = true;
}
- if (
- !areObjectsEqual(
- metadata.color_scheme_domain,
- updatedMetadata.color_scheme_domain,
- ) ||
- !areObjectsEqual(
- metadata.shared_label_colors,
- updatedMetadata.shared_label_colors,
- ) ||
- !areObjectsEqual(
- metadata.full_label_colors,
- updatedMetadata.full_label_colors,
- ) ||
- metadata.color_scheme !== updatedMetadata.color_scheme
- ) {
+ if (requiresUpdate) {
await updateDashboardMetadata(id, updatedMetadata, dispatch);
}
} catch (error) {
diff --git
a/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx
b/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx
index f97fff94c8..5b1987937a 100644
--- a/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx
+++ b/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx
@@ -196,7 +196,7 @@ const PropertiesModal = ({
const metaDataCopy = omit(metadata, [
'positions',
'shared_label_colors',
- 'full_label_colors',
+ 'map_label_colors',
'color_scheme_domain',
]);
@@ -334,8 +334,8 @@ const PropertiesModal = ({
if (metadata?.shared_label_colors) {
delete metadata.shared_label_colors;
}
- if (metadata?.full_label_colors) {
- delete metadata.full_label_colors;
+ if (metadata?.map_label_colors) {
+ delete metadata.map_label_colors;
}
if (metadata?.color_scheme_domain) {
delete metadata.color_scheme_domain;
diff --git
a/superset-frontend/src/dashboard/components/SyncDashboardState/index.tsx
b/superset-frontend/src/dashboard/components/SyncDashboardState/index.tsx
index 0c178df3d8..174ec92d66 100644
--- a/superset-frontend/src/dashboard/components/SyncDashboardState/index.tsx
+++ b/superset-frontend/src/dashboard/components/SyncDashboardState/index.tsx
@@ -66,9 +66,8 @@ const SyncDashboardState: FC<Props> = ({ dashboardPageId })
=> {
>(
({ dashboardInfo, dashboardState, nativeFilters, dataMask }) => ({
labelsColor: dashboardInfo.metadata?.label_colors || EMPTY_OBJECT,
- labelsColorMap: dashboardInfo.metadata?.full_label_colors ||
EMPTY_OBJECT,
- sharedLabelsColorMap:
- dashboardInfo.metadata?.shared_label_colors || EMPTY_OBJECT,
+ labelsColorMap: dashboardInfo.metadata?.map_label_colors || EMPTY_OBJECT,
+ sharedLabelsColors: dashboardInfo.metadata?.shared_label_colors || [],
colorScheme: dashboardState?.colorScheme,
chartConfiguration:
dashboardInfo.metadata?.chart_configuration || EMPTY_OBJECT,
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBarSettings/FilterBarSettings.test.tsx
b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBarSettings/FilterBarSettings.test.tsx
index 5bdacdec1a..0e52e4def6 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBarSettings/FilterBarSettings.test.tsx
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBarSettings/FilterBarSettings.test.tsx
@@ -41,8 +41,8 @@ const initialState: { dashboardInfo: DashboardInfo } = {
color_namespace: '',
color_scheme_domain: [],
label_colors: {},
- shared_label_colors: {},
- full_label_colors: {},
+ shared_label_colors: [],
+ map_label_colors: {},
cross_filters_enabled: false,
},
json_metadata: '',
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/utils.test.ts
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/utils.test.ts
index 60ae8b8e5f..0657e4574c 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/utils.test.ts
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/utils.test.ts
@@ -485,7 +485,7 @@ describe('Ensure buildTree does not throw runtime errors
when encountering an in
Sports: '#8FD3E4',
Strategy: '#A1A6BD',
},
- shared_label_colors: {},
+ shared_label_colors: [],
color_scheme: 'supersetColors',
extra_filters: [
{
@@ -710,7 +710,7 @@ describe('Ensure buildTree does not throw runtime errors
when encountering an in
queryFields: {
metric: 'metrics',
},
- shared_label_colors: {},
+ shared_label_colors: [],
color_scheme: 'supersetColors',
extra_filters: [
{
@@ -759,7 +759,7 @@ describe('Ensure buildTree does not throw runtime errors
when encountering an in
queryFields: {
metric: 'metrics',
},
- shared_label_colors: {},
+ shared_label_colors: [],
color_scheme: 'supersetColors',
dashboardId: 9,
applied_time_extras: {},
@@ -3046,7 +3046,7 @@ describe('Ensure buildTree does not throw runtime errors
when encountering an in
groupby: 'groupby',
metrics: 'metrics',
},
- shared_label_colors: {},
+ shared_label_colors: [],
extra_filters: [
{
col: '__time_range',
@@ -3125,7 +3125,7 @@ describe('Ensure buildTree does not throw runtime errors
when encountering an in
groupby: 'groupby',
metrics: 'metrics',
},
- shared_label_colors: {},
+ shared_label_colors: [],
dashboardId: 9,
applied_time_extras: {},
where: '',
@@ -16514,7 +16514,7 @@ describe('Ensure buildTree does not throw runtime
errors when encountering an in
groupby: 'groupby',
metrics: 'metrics',
},
- shared_label_colors: {},
+ shared_label_colors: [],
extra_filters: [
{
col: '__time_range',
@@ -16661,7 +16661,7 @@ describe('Ensure buildTree does not throw runtime
errors when encountering an in
groupby: 'groupby',
metrics: 'metrics',
},
- shared_label_colors: {},
+ shared_label_colors: [],
dashboardId: 9,
applied_time_extras: {},
where: '',
@@ -17523,7 +17523,7 @@ describe('Ensure buildTree does not throw runtime
errors when encountering an in
Sports: '#8FD3E4',
Strategy: '#A1A6BD',
},
- shared_label_colors: {},
+ shared_label_colors: [],
extra_filters: [
{
col: '__time_range',
@@ -17678,7 +17678,7 @@ describe('Ensure buildTree does not throw runtime
errors when encountering an in
groupby: 'groupby',
metrics: 'metrics',
},
- shared_label_colors: {},
+ shared_label_colors: [],
extra_filters: [
{
col: '__time_range',
@@ -17715,7 +17715,7 @@ describe('Ensure buildTree does not throw runtime
errors when encountering an in
groupby: 'groupby',
metrics: 'metrics',
},
- shared_label_colors: {},
+ shared_label_colors: [],
dashboardId: 9,
applied_time_extras: {},
where: '',
diff --git a/superset-frontend/src/dashboard/containers/Chart.jsx
b/superset-frontend/src/dashboard/containers/Chart.jsx
index 3ea7c807f1..940cdaaa1f 100644
--- a/superset-frontend/src/dashboard/containers/Chart.jsx
+++ b/superset-frontend/src/dashboard/containers/Chart.jsx
@@ -59,10 +59,14 @@ function mapStateToProps(
const datasource =
(chart && chart.form_data && datasources[chart.form_data.datasource]) ||
PLACEHOLDER_DATASOURCE;
- const { colorScheme: appliedColorScheme, colorNamespace, datasetsStatus } =
dashboardState;
+ const {
+ colorScheme: appliedColorScheme,
+ colorNamespace,
+ datasetsStatus,
+ } = dashboardState;
const labelsColor = dashboardInfo?.metadata?.label_colors || {};
- const labelsColorMap = dashboardInfo?.metadata?.full_label_colors || {};
- const sharedLabelsColorMap = dashboardInfo?.metadata?.shared_label_colors ||
{};
+ const labelsColorMap = dashboardInfo?.metadata?.map_label_colors || {};
+ const sharedLabelsColors = dashboardInfo?.metadata?.shared_label_colors ||
[];
const ownColorScheme = chart.form_data?.color_scheme;
// note: this method caches filters if possible to prevent render cascades
const formData = getFormDataWithExtraFilters({
@@ -80,7 +84,7 @@ function mapStateToProps(
extraControls,
labelsColor,
labelsColorMap,
- sharedLabelsColorMap,
+ sharedLabelsColors,
});
formData.dashboardId = dashboardInfo.id;
diff --git a/superset-frontend/src/dashboard/types.ts
b/superset-frontend/src/dashboard/types.ts
index 6272c9a055..2b1bbf01e5 100644
--- a/superset-frontend/src/dashboard/types.ts
+++ b/superset-frontend/src/dashboard/types.ts
@@ -132,8 +132,8 @@ export type DashboardInfo = {
color_namespace: string;
color_scheme_domain: string[];
label_colors: JsonObject;
- shared_label_colors: JsonObject;
- full_label_colors: JsonObject;
+ shared_label_colors: string[];
+ map_label_colors: JsonObject;
cross_filters_enabled: boolean;
};
crossFiltersEnabled: boolean;
diff --git
a/superset-frontend/src/dashboard/util/charts/getFormDataWithExtraFilters.ts
b/superset-frontend/src/dashboard/util/charts/getFormDataWithExtraFilters.ts
index 6f16792ab5..2190318547 100644
--- a/superset-frontend/src/dashboard/util/charts/getFormDataWithExtraFilters.ts
+++ b/superset-frontend/src/dashboard/util/charts/getFormDataWithExtraFilters.ts
@@ -25,6 +25,7 @@ import {
import { ChartConfiguration, ChartQueryPayload } from 'src/dashboard/types';
import { getExtraFormData } from
'src/dashboard/components/nativeFilters/utils';
import { areObjectsEqual } from 'src/reduxUtils';
+import { isEqual } from 'lodash';
import getEffectiveExtraFilters from './getEffectiveExtraFilters';
import { getAllActiveFilters } from '../activeAllDashboardFilters';
@@ -46,7 +47,7 @@ export interface GetFormDataWithExtraFiltersArguments {
extraControls: Record<string, string | boolean | null>;
labelsColor?: Record<string, string>;
labelsColorMap?: Record<string, string>;
- sharedLabelsColorMap?: Record<string, string>;
+ sharedLabelsColors?: string[];
allSliceIds: number[];
}
@@ -66,7 +67,7 @@ export default function getFormDataWithExtraFilters({
extraControls,
labelsColor,
labelsColorMap,
- sharedLabelsColorMap,
+ sharedLabelsColors,
allSliceIds,
}: GetFormDataWithExtraFiltersArguments) {
// if dashboard metadata + filters have not changed, use cache if possible
@@ -81,12 +82,10 @@ export default function getFormDataWithExtraFilters({
areObjectsEqual(cachedFormData?.label_colors, labelsColor, {
ignoreUndefined: true,
}) &&
- areObjectsEqual(cachedFormData?.full_label_colors, labelsColorMap, {
- ignoreUndefined: true,
- }) &&
- areObjectsEqual(cachedFormData?.shared_label_colors, sharedLabelsColorMap,
{
+ areObjectsEqual(cachedFormData?.map_label_colors, labelsColorMap, {
ignoreUndefined: true,
}) &&
+ isEqual(cachedFormData?.shared_label_colors, sharedLabelsColors) &&
!!cachedFormData &&
areObjectsEqual(cachedFormData?.dataMask, dataMask, {
ignoreUndefined: true,
@@ -118,8 +117,8 @@ export default function getFormDataWithExtraFilters({
...chart.form_data,
chart_id: chart.id,
label_colors: labelsColor,
- shared_label_colors: sharedLabelsColorMap,
- full_label_colors: labelsColorMap,
+ shared_label_colors: sharedLabelsColors,
+ map_label_colors: labelsColorMap,
...(colorScheme && { color_scheme: colorScheme }),
...(ownColorScheme && {
own_color_scheme: ownColorScheme,
diff --git
a/superset-frontend/src/explore/components/controls/ColorSchemeControl/ColorSchemeControl.test.tsx
b/superset-frontend/src/explore/components/controls/ColorSchemeControl/ColorSchemeControl.test.tsx
index 70fbb2efe3..264e6968c8 100644
---
a/superset-frontend/src/explore/components/controls/ColorSchemeControl/ColorSchemeControl.test.tsx
+++
b/superset-frontend/src/explore/components/controls/ColorSchemeControl/ColorSchemeControl.test.tsx
@@ -29,7 +29,7 @@ import ColorSchemeControl, { ColorSchemes } from '.';
const defaultProps = () => ({
hasCustomLabelsColor: false,
- sharedLabelsColor: {},
+ sharedLabelsColors: [],
label: 'Color scheme',
labelMargin: 0,
name: 'color',
@@ -129,8 +129,8 @@ test('displays color scheme options', async () => {
});
});
-test('Renders control with dashboard id', () => {
- setup({ dashboardId: 1 });
+test('Renders control with dashboard id and dashboard color scheme', () => {
+ setup({ dashboardId: 1, hasDashboardColorScheme: true });
expect(screen.getByText('Dashboard scheme')).toBeInTheDocument();
expect(
screen.getByLabelText('Select color scheme', { selector: 'input' }),
diff --git
a/superset-frontend/src/explore/components/controls/ColorSchemeControl/index.tsx
b/superset-frontend/src/explore/components/controls/ColorSchemeControl/index.tsx
index 4d296a54d7..9c5734fdbe 100644
---
a/superset-frontend/src/explore/components/controls/ColorSchemeControl/index.tsx
+++
b/superset-frontend/src/explore/components/controls/ColorSchemeControl/index.tsx
@@ -50,7 +50,7 @@ export interface ColorSchemeControlProps {
hasCustomLabelsColor: boolean;
hasDashboardColorScheme?: boolean;
hasSharedLabelsColor?: boolean;
- sharedLabelsColor: Record<string, string>;
+ sharedLabelsColors: string[];
chartId?: number;
dashboardId?: number;
label: string;
@@ -125,7 +125,7 @@ const Label = ({
const ColorSchemeControl = ({
hasCustomLabelsColor = false,
hasDashboardColorScheme = false,
- sharedLabelsColor = {},
+ sharedLabelsColors = [],
dashboardId,
chartId,
label = t('Color scheme'),
@@ -138,7 +138,7 @@ const ColorSchemeControl = ({
isLinear,
...rest
}: ColorSchemeControlProps) => {
- const countSharedLabelsColor = Object.keys(sharedLabelsColor).length;
+ const countSharedLabelsColor = sharedLabelsColors.length;
const colorMapInstance = getLabelsColorMap();
const chartLabels = chartId
? colorMapInstance.chartsLabelsMap.get(chartId)?.labels || []
@@ -146,7 +146,7 @@ const ColorSchemeControl = ({
const hasSharedLabelsColor = !!(
dashboardId &&
countSharedLabelsColor > 0 &&
- chartLabels.some(label => sharedLabelsColor[label])
+ chartLabels.some(label => sharedLabelsColors.includes(label))
);
const hasDashboardScheme = dashboardId && hasDashboardColorScheme;
const theme = useTheme();
diff --git
a/superset-frontend/src/explore/controlUtils/getFormDataFromDashboardContext.test.ts
b/superset-frontend/src/explore/controlUtils/getFormDataFromDashboardContext.test.ts
index fd120355c8..3dea89148b 100644
---
a/superset-frontend/src/explore/controlUtils/getFormDataFromDashboardContext.test.ts
+++
b/superset-frontend/src/explore/controlUtils/getFormDataFromDashboardContext.test.ts
@@ -151,10 +151,8 @@ const getExpectedResultFormData = (overrides: JsonObject =
{}) => ({
girl: '#FF69B4',
boy: '#ADD8E6',
},
- shared_label_colors: {
- boy: '#ADD8E6',
- girl: '#FF69B4',
- },
+ shared_label_colors: ['boy', 'girl'],
+ own_color_scheme: 'supersetColors',
extra_filters: [
{
col: '__time_range',
diff --git a/superset-frontend/src/pages/Chart/index.tsx
b/superset-frontend/src/pages/Chart/index.tsx
index 3f061014a6..5bbeb5fa86 100644
--- a/superset-frontend/src/pages/Chart/index.tsx
+++ b/superset-frontend/src/pages/Chart/index.tsx
@@ -102,7 +102,7 @@ const getDashboardContextFormData = () => {
colorScheme,
labelsColor,
labelsColorMap,
- sharedLabelsColorMap,
+ sharedLabelsColors,
chartConfiguration,
nativeFilters,
filterBoxFilters,
@@ -118,7 +118,7 @@ const getDashboardContextFormData = () => {
colorScheme,
labelsColor,
labelsColorMap,
- sharedLabelsColorMap,
+ sharedLabelsColors,
sliceId,
allSliceIds: [sliceId],
extraControls: {},
diff --git a/superset-frontend/src/types/DashboardContextForExplore.ts
b/superset-frontend/src/types/DashboardContextForExplore.ts
index be6fab0157..117a182606 100644
--- a/superset-frontend/src/types/DashboardContextForExplore.ts
+++ b/superset-frontend/src/types/DashboardContextForExplore.ts
@@ -26,7 +26,7 @@ import { ChartConfiguration } from 'src/dashboard/types';
export interface DashboardContextForExplore {
labelsColor: Record<string, string>;
labelsColorMap: Record<string, string>;
- sharedLabelsColorMap: Record<string, string>;
+ sharedLabelsColors: string[];
colorScheme: string;
chartConfiguration: ChartConfiguration;
nativeFilters: PartialFilters;
diff --git a/superset-frontend/src/utils/colorScheme.ts
b/superset-frontend/src/utils/colorScheme.ts
index 9905661ed8..3fe50b51c1 100644
--- a/superset-frontend/src/utils/colorScheme.ts
+++ b/superset-frontend/src/utils/colorScheme.ts
@@ -32,42 +32,43 @@ import {
export const getColorNamespace = (namespace?: string) => namespace ||
undefined;
/**
- * Get the labels color map entries
+ * Get labels shared across multiple charts
*
- * @param shared - filter out labels not shared across multiple charts
* @returns Record<string, string>
*/
-export const getLabelsColorMapEntries = (
- shared = false,
-): Record<string, string> => {
+
+export const getSharedLabels = (): string[] => {
const labelsColorMapInstance = getLabelsColorMap();
- const updatedLabelsColorMapEntries = Object.fromEntries(
- labelsColorMapInstance.getColorMap(),
- );
- // filter out all labels that are not shared across multiple charts
const { chartsLabelsMap } = labelsColorMapInstance;
- if (shared) {
- const allLabels = new Set<string>();
- const sharedLabels = new Set<string>();
- chartsLabelsMap.forEach(({ labels }) => {
- labels.forEach(label => {
- if (allLabels.has(label)) {
- sharedLabels.add(label);
- }
- allLabels.add(label);
- });
+ const allLabels = new Set<string>();
+ const sharedLabels: string[] = [];
+ chartsLabelsMap.forEach(({ labels }) => {
+ labels.forEach(label => {
+ if (allLabels.has(label) && !sharedLabels.includes(label)) {
+ sharedLabels.push(label);
+ }
+ allLabels.add(label);
});
- const sharedLabelsColorMapEntries = Object.fromEntries(
- Object.entries(updatedLabelsColorMapEntries).filter(([label]) =>
- sharedLabels.has(label),
- ),
- );
+ });
- return sharedLabelsColorMapEntries;
- }
+ return sharedLabels;
+};
- return updatedLabelsColorMapEntries;
+export const getSharedLabelsColorMapEntries = (
+ currentColorMap: Record<string, string>,
+): Record<string, string> => {
+ const sharedLabels = getSharedLabels();
+ return Object.fromEntries(
+ Object.entries(currentColorMap).filter(([label]) =>
+ sharedLabels.includes(label),
+ ),
+ );
+};
+
+export const getLabelsColorMapEntries = (): Record<string, string> => {
+ const labelsColorMapInstance = getLabelsColorMap();
+ return Object.fromEntries(labelsColorMapInstance.getColorMap());
};
export const getColorSchemeDomain = (colorScheme: string) =>
@@ -82,7 +83,7 @@ export const getColorSchemeDomain = (colorScheme: string) =>
export const isLabelsColorMapSynced = (
metadata: Record<string, any>,
): boolean => {
- const currentLabelsColorMap = metadata?.full_label_colors || {};
+ const currentLabelsColorMap = metadata?.map_label_colors || {};
const customLabelColors = metadata?.label_colors || {};
const freshLabelsColorMap = getLabelsColorMap().getColorMap();
@@ -155,10 +156,20 @@ export const applyColors = (
CategoricalColorNamespace.getNamespace(colorNameSpace);
const colorScheme = metadata?.color_scheme;
const customLabelColors = metadata?.label_colors || {};
- const sharedLabelsColorMap = metadata?.shared_label_colors || {};
+ const sharedLabels = Array.isArray(metadata?.shared_label_colors)
+ ? metadata.shared_label_colors
+ : getSharedLabels();
+ const fullLabelsColor = metadata?.map_label_colors || {};
+ // filter the fullLabelsColor object to only shared labels
+ const sharedLabelsColors = Object.fromEntries(
+ Object.entries(fullLabelsColor).filter(([label]) =>
+ sharedLabels.includes(label),
+ ),
+ );
+
const labelsColorMap = shared
- ? sharedLabelsColorMap
- : metadata?.full_label_colors || {};
+ ? sharedLabelsColors
+ : metadata?.map_label_colors || {};
if (fresh) {
// reset custom label colors
@@ -177,7 +188,9 @@ export const applyColors = (
refreshLabelsColorMap(metadata?.color_namespace, colorScheme, merge);
}
- const currentColorMapEntries = getLabelsColorMapEntries(shared);
+ const currentColorMapEntries = shared
+ ? getSharedLabelsColorMapEntries(fullLabelsColor)
+ : getLabelsColorMapEntries();
// get the fresh map that was just updated or existing
const labelsColorMapEntries = fresh
diff --git a/superset/daos/dashboard.py b/superset/daos/dashboard.py
index 2b4fc05d74..d5cc08582c 100644
--- a/superset/daos/dashboard.py
+++ b/superset/daos/dashboard.py
@@ -259,8 +259,8 @@ class DashboardDAO(BaseDAO[Dashboard]):
md["refresh_frequency"] = data.get("refresh_frequency", 0)
md["color_scheme"] = data.get("color_scheme", "")
md["label_colors"] = data.get("label_colors", {})
- md["shared_label_colors"] = data.get("shared_label_colors", {})
- md["full_label_colors"] = data.get("full_label_colors", {})
+ md["shared_label_colors"] = data.get("shared_label_colors", [])
+ md["map_label_colors"] = data.get("map_label_colors", {})
md["color_scheme_domain"] = data.get("color_scheme_domain", [])
md["cross_filters_enabled"] = data.get("cross_filters_enabled", True)
dashboard.json_metadata = json.dumps(md)
diff --git a/superset/dashboards/schemas.py b/superset/dashboards/schemas.py
index c501ff3191..2464847bf1 100644
--- a/superset/dashboards/schemas.py
+++ b/superset/dashboards/schemas.py
@@ -137,8 +137,8 @@ class DashboardJSONMetadataSchema(Schema):
color_namespace = fields.Str(allow_none=True)
positions = fields.Dict(allow_none=True)
label_colors = fields.Dict()
- shared_label_colors = fields.Dict()
- full_label_colors = fields.Dict()
+ shared_label_colors = fields.List(fields.Str())
+ map_label_colors = fields.Dict()
color_scheme_domain = fields.List(fields.Str())
cross_filters_enabled = fields.Boolean(dump_default=True)
# used for v0 import/export
diff --git a/tests/integration_tests/dashboards/api_tests.py
b/tests/integration_tests/dashboards/api_tests.py
index df8461814b..cb97eb3f58 100644
--- a/tests/integration_tests/dashboards/api_tests.py
+++ b/tests/integration_tests/dashboards/api_tests.py
@@ -81,7 +81,7 @@ class TestDashboardApi(ApiOwnersTestCaseMixin,
InsertChartMixin, SupersetTestCas
"slug": "slug1_changed",
"position_json": '{"b": "B"}',
"css": "css_changed",
- "json_metadata": '{"refresh_frequency": 30,
"timed_refresh_immune_slices": [], "expanded_slices": {}, "color_scheme": "",
"label_colors": {}, "shared_label_colors": {}, "full_label_colors": {},
"color_scheme_domain": [], "cross_filters_enabled": false}',
+ "json_metadata": '{"refresh_frequency": 30,
"timed_refresh_immune_slices": [], "expanded_slices": {}, "color_scheme": "",
"label_colors": {}, "shared_label_colors": [], "map_label_colors": {},
"color_scheme_domain": [], "cross_filters_enabled": false}',
"published": False,
}
diff --git a/tests/unit_tests/fixtures/assets_configs.py
b/tests/unit_tests/fixtures/assets_configs.py
index bbccdcd179..0bb7e2711e 100644
--- a/tests/unit_tests/fixtures/assets_configs.py
+++ b/tests/unit_tests/fixtures/assets_configs.py
@@ -175,8 +175,8 @@ dashboards_config_1: dict[str, Any] = {
"color_scheme": "supersetColors",
"label_colors": {},
"color_scheme_domain": [],
- "shared_label_colors": {},
- "full_label_colors": {},
+ "shared_label_colors": [],
+ "map_label_colors": {},
"cross_filters_enabled": False,
},
"version": "1.0.0",
@@ -252,8 +252,8 @@ dashboards_config_2: dict[str, Any] = {
"color_scheme": "supersetColors",
"label_colors": {},
"color_scheme_domain": [],
- "shared_label_colors": {},
- "full_label_colors": {},
+ "shared_label_colors": [],
+ "map_label_colors": {},
},
"version": "1.0.0",
},
diff --git a/tests/unit_tests/security/manager_test.py
b/tests/unit_tests/security/manager_test.py
index 35cf2d03db..a6022525ac 100644
--- a/tests/unit_tests/security/manager_test.py
+++ b/tests/unit_tests/security/manager_test.py
@@ -750,8 +750,8 @@ def test_query_context_modified_sankey_tampered(mocker:
MockerFixture) -> None:
"dashboards": [11],
"extra_form_data": {},
"label_colors": {},
- "shared_label_colors": {},
- "full_label_colors": {},
+ "shared_label_colors": [],
+ "map_label_colors": {},
"extra_filters": [],
"dashboardId": 11,
"force": False,