mirror of https://github.com/apache/superset.git
fix: Drill to detail on values with comma (#21151)
This commit is contained in:
parent
bdcc0a9bcf
commit
0bf4e56dc3
|
@ -39,12 +39,12 @@ export type QueryObjectFilterClause = {
|
|||
} & (
|
||||
| {
|
||||
op: BinaryOperator;
|
||||
val: string | number | boolean;
|
||||
val: string | number | boolean | null | Date;
|
||||
formattedVal?: string;
|
||||
}
|
||||
| {
|
||||
op: SetOperator;
|
||||
val: (string | number | boolean)[];
|
||||
val: (string | number | boolean | null | Date)[];
|
||||
formattedVal?: string[];
|
||||
}
|
||||
| {
|
||||
|
|
|
@ -83,6 +83,7 @@ export interface ChartDataResponseResult {
|
|||
export interface TimeseriesChartDataResponseResult
|
||||
extends ChartDataResponseResult {
|
||||
data: TimeseriesDataRecord[];
|
||||
label_map: Record<string, DataRecordValue[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,22 +17,21 @@
|
|||
* under the License.
|
||||
*/
|
||||
import React, { useCallback } from 'react';
|
||||
import { QueryObjectFilterClause } from '@superset-ui/core';
|
||||
import { GaugeChartTransformedProps } from './types';
|
||||
import Echart from '../components/Echart';
|
||||
import { Event, clickEventHandler } from '../utils/eventHandlers';
|
||||
import { allEventHandlers } from '../utils/eventHandlers';
|
||||
|
||||
export default function EchartsGauge({
|
||||
height,
|
||||
width,
|
||||
echartOptions,
|
||||
setDataMask,
|
||||
labelMap,
|
||||
groupby,
|
||||
selectedValues,
|
||||
formData: { emitFilter },
|
||||
onContextMenu,
|
||||
}: GaugeChartTransformedProps) {
|
||||
export default function EchartsGauge(props: GaugeChartTransformedProps) {
|
||||
const {
|
||||
height,
|
||||
width,
|
||||
echartOptions,
|
||||
setDataMask,
|
||||
labelMap,
|
||||
groupby,
|
||||
selectedValues,
|
||||
formData: { emitFilter },
|
||||
} = props;
|
||||
const handleChange = useCallback(
|
||||
(values: string[]) => {
|
||||
if (!emitFilter) {
|
||||
|
@ -69,28 +68,7 @@ export default function EchartsGauge({
|
|||
[groupby, labelMap, setDataMask, selectedValues],
|
||||
);
|
||||
|
||||
const eventHandlers = {
|
||||
click: clickEventHandler(selectedValues, handleChange),
|
||||
contextmenu: (e: Event) => {
|
||||
if (onContextMenu) {
|
||||
e.event.stop();
|
||||
const pointerEvent = e.event.event;
|
||||
const filters: QueryObjectFilterClause[] = [];
|
||||
if (groupby.length > 0) {
|
||||
const values = e.name.split(',');
|
||||
groupby.forEach((dimension, i) =>
|
||||
filters.push({
|
||||
col: dimension,
|
||||
op: '==',
|
||||
val: values[i].split(': ')[1],
|
||||
formattedVal: values[i].split(': ')[1],
|
||||
}),
|
||||
);
|
||||
}
|
||||
onContextMenu(filters, pointerEvent.offsetX, pointerEvent.offsetY);
|
||||
}
|
||||
},
|
||||
};
|
||||
const eventHandlers = allEventHandlers(props, handleChange);
|
||||
|
||||
return (
|
||||
<Echart
|
||||
|
|
|
@ -116,7 +116,7 @@ export default function EchartsMixedTimeseries({
|
|||
const { data, seriesIndex } = eventParams;
|
||||
if (data) {
|
||||
const pointerEvent = eventParams.event.event;
|
||||
const values = eventParams.seriesName.split(',');
|
||||
const values = labelMap[eventParams.seriesName];
|
||||
const { queryIndex } = (echartOptions.series as any)[seriesIndex];
|
||||
const groupby = queryIndex > 0 ? formData.groupbyB : formData.groupby;
|
||||
const filters: QueryObjectFilterClause[] = [];
|
||||
|
@ -132,7 +132,7 @@ export default function EchartsMixedTimeseries({
|
|||
col: dimension,
|
||||
op: '==',
|
||||
val: values[i],
|
||||
formattedVal: values[i],
|
||||
formattedVal: String(values[i]),
|
||||
}),
|
||||
);
|
||||
onContextMenu(filters, pointerEvent.offsetX, pointerEvent.offsetY);
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
import {
|
||||
AnnotationLayer,
|
||||
CategoricalColorNamespace,
|
||||
DataRecordValue,
|
||||
DTTM_ALIAS,
|
||||
GenericDataType,
|
||||
getColumnLabel,
|
||||
|
@ -29,6 +28,7 @@ import {
|
|||
isFormulaAnnotationLayer,
|
||||
isIntervalAnnotationLayer,
|
||||
isTimeseriesAnnotationLayer,
|
||||
TimeseriesChartDataResponseResult,
|
||||
TimeseriesDataRecord,
|
||||
} from '@superset-ui/core';
|
||||
import { EChartsCoreOption, SeriesOption } from 'echarts';
|
||||
|
@ -90,6 +90,10 @@ export default function transformProps(
|
|||
inContextMenu,
|
||||
} = chartProps;
|
||||
const { verboseMap = {} } = datasource;
|
||||
const { label_map: labelMap } =
|
||||
queriesData[0] as TimeseriesChartDataResponseResult;
|
||||
const { label_map: labelMapB } =
|
||||
queriesData[1] as TimeseriesChartDataResponseResult;
|
||||
const data1 = (queriesData[0].data || []) as TimeseriesDataRecord[];
|
||||
const data2 = (queriesData[1].data || []) as TimeseriesDataRecord[];
|
||||
const annotationData = getAnnotationData(chartProps);
|
||||
|
@ -352,21 +356,6 @@ export default function transformProps(
|
|||
convertInteger(yAxisTitleMargin),
|
||||
convertInteger(xAxisTitleMargin),
|
||||
);
|
||||
const labelMap = rawSeriesA.reduce((acc, datum) => {
|
||||
const label = datum.name as string;
|
||||
return {
|
||||
...acc,
|
||||
[label]: label.split(', '),
|
||||
};
|
||||
}, {}) as Record<string, DataRecordValue[]>;
|
||||
|
||||
const labelMapB = rawSeriesB.reduce((acc, datum) => {
|
||||
const label = datum.name as string;
|
||||
return {
|
||||
...acc,
|
||||
[label]: label.split(', '),
|
||||
};
|
||||
}, {}) as Record<string, DataRecordValue[]>;
|
||||
|
||||
const { setDataMask = () => {}, onContextMenu } = hooks;
|
||||
const alignTicks = yAxisIndex !== yAxisIndexB;
|
||||
|
|
|
@ -182,7 +182,7 @@ export default function EchartsTimeseries({
|
|||
const { data } = eventParams;
|
||||
if (data) {
|
||||
const pointerEvent = eventParams.event.event;
|
||||
const values = eventParams.seriesName.split(',');
|
||||
const values = labelMap[eventParams.seriesName];
|
||||
const filters: QueryObjectFilterClause[] = [];
|
||||
filters.push({
|
||||
col: formData.granularitySqla,
|
||||
|
@ -196,7 +196,7 @@ export default function EchartsTimeseries({
|
|||
col: dimension,
|
||||
op: '==',
|
||||
val: values[i],
|
||||
formattedVal: values[i],
|
||||
formattedVal: String(values[i]),
|
||||
}),
|
||||
);
|
||||
onContextMenu(filters, pointerEvent.offsetX, pointerEvent.offsetY);
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
import {
|
||||
AnnotationLayer,
|
||||
CategoricalColorNamespace,
|
||||
DataRecordValue,
|
||||
DTTM_ALIAS,
|
||||
GenericDataType,
|
||||
getColumnLabel,
|
||||
|
@ -101,7 +100,8 @@ export default function transformProps(
|
|||
} = chartProps;
|
||||
const { verboseMap = {} } = datasource;
|
||||
const [queryData] = queriesData;
|
||||
const { data = [] } = queryData as TimeseriesChartDataResponseResult;
|
||||
const { data = [], label_map: labelMap } =
|
||||
queryData as TimeseriesChartDataResponseResult;
|
||||
const dataTypes = getColtypesMapping(queryData);
|
||||
const annotationData = getAnnotationData(chartProps);
|
||||
|
||||
|
@ -291,20 +291,9 @@ export default function transformProps(
|
|||
? getXAxisFormatter(xAxisTimeFormat)
|
||||
: String;
|
||||
|
||||
const labelMap = series.reduce(
|
||||
(acc: Record<string, DataRecordValue[]>, datum) => {
|
||||
const name: string = datum.name as string;
|
||||
return {
|
||||
...acc,
|
||||
[name]: [name],
|
||||
};
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
const {
|
||||
setDataMask = () => {},
|
||||
setControlValue = (...args: unknown[]) => {},
|
||||
setControlValue = () => {},
|
||||
onContextMenu,
|
||||
} = hooks;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { QueryObjectFilterClause } from '@superset-ui/core';
|
||||
import { DataRecordValue, QueryObjectFilterClause } from '@superset-ui/core';
|
||||
import { EChartTransformedProps, EventHandlers } from '../types';
|
||||
|
||||
export type Event = {
|
||||
|
@ -42,6 +42,7 @@ export const contextMenuEventHandler =
|
|||
(
|
||||
groupby: EChartTransformedProps<any>['groupby'],
|
||||
onContextMenu: EChartTransformedProps<any>['onContextMenu'],
|
||||
labelMap: Record<string, DataRecordValue[]>,
|
||||
) =>
|
||||
(e: Event) => {
|
||||
if (onContextMenu) {
|
||||
|
@ -49,13 +50,13 @@ export const contextMenuEventHandler =
|
|||
const pointerEvent = e.event.event;
|
||||
const filters: QueryObjectFilterClause[] = [];
|
||||
if (groupby.length > 0) {
|
||||
const values = e.name.split(',');
|
||||
const values = labelMap[e.name];
|
||||
groupby.forEach((dimension, i) =>
|
||||
filters.push({
|
||||
col: dimension,
|
||||
op: '==',
|
||||
val: values[i],
|
||||
formattedVal: values[i],
|
||||
formattedVal: String(values[i]),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -67,10 +68,10 @@ export const allEventHandlers = (
|
|||
transformedProps: EChartTransformedProps<any>,
|
||||
handleChange: (values: string[]) => void,
|
||||
) => {
|
||||
const { groupby, selectedValues, onContextMenu } = transformedProps;
|
||||
const { groupby, selectedValues, onContextMenu, labelMap } = transformedProps;
|
||||
const eventHandlers: EventHandlers = {
|
||||
click: clickEventHandler(selectedValues, handleChange),
|
||||
contextmenu: contextMenuEventHandler(groupby, onContextMenu),
|
||||
contextmenu: contextMenuEventHandler(groupby, onContextMenu, labelMap),
|
||||
};
|
||||
return eventHandlers;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue