Skip to content

Commit

Permalink
fix(plugin-chart-echarts): gauge chart enhancements and fixes (apache…
Browse files Browse the repository at this point in the history
…#21007)

* fix(plugin-chart-echarts): gauge chart enhancements and fixes

* fix lint

(cherry picked from commit b303d1e)
  • Loading branch information
stephenLYZ authored and Fahrenheit35 committed Nov 11, 2022
1 parent 20492d0 commit e8737ba
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/
import React from 'react';
import { t, validateNonEmpty, validateInteger } from '@superset-ui/core';
import { t } from '@superset-ui/core';
import {
sharedControls,
ControlPanelConfig,
Expand Down Expand Up @@ -81,8 +81,7 @@ const config: ControlPanelConfig = {
config: {
type: 'TextControl',
isInt: true,
default: String(DEFAULT_FORM_DATA.minVal),
validators: [validateNonEmpty, validateInteger],
default: DEFAULT_FORM_DATA.minVal,
renderTrigger: true,
label: t('Min'),
description: t('Minimum value on the gauge axis'),
Expand All @@ -94,7 +93,6 @@ const config: ControlPanelConfig = {
type: 'TextControl',
isInt: true,
default: DEFAULT_FORM_DATA.maxVal,
validators: [validateNonEmpty, validateInteger],
renderTrigger: true,
label: t('Max'),
description: t('Maximum value on the gauge axis'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
} from '@superset-ui/core';
import { EChartsCoreOption, GaugeSeriesOption } from 'echarts';
import { GaugeDataItemOption } from 'echarts/types/src/chart/gauge/GaugeSeries';
import { CallbackDataParams } from 'echarts/types/src/util/types';
import range from 'lodash/range';
import { parseNumbersList } from '../utils/controls';
import {
Expand Down Expand Up @@ -80,6 +81,12 @@ const calculateAxisLineWidth = (
overlap: boolean,
): number => (overlap ? fontSize : data.length * fontSize);

const calculateMin = (data: GaugeDataItemOption[]) =>
2 * Math.min(...data.map(d => d.value as number).concat([0]));

const calculateMax = (data: GaugeDataItemOption[]) =>
2 * Math.max(...data.map(d => d.value as number).concat([0]));

export default function transformProps(
chartProps: EchartsGaugeChartProps,
): GaugeChartTransformedProps {
Expand Down Expand Up @@ -115,12 +122,7 @@ export default function transformProps(
const data = (queriesData[0]?.data || []) as DataRecord[];
const numberFormatter = getNumberFormatter(numberFormat);
const colorFn = CategoricalColorNamespace.getScale(colorScheme as string);
const normalizer = maxVal;
const axisLineWidth = calculateAxisLineWidth(data, fontSize, overlap);
const axisLabels = range(minVal, maxVal, (maxVal - minVal) / splitNumber);
const axisLabelLength = Math.max(
...axisLabels.map(label => numberFormatter(label).length).concat([1]),
);
const groupbyLabels = groupby.map(getColumnLabel);
const formatValue = (value: number) =>
valueFormatter.replace('{value}', numberFormatter(value));
Expand All @@ -130,12 +132,6 @@ export default function transformProps(
FONT_SIZE_MULTIPLIERS.titleOffsetFromTitle * fontSize;
const detailOffsetFromTitle =
FONT_SIZE_MULTIPLIERS.detailOffsetFromTitle * fontSize;
const intervalBoundsAndColors = setIntervalBoundsAndColors(
intervals,
intervalColorIndices,
colorFn,
normalizer,
);
const columnsLabelMap = new Map<string, DataRecordValue[]>();

const transformedData: GaugeDataItemOption[] = data.map(
Expand Down Expand Up @@ -196,6 +192,33 @@ export default function transformProps(

const { setDataMask = () => {} } = hooks;

const min = minVal ?? calculateMin(transformedData);
const max = maxVal ?? calculateMax(transformedData);
const axisLabels = range(min, max, (max - min) / splitNumber);
const axisLabelLength = Math.max(
...axisLabels.map(label => numberFormatter(label).length).concat([1]),
);
const normalizer = max;
const intervalBoundsAndColors = setIntervalBoundsAndColors(
intervals,
intervalColorIndices,
colorFn,
normalizer,
);
const splitLineDistance =
axisLineWidth + splitLineLength + OFFSETS.ticksFromLine;
const axisLabelDistance =
FONT_SIZE_MULTIPLIERS.axisLabelDistance *
fontSize *
FONT_SIZE_MULTIPLIERS.axisLabelLength *
axisLabelLength +
(showSplitLine ? splitLineLength : 0) +
(showAxisTick ? axisTickLength : 0) +
OFFSETS.ticksFromLine -
axisLineWidth;
const axisTickDistance =
axisLineWidth + axisTickLength + OFFSETS.ticksFromLine;

const progress = {
show: showProgress,
overlap,
Expand All @@ -204,7 +227,7 @@ export default function transformProps(
};
const splitLine = {
show: showSplitLine,
distance: -axisLineWidth - splitLineLength - OFFSETS.ticksFromLine,
distance: -splitLineDistance,
length: splitLineLength,
lineStyle: {
width: FONT_SIZE_MULTIPLIERS.splitLineWidth * fontSize,
Expand All @@ -219,22 +242,14 @@ export default function transformProps(
},
};
const axisLabel = {
distance:
axisLineWidth -
FONT_SIZE_MULTIPLIERS.axisLabelDistance *
fontSize *
FONT_SIZE_MULTIPLIERS.axisLabelLength *
axisLabelLength -
(showSplitLine ? splitLineLength : 0) -
(showAxisTick ? axisTickLength : 0) -
OFFSETS.ticksFromLine,
distance: -axisLabelDistance,
fontSize,
formatter: numberFormatter,
color: gaugeSeriesOptions.axisLabel?.color,
};
const axisTick = {
show: showAxisTick,
distance: -axisLineWidth - axisTickLength - OFFSETS.ticksFromLine,
distance: -axisTickDistance,
length: axisTickLength,
lineStyle: gaugeSeriesOptions.axisTick?.lineStyle as AxisTickLineStyle,
};
Expand All @@ -243,8 +258,14 @@ export default function transformProps(
formatter: (value: number) => formatValue(value),
color: gaugeSeriesOptions.detail?.color,
};
let pointer;
const tooltip = {
formatter: (params: CallbackDataParams) => {
const { name, value } = params;
return `${name} : ${formatValue(value as number)}`;
},
};

let pointer;
if (intervalBoundsAndColors.length) {
splitLine.lineStyle.color =
INTERVAL_GAUGE_SERIES_OPTION.splitLine?.lineStyle?.color;
Expand All @@ -269,8 +290,8 @@ export default function transformProps(
type: 'gauge',
startAngle,
endAngle,
min: minVal,
max: maxVal,
min,
max,
progress,
animation,
axisLine: axisLine as GaugeSeriesOption['axisLine'],
Expand All @@ -280,11 +301,19 @@ export default function transformProps(
axisTick,
pointer,
detail,
tooltip,
radius:
Math.min(width, height) / 2 - axisLabelDistance - axisTickDistance,
center: ['50%', '55%'],
data: transformedData,
},
];

const echartOptions: EChartsCoreOption = {
tooltip: {
appendToBody: true,
trigger: 'item',
},
series,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ export type EchartsGaugeFormData = QueryFormData & {
groupby: QueryFormColumn[];
metric?: string;
rowLimit: number;
minVal: number;
maxVal: number;
minVal: number | null;
maxVal: number | null;
fontSize: number;
numberFormat: string;
animation: boolean;
Expand All @@ -58,8 +58,8 @@ export const DEFAULT_FORM_DATA: Partial<EchartsGaugeFormData> = {
...DEFAULT_LEGEND_FORM_DATA,
groupby: [],
rowLimit: 10,
minVal: 0,
maxVal: 100,
minVal: null,
maxVal: null,
fontSize: 15,
numberFormat: 'SMART_NUMBER',
animation: true,
Expand Down

0 comments on commit e8737ba

Please sign in to comment.