Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(plugin-chart-echarts): support horizontal bar chart #19918

Merged
merged 9 commits into from
May 16, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
import {
DEFAULT_FORM_DATA,
EchartsTimeseriesContributionType,
EchartsOrientType,
} from '../../types';
import {
legendSection,
Expand All @@ -49,6 +50,7 @@ const {
yAxisBounds,
zoomable,
xAxisLabelRotation,
orient,
} = DEFAULT_FORM_DATA;
const config: ControlPanelConfig = {
controlPanelSections: [
Expand Down Expand Up @@ -87,6 +89,28 @@ const config: ControlPanelConfig = {
sections.advancedAnalyticsControls,
sections.annotationsAndLayersControls,
sections.forecastIntervalControls,
{
label: t('Chart Orient'),
stephenLYZ marked this conversation as resolved.
Show resolved Hide resolved
expanded: true,
controlSetRows: [
[
{
name: 'bar_orient',
stephenLYZ marked this conversation as resolved.
Show resolved Hide resolved
config: {
type: 'RadioButtonControl',
renderTrigger: true,
label: t('Bar orientation'),
default: orient,
options: [
[EchartsOrientType.vertical, t('Vertical')],
[EchartsOrientType.horizontal, t('Horizontal')],
],
description: t('Orientation of bar chart'),
},
},
],
],
},
sections.titleControls,
{
label: t('Chart Options'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import {
EchartsTimeseriesSeriesType,
TimeseriesChartTransformedProps,
} from './types';
import { ForecastSeriesEnum, ForecastValue } from '../types';
import { ForecastSeriesEnum, ForecastValue, EchartsOrientType } from '../types';
import { parseYAxisBound } from '../utils/controls';
import {
currentSeries,
Expand Down Expand Up @@ -136,15 +136,18 @@ export default function transformProps(
yAxisTitlePosition,
sliceId,
timeGrainSqla,
barOrient,
}: EchartsTimeseriesFormData = { ...DEFAULT_FORM_DATA, ...formData };

const colorScale = CategoricalColorNamespace.getScale(colorScheme as string);
const rebasedData = rebaseForecastDatum(data, verboseMap);
const xAxisCol = verboseMap[xAxisOrig] || xAxisOrig || DTTM_ALIAS;
const isHorizontal = barOrient === EchartsOrientType.horizontal;
const rawSeries = extractSeries(rebasedData, {
fillNeighborValue: stack && !forecastEnabled ? 0 : undefined,
xAxis: xAxisCol,
removeNulls: seriesType === EchartsTimeseriesSeriesType.Scatter,
isHorizontal,
});
const seriesContexts = extractForecastSeriesContexts(
Object.values(rawSeries).map(series => series.name as string),
Expand Down Expand Up @@ -210,6 +213,7 @@ export default function transformProps(
thresholdValues,
richTooltip,
sliceId,
isHorizontal,
});
if (transformedSeries) series.push(transformedSeries);
});
Expand Down Expand Up @@ -318,57 +322,68 @@ export default function transformProps(
.map(entry => entry.name || '')
.concat(extractAnnotationLabels(annotationLayers, annotationData));

let xAxis: any = {
type: xAxisType,
name: xAxisTitle,
nameGap: convertInteger(xAxisTitleMargin),
nameLocation: 'middle',
axisLabel: {
hideOverlap: true,
formatter: xAxisFormatter,
rotate: xAxisLabelRotation,
},
minInterval:
xAxisType === 'time' && timeGrainSqla
? TimeGrainToTimestamp[timeGrainSqla]
: 0,
};
let yAxis: any = {
...defaultYAxis,
type: logAxis ? 'log' : 'value',
min,
max,
minorTick: { show: true },
minorSplitLine: { show: minorSplitLine },
axisLabel: { formatter },
scale: truncateYAxis,
name: yAxisTitle,
nameGap: convertInteger(yAxisTitleMargin),
nameLocation: yAxisTitlePosition === 'Left' ? 'middle' : 'end',
};

if (isHorizontal) {
const temp = xAxis;
xAxis = yAxis;
yAxis = temp;
stephenLYZ marked this conversation as resolved.
Show resolved Hide resolved
}

const echartOptions: EChartsCoreOption = {
useUTC: true,
grid: {
...defaultGrid,
...padding,
},
xAxis: {
type: xAxisType,
name: xAxisTitle,
nameGap: convertInteger(xAxisTitleMargin),
nameLocation: 'middle',
axisLabel: {
hideOverlap: true,
formatter: xAxisFormatter,
rotate: xAxisLabelRotation,
},
minInterval:
xAxisType === 'time' && timeGrainSqla
? TimeGrainToTimestamp[timeGrainSqla]
: 0,
},
yAxis: {
...defaultYAxis,
type: logAxis ? 'log' : 'value',
min,
max,
minorTick: { show: true },
minorSplitLine: { show: minorSplitLine },
axisLabel: { formatter },
scale: truncateYAxis,
name: yAxisTitle,
nameGap: convertInteger(yAxisTitleMargin),
nameLocation: yAxisTitlePosition === 'Left' ? 'middle' : 'end',
},
xAxis,
yAxis,
tooltip: {
...defaultTooltip,
appendToBody: true,
trigger: richTooltip ? 'axis' : 'item',
formatter: (params: any) => {
const xIndex = isHorizontal ? 1 : 0;
const yIndex = isHorizontal ? 0 : 1;
stephenLYZ marked this conversation as resolved.
Show resolved Hide resolved
const xValue: number = richTooltip
? params[0].value[0]
: params.value[0];
? params[0].value[xIndex]
: params.value[xIndex];
const forecastValue: any[] = richTooltip ? params : [params];

if (richTooltip && tooltipSortByMetric) {
forecastValue.sort((a, b) => b.data[1] - a.data[1]);
forecastValue.sort((a, b) => b.data[yIndex] - a.data[yIndex]);
}

const rows: Array<string> = [`${tooltipFormatter(xValue)}`];
const forecastValues: Record<string, ForecastValue> =
extractForecastValuesFromTooltipParams(forecastValue);
extractForecastValuesFromTooltipParams(forecastValue, isHorizontal);

Object.keys(forecastValues).forEach(key => {
const value = forecastValues[key];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export function transformSeries(
richTooltip?: boolean;
seriesKey?: OptionName;
sliceId?: number;
isHorizontal?: boolean;
},
): SeriesOption | undefined {
const { name } = series;
Expand All @@ -107,6 +108,7 @@ export function transformSeries(
richTooltip,
seriesKey,
sliceId,
isHorizontal = false,
} = opts;
const contexts = seriesContexts[name || ''] || [];
const hasForecast =
Expand Down Expand Up @@ -216,14 +218,10 @@ export function transformSeries(
symbolSize: markerSize,
label: {
show: !!showValue,
position: 'top',
position: isHorizontal ? 'right' : 'top',
formatter: (params: any) => {
const {
value: [, numericValue],
dataIndex,
seriesIndex,
seriesName,
} = params;
const { value, dataIndex, seriesIndex, seriesName } = params;
const numericValue = isHorizontal ? value[0] : value[1];
const isSelectedLegend = currentSeries.legend === seriesName;
if (!formatter) return numericValue;
if (!stack || isSelectedLegend) return formatter(numericValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ export enum EchartsTimeseriesContributionType {
Column = 'column',
}

export enum EchartsOrientType {
stephenLYZ marked this conversation as resolved.
Show resolved Hide resolved
vertical = 'vertical',
horizontal = 'horizontal',
}

export enum EchartsTimeseriesSeriesType {
Line = 'line',
Scatter = 'scatter',
Expand Down Expand Up @@ -82,6 +87,7 @@ export type EchartsTimeseriesFormData = QueryFormData & {
showValue: boolean;
onlyTotal: boolean;
percentageThreshold: number;
barOrient?: EchartsOrientType;
} & EchartsLegendFormData &
EchartsTitleFormData;

Expand Down Expand Up @@ -119,6 +125,7 @@ export const DEFAULT_FORM_DATA: EchartsTimeseriesFormData = {
showValue: false,
onlyTotal: false,
percentageThreshold: 0,
orient: EchartsOrientType.vertical,
...DEFAULT_TITLE_FORM_DATA,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ export const extractForecastSeriesContexts = (

export const extractForecastValuesFromTooltipParams = (
params: any[],
isHorizontal = false,
): Record<string, ForecastValue> => {
const values: Record<string, ForecastValue> = {};
params.forEach(param => {
const { marker, seriesId, value } = param;
const context = extractForecastSeriesContext(seriesId);
const numericValue = (value as [Date, number])[1];
const numericValue = isHorizontal ? value[0] : value[1];
if (numericValue) {
if (!(context.name in values))
values[context.name] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,15 @@ export function extractSeries(
fillNeighborValue?: number;
xAxis?: string;
removeNulls?: boolean;
isHorizontal?: boolean;
} = {},
): SeriesOption[] {
const { fillNeighborValue, xAxis = DTTM_ALIAS, removeNulls = false } = opts;
const {
fillNeighborValue,
xAxis = DTTM_ALIAS,
removeNulls = false,
isHorizontal = false,
} = opts;
if (data.length === 0) return [];
const rows: DataRecord[] = data.map(datum => ({
...datum,
Expand All @@ -69,7 +75,8 @@ export function extractSeries(
: row[key],
];
})
.filter(obs => !removeNulls || (obs[0] !== null && obs[1] !== null)),
.filter(obs => !removeNulls || (obs[0] !== null && obs[1] !== null))
.map(obs => (isHorizontal ? [obs[1], obs[0]] : obs)),
}));
}

Expand Down