feat(world-map): support color by metric or country column (#19881)

* feat(world-map): support color by metric or country column

* fix lint

* Update superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/components/RadioButtonControl.tsx

Co-authored-by: Evan Rusackas <evan@preset.io>

* Update superset-frontend/plugins/legacy-plugin-chart-world-map/src/controlPanel.ts

Co-authored-by: Evan Rusackas <evan@preset.io>

* Update superset-frontend/plugins/legacy-plugin-chart-world-map/src/controlPanel.ts

Co-authored-by: Evan Rusackas <evan@preset.io>

* fix lint

Co-authored-by: Evan Rusackas <evan@preset.io>
This commit is contained in:
Stephen Liu 2022-06-03 21:31:22 +08:00 committed by GitHub
parent 0e38c686c6
commit 766f737728
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 91 additions and 15 deletions

View File

@ -53,8 +53,12 @@ export default function RadioButtonControl({
'.btn:focus': {
outline: 'none',
},
'.control-label': {
color: theme.colors.grayscale.base,
marginBottom: theme.gridUnit,
},
'.control-label + .btn-group': {
marginTop: 1,
marginTop: '1px',
},
'.btn-group .btn-default': {
color: theme.colors.grayscale.dark1,

View File

@ -23,8 +23,10 @@ import { extent as d3Extent } from 'd3-array';
import {
getNumberFormatter,
getSequentialSchemeRegistry,
CategoricalColorNamespace,
} from '@superset-ui/core';
import Datamap from 'datamaps/dist/datamaps.world.min';
import { ColorBy } from './utils';
const propTypes = {
data: PropTypes.arrayOf(
@ -55,6 +57,9 @@ function WorldMap(element, props) {
showBubbles,
linearColorScheme,
color,
colorBy,
colorScheme,
sliceId,
theme,
} = props;
const div = d3.select(element);
@ -70,15 +75,27 @@ function WorldMap(element, props) {
.domain([extRadius[0], extRadius[1]])
.range([1, maxBubbleSize]);
const colorScale = getSequentialSchemeRegistry()
.get(linearColorScheme)
.createLinearScale(d3Extent(filteredData, d => d.m1));
let processedData;
let colorScale;
if (colorBy === ColorBy.country) {
colorScale = CategoricalColorNamespace.getScale(colorScheme);
const processedData = filteredData.map(d => ({
...d,
radius: radiusScale(Math.sqrt(d.m2)),
fillColor: colorScale(d.m1),
}));
processedData = filteredData.map(d => ({
...d,
radius: radiusScale(Math.sqrt(d.m2)),
fillColor: colorScale(d.name, sliceId),
}));
} else {
colorScale = getSequentialSchemeRegistry()
.get(linearColorScheme)
.createLinearScale(d3Extent(filteredData, d => d.m1));
processedData = filteredData.map(d => ({
...d,
radius: radiusScale(Math.sqrt(d.m2)),
fillColor: colorScale(d.m1),
}));
}
const mapData = {};
processedData.forEach(d => {

View File

@ -22,6 +22,7 @@ import {
formatSelectOptions,
sections,
} from '@superset-ui/chart-controls';
import { ColorBy } from './utils';
const config: ControlPanelConfig = {
controlPanelSections: [
@ -106,7 +107,25 @@ const config: ControlPanelConfig = {
},
],
['color_picker'],
[
{
name: 'color_by',
config: {
type: 'RadioButtonControl',
label: t('Color by'),
default: ColorBy.metric,
options: [
[ColorBy.metric, t('Metric')],
[ColorBy.country, t('Country')],
],
description: t(
'Choose whether a country should be shaded by the metric, or assigned a color based on a categorical color palette',
),
},
},
],
['linear_color_scheme'],
['color_scheme'],
],
},
],
@ -115,10 +134,6 @@ const config: ControlPanelConfig = {
label: t('Country Column'),
description: t('3 letter code of the country'),
},
metric: {
label: t('Metric for Color'),
description: t('Metric that defines the color of the country'),
},
secondary_metric: {
label: t('Bubble Size'),
description: t('Metric that defines the size of the bubble'),
@ -128,6 +143,13 @@ const config: ControlPanelConfig = {
},
linear_color_scheme: {
label: t('Country Color Scheme'),
visibility: ({ controls }) =>
Boolean(controls?.color_by.value === ColorBy.metric),
},
color_scheme: {
label: t('Country Color Scheme'),
visibility: ({ controls }) =>
Boolean(controls?.color_by.value === ColorBy.country),
},
},
};

View File

@ -20,8 +20,15 @@ import { rgb } from 'd3-color';
export default function transformProps(chartProps) {
const { width, height, formData, queriesData } = chartProps;
const { maxBubbleSize, showBubbles, linearColorScheme, colorPicker } =
formData;
const {
maxBubbleSize,
showBubbles,
linearColorScheme,
colorPicker,
colorBy,
colorScheme,
sliceId,
} = formData;
const { r, g, b } = colorPicker;
return {
@ -32,5 +39,8 @@ export default function transformProps(chartProps) {
showBubbles,
linearColorScheme,
color: rgb(r, g, b).hex(),
colorBy,
colorScheme,
sliceId,
};
}

View File

@ -0,0 +1,23 @@
/**
* 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.
*/
export enum ColorBy {
metric = 'metric',
country = 'country',
}