feat(explore): Color scheme groups, new color schemes (#27995)
This commit is contained in:
parent
b224b8331a
commit
bbfe5c0ae8
|
|
@ -215,7 +215,7 @@ describe('Dashboard edit', () => {
|
|||
|
||||
it('should apply same color to same labels with color scheme set', () => {
|
||||
openProperties();
|
||||
selectColorScheme('lyftColors');
|
||||
selectColorScheme('blueToGreen');
|
||||
applyChanges();
|
||||
saveChanges();
|
||||
|
||||
|
|
@ -231,7 +231,7 @@ describe('Dashboard edit', () => {
|
|||
'[data-test-chart-name="Top 10 California Names Timeseries"] .line .nv-legend-symbol',
|
||||
)
|
||||
.first()
|
||||
.should('have.css', 'fill', 'rgb(51, 61, 71)');
|
||||
.should('have.css', 'fill', 'rgb(0, 234, 162)');
|
||||
|
||||
// open 2nd main tab
|
||||
openTab(0, 1);
|
||||
|
|
@ -240,7 +240,7 @@ describe('Dashboard edit', () => {
|
|||
// label Anthony
|
||||
cy.get('[data-test-chart-name="Trends"] .line .nv-legend-symbol')
|
||||
.eq(2)
|
||||
.should('have.css', 'fill', 'rgb(51, 61, 71)');
|
||||
.should('have.css', 'fill', 'rgb(0, 234, 162)');
|
||||
});
|
||||
|
||||
it('should apply same color to same labels with no color scheme set', () => {
|
||||
|
|
@ -480,7 +480,7 @@ describe('Dashboard edit', () => {
|
|||
|
||||
it.skip('should change color scheme multiple times', () => {
|
||||
openProperties();
|
||||
selectColorScheme('lyftColors');
|
||||
selectColorScheme('blueToGreen');
|
||||
applyChanges();
|
||||
saveChanges();
|
||||
|
||||
|
|
@ -509,7 +509,7 @@ describe('Dashboard edit', () => {
|
|||
|
||||
editDashboard();
|
||||
openProperties();
|
||||
selectColorScheme('bnbColors');
|
||||
selectColorScheme('modernSunset');
|
||||
applyChanges();
|
||||
saveChanges();
|
||||
|
||||
|
|
@ -532,7 +532,7 @@ describe('Dashboard edit', () => {
|
|||
|
||||
it.skip('should apply the color scheme across main tabs', () => {
|
||||
openProperties();
|
||||
selectColorScheme('lyftColors');
|
||||
selectColorScheme('blueToGreen');
|
||||
applyChanges();
|
||||
saveChanges();
|
||||
|
||||
|
|
@ -548,7 +548,7 @@ describe('Dashboard edit', () => {
|
|||
it.skip('should apply the color scheme across main tabs for rendered charts', () => {
|
||||
waitForChartLoad({ name: 'Treemap', viz: 'treemap_v2' });
|
||||
openProperties();
|
||||
selectColorScheme('bnbColors');
|
||||
selectColorScheme('blueToGreen');
|
||||
applyChanges();
|
||||
saveChanges();
|
||||
|
||||
|
|
@ -563,7 +563,7 @@ describe('Dashboard edit', () => {
|
|||
// change scheme now that charts are rendered across the main tabs
|
||||
editDashboard();
|
||||
openProperties();
|
||||
selectColorScheme('lyftColors');
|
||||
selectColorScheme('modernSunset');
|
||||
applyChanges();
|
||||
saveChanges();
|
||||
|
||||
|
|
@ -574,7 +574,7 @@ describe('Dashboard edit', () => {
|
|||
|
||||
it.skip('should apply the color scheme in nested tabs', () => {
|
||||
openProperties();
|
||||
selectColorScheme('lyftColors');
|
||||
selectColorScheme('blueToGreen');
|
||||
applyChanges();
|
||||
saveChanges();
|
||||
|
||||
|
|
@ -609,7 +609,7 @@ describe('Dashboard edit', () => {
|
|||
// go to previous tab
|
||||
openTab(1, 0);
|
||||
openProperties();
|
||||
selectColorScheme('lyftColors');
|
||||
selectColorScheme('blueToGreen');
|
||||
applyChanges();
|
||||
saveChanges();
|
||||
|
||||
|
|
@ -646,16 +646,16 @@ describe('Dashboard edit', () => {
|
|||
});
|
||||
|
||||
it.skip('should overwrite the color scheme when advanced is closed', () => {
|
||||
selectColorScheme('d3Category20b');
|
||||
selectColorScheme('blueToGreen');
|
||||
openAdvancedProperties();
|
||||
assertMetadata('d3Category20b');
|
||||
assertMetadata('blueToGreen');
|
||||
applyChanges();
|
||||
});
|
||||
|
||||
it.skip('should overwrite the color scheme when advanced is open', () => {
|
||||
openAdvancedProperties();
|
||||
selectColorScheme('googleCategory10c');
|
||||
assertMetadata('googleCategory10c');
|
||||
selectColorScheme('modernSunset');
|
||||
assertMetadata('modernSunset');
|
||||
applyChanges();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -17,12 +17,15 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { ColorSchemeGroup } from './types';
|
||||
|
||||
export interface ColorSchemeConfig {
|
||||
colors: string[];
|
||||
description?: string;
|
||||
id: string;
|
||||
label?: string;
|
||||
isDefault?: boolean;
|
||||
group?: ColorSchemeGroup;
|
||||
}
|
||||
|
||||
export default class ColorScheme {
|
||||
|
|
@ -36,17 +39,21 @@ export default class ColorScheme {
|
|||
|
||||
isDefault?: boolean;
|
||||
|
||||
group?: ColorSchemeGroup;
|
||||
|
||||
constructor({
|
||||
colors,
|
||||
description = '',
|
||||
id,
|
||||
label,
|
||||
isDefault,
|
||||
group,
|
||||
}: ColorSchemeConfig) {
|
||||
this.id = id;
|
||||
this.label = label ?? id;
|
||||
this.colors = colors;
|
||||
this.description = description;
|
||||
this.isDefault = isDefault;
|
||||
this.group = group;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
import CategoricalScheme from '../../CategoricalScheme';
|
||||
|
||||
// TODO: add the colors to the theme while working on SIP https://github.com/apache/superset/issues/20159
|
||||
const schemes = [
|
||||
{
|
||||
id: 'bnbColors',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import CategoricalScheme from '../../CategoricalScheme';
|
||||
import { ColorSchemeGroup } from '../../types';
|
||||
|
||||
// TODO: add the colors to the theme while working on SIP https://github.com/apache/superset/issues/20159
|
||||
const schemes = [
|
||||
{
|
||||
id: 'blueToGreen',
|
||||
label: 'Blue to green',
|
||||
group: ColorSchemeGroup.Featured,
|
||||
colors: [
|
||||
'#3200A7',
|
||||
'#004CDA',
|
||||
'#0074F1',
|
||||
'#0096EF',
|
||||
'#53BFFF',
|
||||
'#41C8E6',
|
||||
'#30DEDE',
|
||||
'#04D9C7',
|
||||
'#00EAA2',
|
||||
'#A6FF93',
|
||||
],
|
||||
},
|
||||
].map(s => new CategoricalScheme(s));
|
||||
|
||||
export default schemes;
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import CategoricalScheme from '../../CategoricalScheme';
|
||||
import { ColorSchemeGroup } from '../../types';
|
||||
|
||||
// TODO: add the colors to the theme while working on SIP https://github.com/apache/superset/issues/20159
|
||||
const schemes = [
|
||||
{
|
||||
id: 'colorsOfRainbow',
|
||||
label: 'Colors of rainbow',
|
||||
group: ColorSchemeGroup.Featured,
|
||||
colors: [
|
||||
'#41ED86',
|
||||
'#2FC096',
|
||||
'#01DFFF',
|
||||
'#153AE0',
|
||||
'#850AD6',
|
||||
'#BD59FF',
|
||||
'#FF4A96',
|
||||
'#C32668',
|
||||
'#F40000',
|
||||
'#FF8901',
|
||||
'#FFBC0A',
|
||||
'#FFEC43',
|
||||
],
|
||||
},
|
||||
].map(s => new CategoricalScheme(s));
|
||||
|
||||
export default schemes;
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
import CategoricalScheme from '../../CategoricalScheme';
|
||||
|
||||
// TODO: add the colors to the theme while working on SIP https://github.com/apache/superset/issues/20159
|
||||
const schemes = [
|
||||
{
|
||||
id: 'd3Category10',
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
import CategoricalScheme from '../../CategoricalScheme';
|
||||
|
||||
// TODO: add the colors to the theme while working on SIP https://github.com/apache/superset/issues/20159
|
||||
const schemes = [
|
||||
{
|
||||
id: 'echarts4Colors',
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
import CategoricalScheme from '../../CategoricalScheme';
|
||||
|
||||
// TODO: add the colors to the theme while working on SIP https://github.com/apache/superset/issues/20159
|
||||
const schemes = [
|
||||
{
|
||||
id: 'googleCategory10c',
|
||||
|
|
|
|||
|
|
@ -24,3 +24,9 @@ export { default as CategoricalGoogle } from './google';
|
|||
export { default as CategoricalLyft } from './lyft';
|
||||
export { default as CategoricalPreset } from './preset';
|
||||
export { default as CategoricalSuperset } from './superset';
|
||||
export { default as CategoricalPresetSuperset } from './presetAndSuperset';
|
||||
export { default as CategoricalModernSunset } from './modernSunset';
|
||||
export { default as CategoricalColorsOfRainbow } from './colorsOfRainbow';
|
||||
export { default as CategoricalBlueToGreen } from './blueToGreen';
|
||||
export { default as CategoricalRedToYellow } from './redToYellow';
|
||||
export { default as CategoricalWavesOfBlue } from './wavesOfBlue';
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
import CategoricalScheme from '../../CategoricalScheme';
|
||||
|
||||
// TODO: add the colors to the theme while working on SIP https://github.com/apache/superset/issues/20159
|
||||
const schemes = [
|
||||
{
|
||||
id: 'lyftColors',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import CategoricalScheme from '../../CategoricalScheme';
|
||||
import { ColorSchemeGroup } from '../../types';
|
||||
|
||||
// TODO: add the colors to the theme while working on SIP https://github.com/apache/superset/issues/20159
|
||||
const schemes = [
|
||||
{
|
||||
id: 'modernSunset',
|
||||
label: 'Modern sunset',
|
||||
group: ColorSchemeGroup.Featured,
|
||||
colors: [
|
||||
'#0080F6',
|
||||
'#254081',
|
||||
'#6C4592',
|
||||
'#A94693',
|
||||
'#DC4180',
|
||||
'#F35193',
|
||||
'#FF7582',
|
||||
'#FF4C5D',
|
||||
'#FF824E',
|
||||
'#FFAD2A',
|
||||
'#FFDB04',
|
||||
'#F3F700',
|
||||
],
|
||||
},
|
||||
].map(s => new CategoricalScheme(s));
|
||||
|
||||
export default schemes;
|
||||
|
|
@ -18,11 +18,14 @@
|
|||
*/
|
||||
|
||||
import CategoricalScheme from '../../CategoricalScheme';
|
||||
import { ColorSchemeGroup } from '../../types';
|
||||
|
||||
// TODO: add the colors to the theme while working on SIP https://github.com/apache/superset/issues/20159
|
||||
const schemes = [
|
||||
{
|
||||
id: 'presetColors',
|
||||
label: 'Preset Colors',
|
||||
group: ColorSchemeGroup.Featured,
|
||||
colors: [
|
||||
// Full color
|
||||
'#6BD3B3',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import CategoricalScheme from '../../CategoricalScheme';
|
||||
import { ColorSchemeGroup } from '../../types';
|
||||
|
||||
// TODO: add the colors to the theme while working on SIP https://github.com/apache/superset/issues/20159
|
||||
const schemes = [
|
||||
{
|
||||
id: 'supersetAndPresetColors',
|
||||
label: 'Preset + Superset',
|
||||
group: ColorSchemeGroup.Featured,
|
||||
colors: [
|
||||
'#004960',
|
||||
'#2893B3',
|
||||
'#20A7C9',
|
||||
'#5CC0DA',
|
||||
'#7DCDE1',
|
||||
'#A9D3E1',
|
||||
'#C6ECE1',
|
||||
'#AAE2D2',
|
||||
'#71CFB4',
|
||||
'#2FC096',
|
||||
'#178F7A',
|
||||
'#067162',
|
||||
],
|
||||
},
|
||||
].map(s => new CategoricalScheme(s));
|
||||
|
||||
export default schemes;
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import CategoricalScheme from '../../CategoricalScheme';
|
||||
import { ColorSchemeGroup } from '../../types';
|
||||
|
||||
// TODO: add the colors to the theme while working on SIP https://github.com/apache/superset/issues/20159
|
||||
const schemes = [
|
||||
{
|
||||
id: 'redToYellow',
|
||||
label: 'Red to yellow',
|
||||
group: ColorSchemeGroup.Featured,
|
||||
colors: [
|
||||
'#90042A',
|
||||
'#D60039',
|
||||
'#D1353B',
|
||||
'#E45233',
|
||||
'#F47028',
|
||||
'#FE8E17',
|
||||
'#FFAD00',
|
||||
'#FFCC00',
|
||||
'#FFE601',
|
||||
'#FFF46D',
|
||||
],
|
||||
},
|
||||
].map(s => new CategoricalScheme(s));
|
||||
|
||||
export default schemes;
|
||||
|
|
@ -18,11 +18,14 @@
|
|||
*/
|
||||
|
||||
import CategoricalScheme from '../../CategoricalScheme';
|
||||
import { ColorSchemeGroup } from '../../types';
|
||||
|
||||
// TODO: add the colors to the theme while working on SIP https://github.com/apache/superset/issues/20159
|
||||
const schemes = [
|
||||
{
|
||||
id: 'supersetColors',
|
||||
label: 'Superset Colors',
|
||||
group: ColorSchemeGroup.Featured,
|
||||
colors: [
|
||||
// Full color
|
||||
'#1FA8C9',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import CategoricalScheme from '../../CategoricalScheme';
|
||||
import { ColorSchemeGroup } from '../../types';
|
||||
|
||||
// TODO: add the colors to the theme while working on SIP https://github.com/apache/superset/issues/20159
|
||||
const schemes = [
|
||||
{
|
||||
id: 'wavesOfBlue',
|
||||
label: 'Waves of blue',
|
||||
group: ColorSchemeGroup.Featured,
|
||||
colors: [
|
||||
'#070061',
|
||||
'#0A0095',
|
||||
'#0054B4',
|
||||
'#006BE7',
|
||||
'#2289FF',
|
||||
'#4A9FFF',
|
||||
'#76B6FF',
|
||||
'#9DCBFF',
|
||||
'#BEDCFF',
|
||||
'#DAEBFF',
|
||||
],
|
||||
},
|
||||
].map(s => new CategoricalScheme(s));
|
||||
|
||||
export default schemes;
|
||||
|
|
@ -31,3 +31,9 @@ export interface RgbaColor {
|
|||
b: number;
|
||||
a: number;
|
||||
}
|
||||
|
||||
export enum ColorSchemeGroup {
|
||||
Custom = 'custom',
|
||||
Featured = 'featured',
|
||||
Other = 'other',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export const StyledContainer = styled.div<{ headerPosition: string }>`
|
|||
|
||||
export const StyledSelect = styled(AntdSelect, {
|
||||
shouldForwardProp: prop => prop !== 'headerPosition' && prop !== 'oneLine',
|
||||
})<{ headerPosition: string; oneLine?: boolean }>`
|
||||
})<{ headerPosition?: string; oneLine?: boolean }>`
|
||||
${({ theme, headerPosition, oneLine }) => `
|
||||
flex: ${headerPosition === 'left' ? 1 : 0};
|
||||
&& .ant-select-selector {
|
||||
|
|
|
|||
|
|
@ -17,23 +17,37 @@
|
|||
* under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import {
|
||||
CategoricalD3,
|
||||
CategoricalModernSunset,
|
||||
CategoricalScheme,
|
||||
ColorSchemeGroup,
|
||||
getCategoricalSchemeRegistry,
|
||||
} from '@superset-ui/core';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { render, screen, waitFor } from 'spec/helpers/testing-library';
|
||||
import ColorSchemeControl, { ColorSchemes } from '.';
|
||||
|
||||
const defaultProps = {
|
||||
const defaultProps = () => ({
|
||||
hasCustomLabelColors: false,
|
||||
label: 'Color scheme',
|
||||
labelMargin: 0,
|
||||
name: 'color',
|
||||
value: 'supersetDefault',
|
||||
clearable: true,
|
||||
choices: [],
|
||||
schemes: () => ({}) as ColorSchemes,
|
||||
choices: getCategoricalSchemeRegistry()
|
||||
.keys()
|
||||
.map(s => [s, s]),
|
||||
schemes: getCategoricalSchemeRegistry().getMap() as ColorSchemes,
|
||||
isLinear: false,
|
||||
};
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
getCategoricalSchemeRegistry().clear();
|
||||
});
|
||||
|
||||
const setup = (overrides?: Record<string, any>) =>
|
||||
render(<ColorSchemeControl {...defaultProps} {...overrides} />);
|
||||
render(<ColorSchemeControl {...defaultProps()} {...overrides} />);
|
||||
|
||||
test('should render', async () => {
|
||||
const { container } = setup();
|
||||
|
|
@ -56,7 +70,6 @@ test('should not display an alert icon if hasCustomLabelColors=false', async ()
|
|||
|
||||
test('should display an alert icon if hasCustomLabelColors=true', async () => {
|
||||
const hasCustomLabelColorsProps = {
|
||||
...defaultProps,
|
||||
hasCustomLabelColors: true,
|
||||
};
|
||||
setup(hasCustomLabelColorsProps);
|
||||
|
|
@ -66,3 +79,51 @@ test('should display an alert icon if hasCustomLabelColors=true', async () => {
|
|||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test('displays color scheme options when only "other" group is registered', async () => {
|
||||
[...CategoricalD3].forEach(scheme =>
|
||||
getCategoricalSchemeRegistry().registerValue(scheme.id, scheme),
|
||||
);
|
||||
setup();
|
||||
userEvent.click(
|
||||
screen.getByLabelText('Select color scheme', { selector: 'input' }),
|
||||
);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('D3 Category 10')).toBeInTheDocument();
|
||||
expect(screen.getByText('D3 Category 20')).toBeInTheDocument();
|
||||
expect(screen.getByText('D3 Category 20b')).toBeInTheDocument();
|
||||
});
|
||||
expect(screen.queryByText('Other color palettes')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('Featured color palettes')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('Custom color palettes')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('displays color scheme options', async () => {
|
||||
[
|
||||
...CategoricalD3,
|
||||
...CategoricalModernSunset,
|
||||
{
|
||||
id: 'customScheme',
|
||||
label: 'Custom scheme',
|
||||
group: ColorSchemeGroup.Custom,
|
||||
colors: ['#0080F6', '#254081'],
|
||||
} as CategoricalScheme,
|
||||
].forEach(scheme =>
|
||||
getCategoricalSchemeRegistry().registerValue(scheme.id, scheme),
|
||||
);
|
||||
setup();
|
||||
userEvent.click(
|
||||
screen.getByLabelText('Select color scheme', { selector: 'input' }),
|
||||
);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('D3 Category 10')).toBeInTheDocument();
|
||||
expect(screen.getByText('D3 Category 20')).toBeInTheDocument();
|
||||
expect(screen.getByText('D3 Category 20b')).toBeInTheDocument();
|
||||
expect(screen.getByText('Modern sunset')).toBeInTheDocument();
|
||||
expect(screen.getByText('Custom scheme')).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText('Custom color palettes')).toBeInTheDocument();
|
||||
expect(screen.getByText('Featured color palettes')).toBeInTheDocument();
|
||||
expect(screen.getByText('Other color palettes')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -17,14 +17,29 @@
|
|||
* under the License.
|
||||
*/
|
||||
import React, { useMemo } from 'react';
|
||||
import { ColorScheme, SequentialScheme, styled, t } from '@superset-ui/core';
|
||||
import { isFunction } from 'lodash';
|
||||
import { Select } from 'src/components';
|
||||
import {
|
||||
css,
|
||||
ColorScheme,
|
||||
ColorSchemeGroup,
|
||||
SequentialScheme,
|
||||
styled,
|
||||
t,
|
||||
useTheme,
|
||||
} from '@superset-ui/core';
|
||||
import AntdSelect from 'antd/lib/select';
|
||||
import { isFunction, sortBy } from 'lodash';
|
||||
import ControlHeader from 'src/explore/components/ControlHeader';
|
||||
import { Tooltip } from 'src/components/Tooltip';
|
||||
import Icons from 'src/components/Icons';
|
||||
import { SelectOptionsType } from 'src/components/Select/types';
|
||||
import { StyledSelect } from 'src/components/Select/styles';
|
||||
import { handleFilterOptionHelper } from 'src/components/Select/utils';
|
||||
import ColorSchemeLabel from './ColorSchemeLabel';
|
||||
|
||||
const { Option, OptGroup } = AntdSelect;
|
||||
|
||||
export type OptionData = SelectOptionsType[number]['options'][number];
|
||||
|
||||
export interface ColorSchemes {
|
||||
[key: string]: ColorScheme;
|
||||
}
|
||||
|
|
@ -85,7 +100,6 @@ const ColorSchemeControl = ({
|
|||
hasCustomLabelColors = false,
|
||||
dashboardId,
|
||||
label = t('Color scheme'),
|
||||
name,
|
||||
onChange = () => {},
|
||||
value,
|
||||
clearable = false,
|
||||
|
|
@ -95,6 +109,7 @@ const ColorSchemeControl = ({
|
|||
isLinear,
|
||||
...rest
|
||||
}: ColorSchemeControlProps) => {
|
||||
const theme = useTheme();
|
||||
const currentScheme = useMemo(() => {
|
||||
if (dashboardId) {
|
||||
return 'dashboard';
|
||||
|
|
@ -130,30 +145,82 @@ const ColorSchemeControl = ({
|
|||
return isValidColorOption;
|
||||
});
|
||||
|
||||
return filteredColorOptions.map(([value]) => {
|
||||
const currentScheme = schemesObject[value];
|
||||
const groups = filteredColorOptions.reduce(
|
||||
(acc, [value]) => {
|
||||
const currentScheme = schemesObject[value];
|
||||
|
||||
// For categorical scheme, display all the colors
|
||||
// For sequential scheme, show 10 or interpolate to 10.
|
||||
// Sequential schemes usually have at most 10 colors.
|
||||
let colors: string[] = [];
|
||||
if (currentScheme) {
|
||||
colors = isLinear
|
||||
? (currentScheme as SequentialScheme).getColors(10)
|
||||
: currentScheme.colors;
|
||||
}
|
||||
return {
|
||||
customLabel: (
|
||||
<ColorSchemeLabel
|
||||
id={currentScheme.id}
|
||||
label={currentScheme.label}
|
||||
colors={colors}
|
||||
/>
|
||||
),
|
||||
label: schemesObject?.[value]?.label || value,
|
||||
value,
|
||||
};
|
||||
});
|
||||
// For categorical scheme, display all the colors
|
||||
// For sequential scheme, show 10 or interpolate to 10.
|
||||
// Sequential schemes usually have at most 10 colors.
|
||||
let colors: string[] = [];
|
||||
if (currentScheme) {
|
||||
colors = isLinear
|
||||
? (currentScheme as SequentialScheme).getColors(10)
|
||||
: currentScheme.colors;
|
||||
}
|
||||
const option = {
|
||||
customLabel: (
|
||||
<ColorSchemeLabel
|
||||
id={currentScheme.id}
|
||||
label={currentScheme.label}
|
||||
colors={colors}
|
||||
/>
|
||||
) as React.ReactNode,
|
||||
label: schemesObject?.[value]?.label || value,
|
||||
value,
|
||||
};
|
||||
acc[currentScheme.group ?? ColorSchemeGroup.Other].options.push(option);
|
||||
return acc;
|
||||
},
|
||||
{
|
||||
[ColorSchemeGroup.Custom]: {
|
||||
title: ColorSchemeGroup.Custom,
|
||||
label: t('Custom color palettes'),
|
||||
options: [] as OptionData,
|
||||
},
|
||||
[ColorSchemeGroup.Featured]: {
|
||||
title: ColorSchemeGroup.Featured,
|
||||
label: t('Featured color palettes'),
|
||||
options: [] as OptionData,
|
||||
},
|
||||
[ColorSchemeGroup.Other]: {
|
||||
title: ColorSchemeGroup.Other,
|
||||
label: t('Other color palettes'),
|
||||
options: [] as OptionData,
|
||||
},
|
||||
},
|
||||
);
|
||||
const nonEmptyGroups = Object.values(groups)
|
||||
.filter(group => group.options.length > 0)
|
||||
.map(group => ({
|
||||
...group,
|
||||
options: sortBy(group.options, opt => opt.label),
|
||||
}));
|
||||
|
||||
// if there are no featured or custom color schemes, return the ungrouped options
|
||||
if (
|
||||
nonEmptyGroups.length === 1 &&
|
||||
nonEmptyGroups[0].title === ColorSchemeGroup.Other
|
||||
) {
|
||||
return nonEmptyGroups[0].options.map((opt, index) => (
|
||||
<Option value={opt.value} label={opt.label} key={index}>
|
||||
{opt.customLabel}
|
||||
</Option>
|
||||
));
|
||||
}
|
||||
return nonEmptyGroups.map((group, groupIndex) => (
|
||||
<OptGroup label={group.label} key={groupIndex}>
|
||||
{group.options.map((opt, optIndex) => (
|
||||
<Option
|
||||
value={opt.value}
|
||||
label={opt.label}
|
||||
key={`${groupIndex}-${optIndex}`}
|
||||
>
|
||||
{opt.customLabel}
|
||||
</Option>
|
||||
))}
|
||||
</OptGroup>
|
||||
));
|
||||
}, [choices, dashboardId, isLinear, schemes]);
|
||||
|
||||
// We can't pass on change directly because it receives a second
|
||||
|
|
@ -161,28 +228,48 @@ const ColorSchemeControl = ({
|
|||
const handleOnChange = (value: string) => onChange(value);
|
||||
|
||||
return (
|
||||
<Select
|
||||
header={
|
||||
<ControlHeader
|
||||
{...rest}
|
||||
label={
|
||||
<Label
|
||||
label={label}
|
||||
hasCustomLabelColors={hasCustomLabelColors}
|
||||
dashboardId={dashboardId}
|
||||
/>
|
||||
<>
|
||||
<ControlHeader
|
||||
{...rest}
|
||||
label={
|
||||
<Label
|
||||
label={label}
|
||||
hasCustomLabelColors={hasCustomLabelColors}
|
||||
dashboardId={dashboardId}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<StyledSelect
|
||||
css={css`
|
||||
width: 100%;
|
||||
& .ant-select-item.ant-select-item-group {
|
||||
padding-left: ${theme.gridUnit}px;
|
||||
font-size: ${theme.typography.sizes.m}px;
|
||||
}
|
||||
/>
|
||||
}
|
||||
ariaLabel={t('Select color scheme')}
|
||||
allowClear={clearable}
|
||||
disabled={!!dashboardId}
|
||||
name={`select-${name}`}
|
||||
onChange={handleOnChange}
|
||||
options={options}
|
||||
placeholder={t('Select scheme')}
|
||||
value={currentScheme}
|
||||
/>
|
||||
& .ant-select-item-option-grouped {
|
||||
padding-left: ${theme.gridUnit * 3}px;
|
||||
}
|
||||
`}
|
||||
aria-label={t('Select color scheme')}
|
||||
allowClear={clearable}
|
||||
disabled={!!dashboardId}
|
||||
onChange={handleOnChange}
|
||||
placeholder={t('Select scheme')}
|
||||
value={currentScheme}
|
||||
getPopupContainer={triggerNode => triggerNode.parentNode}
|
||||
showSearch
|
||||
filterOption={(search, option) =>
|
||||
handleFilterOptionHelper(
|
||||
search,
|
||||
option as OptionData,
|
||||
['label', 'value'],
|
||||
true,
|
||||
)
|
||||
}
|
||||
>
|
||||
{options}
|
||||
</StyledSelect>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,13 @@ import {
|
|||
SequentialCommon,
|
||||
SequentialD3,
|
||||
ColorSchemeRegistry,
|
||||
ColorSchemeGroup,
|
||||
CategoricalPresetSuperset,
|
||||
CategoricalModernSunset,
|
||||
CategoricalColorsOfRainbow,
|
||||
CategoricalBlueToGreen,
|
||||
CategoricalRedToYellow,
|
||||
CategoricalWavesOfBlue,
|
||||
} from '@superset-ui/core';
|
||||
|
||||
function registerColorSchemes<T extends ColorScheme>(
|
||||
|
|
@ -55,7 +62,8 @@ export default function setupColors(
|
|||
extraSequentialColorSchemeConfigs: SequentialSchemeConfig[] = [],
|
||||
) {
|
||||
const extraCategoricalColorSchemes = extraCategoricalColorSchemeConfigs.map(
|
||||
config => new CategoricalScheme(config),
|
||||
config =>
|
||||
new CategoricalScheme({ ...config, group: ColorSchemeGroup.Custom }),
|
||||
);
|
||||
const extraSequentialColorSchemes = extraSequentialColorSchemeConfigs.map(
|
||||
config => new SequentialScheme(config),
|
||||
|
|
@ -71,6 +79,12 @@ export default function setupColors(
|
|||
...CategoricalLyft,
|
||||
...CategoricalPreset,
|
||||
...CategoricalSuperset,
|
||||
...CategoricalPresetSuperset,
|
||||
...CategoricalModernSunset,
|
||||
...CategoricalColorsOfRainbow,
|
||||
...CategoricalBlueToGreen,
|
||||
...CategoricalRedToYellow,
|
||||
...CategoricalWavesOfBlue,
|
||||
...extraCategoricalColorSchemes,
|
||||
],
|
||||
'supersetColors',
|
||||
|
|
|
|||
Loading…
Reference in New Issue