mirror of
https://github.com/apache/superset.git
synced 2026-04-19 08:04:53 +00:00
feat: improve color consistency (save all labels) (#19038)
This commit is contained in:
@@ -63,6 +63,7 @@ export default function transformProps(
|
||||
xAxisTitleMargin,
|
||||
yAxisTitleMargin,
|
||||
yAxisTitlePosition,
|
||||
sliceId,
|
||||
} = formData as BoxPlotQueryFormData;
|
||||
const colorFn = CategoricalColorNamespace.getScale(colorScheme as string);
|
||||
const numberFormatter = getNumberFormatter(numberFormat);
|
||||
@@ -98,9 +99,9 @@ export default function transformProps(
|
||||
datum[`${metric}__outliers`],
|
||||
],
|
||||
itemStyle: {
|
||||
color: colorFn(groupbyLabel),
|
||||
color: colorFn(groupbyLabel, sliceId),
|
||||
opacity: isFiltered ? OpacityEnum.SemiTransparent : 0.6,
|
||||
borderColor: colorFn(groupbyLabel),
|
||||
borderColor: colorFn(groupbyLabel, sliceId),
|
||||
},
|
||||
};
|
||||
});
|
||||
@@ -138,7 +139,7 @@ export default function transformProps(
|
||||
},
|
||||
},
|
||||
itemStyle: {
|
||||
color: colorFn(groupbyLabel),
|
||||
color: colorFn(groupbyLabel, sliceId),
|
||||
opacity: isFiltered
|
||||
? OpacityEnum.SemiTransparent
|
||||
: OpacityEnum.NonTransparent,
|
||||
|
||||
@@ -103,6 +103,7 @@ export default function transformProps(
|
||||
showLabels,
|
||||
showLegend,
|
||||
emitFilter,
|
||||
sliceId,
|
||||
}: EchartsFunnelFormData = {
|
||||
...DEFAULT_LEGEND_FORM_DATA,
|
||||
...DEFAULT_FUNNEL_FORM_DATA,
|
||||
@@ -145,7 +146,7 @@ export default function transformProps(
|
||||
value: datum[metricLabel],
|
||||
name,
|
||||
itemStyle: {
|
||||
color: colorFn(name),
|
||||
color: colorFn(name, sliceId),
|
||||
opacity: isFiltered
|
||||
? OpacityEnum.SemiTransparent
|
||||
: OpacityEnum.NonTransparent,
|
||||
|
||||
@@ -107,6 +107,7 @@ export default function transformProps(
|
||||
intervalColorIndices,
|
||||
valueFormatter,
|
||||
emitFilter,
|
||||
sliceId,
|
||||
}: EchartsGaugeFormData = { ...DEFAULT_GAUGE_FORM_DATA, ...formData };
|
||||
const data = (queriesData[0]?.data || []) as DataRecord[];
|
||||
const numberFormatter = getNumberFormatter(numberFormat);
|
||||
@@ -147,7 +148,7 @@ export default function transformProps(
|
||||
value: data_point[getMetricLabel(metric as QueryFormMetric)] as number,
|
||||
name,
|
||||
itemStyle: {
|
||||
color: colorFn(index),
|
||||
color: colorFn(index, sliceId),
|
||||
},
|
||||
title: {
|
||||
offsetCenter: [
|
||||
@@ -175,7 +176,7 @@ export default function transformProps(
|
||||
item = {
|
||||
...item,
|
||||
itemStyle: {
|
||||
color: colorFn(index),
|
||||
color: colorFn(index, sliceId),
|
||||
opacity: OpacityEnum.SemiTransparent,
|
||||
},
|
||||
detail: {
|
||||
|
||||
@@ -184,6 +184,7 @@ export default function transformProps(chartProps: ChartProps): EchartsProps {
|
||||
baseEdgeWidth,
|
||||
baseNodeSize,
|
||||
edgeSymbol,
|
||||
sliceId,
|
||||
}: EchartsGraphFormData = { ...DEFAULT_GRAPH_FORM_DATA, ...formData };
|
||||
|
||||
const metricLabel = getMetricLabel(metric);
|
||||
@@ -264,7 +265,7 @@ export default function transformProps(chartProps: ChartProps): EchartsProps {
|
||||
type: 'graph',
|
||||
categories: categoryList.map(c => ({
|
||||
name: c,
|
||||
itemStyle: { color: colorFn(c) },
|
||||
itemStyle: { color: colorFn(c, sliceId) },
|
||||
})),
|
||||
layout,
|
||||
force: {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { QueryFormData } from '@superset-ui/core';
|
||||
import { GraphNodeItemOption } from 'echarts/types/src/chart/graph/GraphSeries';
|
||||
import { SeriesTooltipOption } from 'echarts/types/src/util/types';
|
||||
import {
|
||||
@@ -27,32 +28,34 @@ import {
|
||||
|
||||
export type EdgeSymbol = 'none' | 'circle' | 'arrow';
|
||||
|
||||
export type EchartsGraphFormData = EchartsLegendFormData & {
|
||||
source: string;
|
||||
target: string;
|
||||
sourceCategory?: string;
|
||||
targetCategory?: string;
|
||||
colorScheme?: string;
|
||||
metric?: string;
|
||||
layout?: 'none' | 'circular' | 'force';
|
||||
roam: boolean | 'scale' | 'move';
|
||||
draggable: boolean;
|
||||
selectedMode?: boolean | 'multiple' | 'single';
|
||||
showSymbolThreshold: number;
|
||||
repulsion: number;
|
||||
gravity: number;
|
||||
baseNodeSize: number;
|
||||
baseEdgeWidth: number;
|
||||
edgeLength: number;
|
||||
edgeSymbol: string;
|
||||
friction: number;
|
||||
};
|
||||
export type EchartsGraphFormData = QueryFormData &
|
||||
EchartsLegendFormData & {
|
||||
source: string;
|
||||
target: string;
|
||||
sourceCategory?: string;
|
||||
targetCategory?: string;
|
||||
colorScheme?: string;
|
||||
metric?: string;
|
||||
layout?: 'none' | 'circular' | 'force';
|
||||
roam: boolean | 'scale' | 'move';
|
||||
draggable: boolean;
|
||||
selectedMode?: boolean | 'multiple' | 'single';
|
||||
showSymbolThreshold: number;
|
||||
repulsion: number;
|
||||
gravity: number;
|
||||
baseNodeSize: number;
|
||||
baseEdgeWidth: number;
|
||||
edgeLength: number;
|
||||
edgeSymbol: string;
|
||||
friction: number;
|
||||
};
|
||||
|
||||
export type EChartGraphNode = Omit<GraphNodeItemOption, 'value'> & {
|
||||
value: number;
|
||||
tooltip?: Pick<SeriesTooltipOption, 'formatter'>;
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
export const DEFAULT_FORM_DATA: EchartsGraphFormData = {
|
||||
...DEFAULT_LEGEND_FORM_DATA,
|
||||
source: '',
|
||||
|
||||
@@ -128,6 +128,7 @@ export default function transformProps(
|
||||
xAxisTitleMargin,
|
||||
yAxisTitleMargin,
|
||||
yAxisTitlePosition,
|
||||
sliceId,
|
||||
}: EchartsMixedTimeseriesFormData = { ...DEFAULT_FORM_DATA, ...formData };
|
||||
|
||||
const colorScale = CategoricalColorNamespace.getScale(colorScheme as string);
|
||||
@@ -177,6 +178,7 @@ export default function transformProps(
|
||||
yAxisIndex,
|
||||
filterState,
|
||||
seriesKey: entry.name,
|
||||
sliceId,
|
||||
});
|
||||
if (transformedSeries) series.push(transformedSeries);
|
||||
});
|
||||
@@ -195,6 +197,7 @@ export default function transformProps(
|
||||
seriesKey: primarySeries.has(entry.name as string)
|
||||
? `${entry.name} (1)`
|
||||
: entry.name,
|
||||
sliceId,
|
||||
});
|
||||
if (transformedSeries) series.push(transformedSeries);
|
||||
});
|
||||
@@ -203,7 +206,9 @@ export default function transformProps(
|
||||
.filter((layer: AnnotationLayer) => layer.show)
|
||||
.forEach((layer: AnnotationLayer) => {
|
||||
if (isFormulaAnnotationLayer(layer))
|
||||
series.push(transformFormulaAnnotation(layer, data1, colorScale));
|
||||
series.push(
|
||||
transformFormulaAnnotation(layer, data1, colorScale, sliceId),
|
||||
);
|
||||
else if (isIntervalAnnotationLayer(layer)) {
|
||||
series.push(
|
||||
...transformIntervalAnnotation(
|
||||
@@ -211,11 +216,18 @@ export default function transformProps(
|
||||
data1,
|
||||
annotationData,
|
||||
colorScale,
|
||||
sliceId,
|
||||
),
|
||||
);
|
||||
} else if (isEventAnnotationLayer(layer)) {
|
||||
series.push(
|
||||
...transformEventAnnotation(layer, data1, annotationData, colorScale),
|
||||
...transformEventAnnotation(
|
||||
layer,
|
||||
data1,
|
||||
annotationData,
|
||||
colorScale,
|
||||
sliceId,
|
||||
),
|
||||
);
|
||||
} else if (isTimeseriesAnnotationLayer(layer)) {
|
||||
series.push(
|
||||
|
||||
@@ -109,6 +109,7 @@ export default function transformProps(
|
||||
showLegend,
|
||||
showLabelsThreshold,
|
||||
emitFilter,
|
||||
sliceId,
|
||||
}: EchartsPieFormData = {
|
||||
...DEFAULT_LEGEND_FORM_DATA,
|
||||
...DEFAULT_PIE_FORM_DATA,
|
||||
@@ -162,7 +163,7 @@ export default function transformProps(
|
||||
value: datum[metricLabel],
|
||||
name,
|
||||
itemStyle: {
|
||||
color: colorFn(name),
|
||||
color: colorFn(name, sliceId),
|
||||
opacity: isFiltered
|
||||
? OpacityEnum.SemiTransparent
|
||||
: OpacityEnum.NonTransparent,
|
||||
|
||||
@@ -91,6 +91,7 @@ export default function transformProps(
|
||||
showLegend,
|
||||
isCircle,
|
||||
columnConfig,
|
||||
sliceId,
|
||||
}: EchartsRadarFormData = {
|
||||
...DEFAULT_LEGEND_FORM_DATA,
|
||||
...DEFAULT_RADAR_FORM_DATA,
|
||||
@@ -154,7 +155,7 @@ export default function transformProps(
|
||||
value: metricLabels.map(metricLabel => datum[metricLabel]),
|
||||
name: joinedName,
|
||||
itemStyle: {
|
||||
color: colorFn(joinedName),
|
||||
color: colorFn(joinedName, sliceId),
|
||||
opacity: isFiltered
|
||||
? OpacityEnum.Transparent
|
||||
: OpacityEnum.NonTransparent,
|
||||
|
||||
@@ -125,6 +125,7 @@ export default function transformProps(
|
||||
xAxisTitleMargin,
|
||||
yAxisTitleMargin,
|
||||
yAxisTitlePosition,
|
||||
sliceId,
|
||||
}: EchartsTimeseriesFormData = { ...DEFAULT_FORM_DATA, ...formData };
|
||||
|
||||
const colorScale = CategoricalColorNamespace.getScale(colorScheme as string);
|
||||
@@ -198,6 +199,7 @@ export default function transformProps(
|
||||
showValueIndexes,
|
||||
thresholdValues,
|
||||
richTooltip,
|
||||
sliceId,
|
||||
});
|
||||
if (transformedSeries) series.push(transformedSeries);
|
||||
});
|
||||
@@ -217,7 +219,9 @@ export default function transformProps(
|
||||
.filter((layer: AnnotationLayer) => layer.show)
|
||||
.forEach((layer: AnnotationLayer) => {
|
||||
if (isFormulaAnnotationLayer(layer))
|
||||
series.push(transformFormulaAnnotation(layer, data, colorScale));
|
||||
series.push(
|
||||
transformFormulaAnnotation(layer, data, colorScale, sliceId),
|
||||
);
|
||||
else if (isIntervalAnnotationLayer(layer)) {
|
||||
series.push(
|
||||
...transformIntervalAnnotation(
|
||||
@@ -225,11 +229,18 @@ export default function transformProps(
|
||||
data,
|
||||
annotationData,
|
||||
colorScale,
|
||||
sliceId,
|
||||
),
|
||||
);
|
||||
} else if (isEventAnnotationLayer(layer)) {
|
||||
series.push(
|
||||
...transformEventAnnotation(layer, data, annotationData, colorScale),
|
||||
...transformEventAnnotation(
|
||||
layer,
|
||||
data,
|
||||
annotationData,
|
||||
colorScale,
|
||||
sliceId,
|
||||
),
|
||||
);
|
||||
} else if (isTimeseriesAnnotationLayer(layer)) {
|
||||
series.push(
|
||||
|
||||
@@ -84,6 +84,7 @@ export function transformSeries(
|
||||
thresholdValues?: number[];
|
||||
richTooltip?: boolean;
|
||||
seriesKey?: OptionName;
|
||||
sliceId?: number;
|
||||
},
|
||||
): SeriesOption | undefined {
|
||||
const { name } = series;
|
||||
@@ -105,6 +106,7 @@ export function transformSeries(
|
||||
thresholdValues = [],
|
||||
richTooltip,
|
||||
seriesKey,
|
||||
sliceId,
|
||||
} = opts;
|
||||
const contexts = seriesContexts[name || ''] || [];
|
||||
const hasForecast =
|
||||
@@ -151,7 +153,7 @@ export function transformSeries(
|
||||
}
|
||||
// forcing the colorScale to return a different color for same metrics across different queries
|
||||
const itemStyle = {
|
||||
color: colorScale(seriesKey || forecastSeries.name),
|
||||
color: colorScale(seriesKey || forecastSeries.name, sliceId),
|
||||
opacity,
|
||||
};
|
||||
let emphasis = {};
|
||||
@@ -244,13 +246,14 @@ export function transformFormulaAnnotation(
|
||||
layer: FormulaAnnotationLayer,
|
||||
data: TimeseriesDataRecord[],
|
||||
colorScale: CategoricalColorScale,
|
||||
sliceId?: number,
|
||||
): SeriesOption {
|
||||
const { name, color, opacity, width, style } = layer;
|
||||
return {
|
||||
name,
|
||||
id: name,
|
||||
itemStyle: {
|
||||
color: color || colorScale(name),
|
||||
color: color || colorScale(name, sliceId),
|
||||
},
|
||||
lineStyle: {
|
||||
opacity: parseAnnotationOpacity(opacity),
|
||||
@@ -269,6 +272,7 @@ export function transformIntervalAnnotation(
|
||||
data: TimeseriesDataRecord[],
|
||||
annotationData: AnnotationData,
|
||||
colorScale: CategoricalColorScale,
|
||||
sliceId?: number,
|
||||
): SeriesOption[] {
|
||||
const series: SeriesOption[] = [];
|
||||
const annotations = extractRecordAnnotations(layer, annotationData);
|
||||
@@ -323,7 +327,7 @@ export function transformIntervalAnnotation(
|
||||
markArea: {
|
||||
silent: false,
|
||||
itemStyle: {
|
||||
color: color || colorScale(name),
|
||||
color: color || colorScale(name, sliceId),
|
||||
opacity: parseAnnotationOpacity(opacity || AnnotationOpacity.Medium),
|
||||
emphasis: {
|
||||
opacity: 0.8,
|
||||
@@ -342,6 +346,7 @@ export function transformEventAnnotation(
|
||||
data: TimeseriesDataRecord[],
|
||||
annotationData: AnnotationData,
|
||||
colorScale: CategoricalColorScale,
|
||||
sliceId?: number,
|
||||
): SeriesOption[] {
|
||||
const series: SeriesOption[] = [];
|
||||
const annotations = extractRecordAnnotations(layer, annotationData);
|
||||
@@ -359,7 +364,7 @@ export function transformEventAnnotation(
|
||||
const lineStyle: LineStyleOption & DefaultStatesMixin['emphasis'] = {
|
||||
width,
|
||||
type: style as ZRLineType,
|
||||
color: color || colorScale(name),
|
||||
color: color || colorScale(name, sliceId),
|
||||
opacity: parseAnnotationOpacity(opacity),
|
||||
emphasis: {
|
||||
width: width ? width + 1 : width,
|
||||
|
||||
@@ -127,6 +127,7 @@ export default function transformProps(
|
||||
showUpperLabels,
|
||||
dashboardId,
|
||||
emitFilter,
|
||||
sliceId,
|
||||
}: EchartsTreemapFormData = {
|
||||
...DEFAULT_TREEMAP_FORM_DATA,
|
||||
...formData,
|
||||
@@ -223,7 +224,7 @@ export default function transformProps(
|
||||
colorSaturation: COLOR_SATURATION,
|
||||
itemStyle: {
|
||||
borderColor: BORDER_COLOR,
|
||||
color: colorFn(`${child.name}`),
|
||||
color: colorFn(`${child.name}`, sliceId),
|
||||
borderWidth: BORDER_WIDTH,
|
||||
gapWidth: GAP_WIDTH,
|
||||
},
|
||||
@@ -259,7 +260,7 @@ export default function transformProps(
|
||||
show: false,
|
||||
},
|
||||
itemStyle: {
|
||||
color: CategoricalColorNamespace.getColor(),
|
||||
color: '#1FA8C9',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user