You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by li...@apache.org on 2023/04/27 16:17:41 UTC
[superset] branch master updated: feat: format timestamps in drill by breadcrumbs (#23698)
This is an automated email from the ASF dual-hosted git repository.
lilykuang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 0bf8907f2f feat: format timestamps in drill by breadcrumbs (#23698)
0bf8907f2f is described below
commit 0bf8907f2f6d7a17a1e3efa1c03a5af06daa8190
Author: Lily Kuang <li...@preset.io>
AuthorDate: Thu Apr 27 09:17:33 2023 -0700
feat: format timestamps in drill by breadcrumbs (#23698)
---
.../src/BoxPlot/transformProps.ts | 1 +
.../src/Funnel/transformProps.ts | 4 +++-
.../src/Gauge/transformProps.ts | 3 +++
.../src/Graph/EchartsGraph.tsx | 20 +++++++++++++++++-
.../src/Graph/transformProps.ts | 10 +++++++--
.../src/MixedTimeseries/EchartsMixedTimeseries.tsx | 17 +++++++++++----
.../src/MixedTimeseries/transformProps.ts | 6 +++++-
.../plugin-chart-echarts/src/Pie/transformProps.ts | 1 +
.../src/Radar/transformProps.ts | 1 +
.../src/Sunburst/EchartsSunburst.tsx | 20 +++++++++++++++---
.../src/Sunburst/transformProps.ts | 1 +
.../src/Timeseries/EchartsTimeseries.tsx | 16 ++++++++++++---
.../src/Timeseries/transformProps.ts | 1 +
.../src/Treemap/EchartsTreemap.tsx | 13 +++++++++++-
.../src/Treemap/transformProps.ts | 1 +
.../plugins/plugin-chart-echarts/src/types.ts | 1 +
.../src/utils/eventHandlers.ts | 24 ++++++++++++++++++----
17 files changed, 120 insertions(+), 20 deletions(-)
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BoxPlot/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BoxPlot/transformProps.ts
index 54a1cbfd20..0edeadb7fa 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/BoxPlot/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BoxPlot/transformProps.ts
@@ -297,5 +297,6 @@ export default function transformProps(
selectedValues,
onContextMenu,
refs,
+ coltypeMapping,
};
}
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Funnel/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Funnel/transformProps.ts
index 07da17d252..ac2f650e32 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Funnel/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Funnel/transformProps.ts
@@ -37,6 +37,7 @@ import {
import {
extractGroupbyLabel,
getChartPadding,
+ getColtypesMapping,
getLegendProps,
sanitizeHtml,
} from '../utils/series';
@@ -95,7 +96,7 @@ export default function transformProps(
emitCrossFilters,
} = chartProps;
const data: DataRecord[] = queriesData[0].data || [];
-
+ const coltypeMapping = getColtypesMapping(queriesData[0]);
const {
colorScheme,
groupby,
@@ -244,5 +245,6 @@ export default function transformProps(
selectedValues,
onContextMenu,
refs,
+ coltypeMapping,
};
}
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Gauge/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Gauge/transformProps.ts
index 6ff97bf0c5..27e6c9f197 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Gauge/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Gauge/transformProps.ts
@@ -46,6 +46,7 @@ import {
import { OpacityEnum } from '../constants';
import { getDefaultTooltip } from '../utils/tooltip';
import { Refs } from '../types';
+import { getColtypesMapping } from '../utils/series';
const setIntervalBoundsAndColors = (
intervals: string,
@@ -130,6 +131,7 @@ export default function transformProps(
}: EchartsGaugeFormData = { ...DEFAULT_GAUGE_FORM_DATA, ...formData };
const refs: Refs = {};
const data = (queriesData[0]?.data || []) as DataRecord[];
+ const coltypeMapping = getColtypesMapping(queriesData[0]);
const numberFormatter = getNumberFormatter(numberFormat);
const colorFn = CategoricalColorNamespace.getScale(colorScheme as string);
const axisLineWidth = calculateAxisLineWidth(data, fontSize, overlap);
@@ -341,5 +343,6 @@ export default function transformProps(
selectedValues: filterState.selectedValues || [],
onContextMenu,
refs,
+ coltypeMapping,
};
}
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Graph/EchartsGraph.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Graph/EchartsGraph.tsx
index 8e90bf1791..308d28f719 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Graph/EchartsGraph.tsx
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Graph/EchartsGraph.tsx
@@ -17,9 +17,15 @@
* under the License.
*/
import React from 'react';
+import {
+ getColumnLabel,
+ getNumberFormatter,
+ getTimeFormatter,
+} from '@superset-ui/core';
import { EventHandlers } from '../types';
import Echart from '../components/Echart';
import { GraphChartTransformedProps } from './types';
+import { formatSeriesName } from '../utils/series';
type DataRow = {
source?: string;
@@ -46,6 +52,7 @@ export default function EchartsGraph({
filterState,
emitCrossFilters,
refs,
+ coltypeMapping,
}: GraphChartTransformedProps) {
const getCrossFilterDataMask = (node: DataRow | undefined) => {
if (!node?.name || !node?.col) {
@@ -143,7 +150,18 @@ export default function EchartsGraph({
drillToDetail: drillToDetailFilters,
crossFilter: getCrossFilterDataMask(node),
drillBy: node && {
- filters: [{ col: node.col, op: '==', val: node.name }],
+ filters: [
+ {
+ col: node.col,
+ op: '==',
+ val: node.name,
+ formattedVal: formatSeriesName(node.name, {
+ timeFormatter: getTimeFormatter(formData.dateFormat),
+ numberFormatter: getNumberFormatter(formData.numberFormat),
+ coltype: coltypeMapping?.[getColumnLabel(node.col)],
+ }),
+ },
+ ],
groupbyFieldName:
node.col === formData.source ? 'source' : 'target',
},
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Graph/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Graph/transformProps.ts
index d61c229f07..256b984f7d 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Graph/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Graph/transformProps.ts
@@ -34,7 +34,12 @@ import {
EchartsGraphChartProps,
} from './types';
import { DEFAULT_GRAPH_SERIES_OPTION } from './constants';
-import { getChartPadding, getLegendProps, sanitizeHtml } from '../utils/series';
+import {
+ getChartPadding,
+ getColtypesMapping,
+ getLegendProps,
+ sanitizeHtml,
+} from '../utils/series';
import { getDefaultTooltip } from '../utils/tooltip';
import { Refs } from '../types';
@@ -174,7 +179,7 @@ export default function transformProps(
theme,
} = chartProps;
const data: DataRecord[] = queriesData[0].data || [];
-
+ const coltypeMapping = getColtypesMapping(queriesData[0]);
const {
source,
target,
@@ -343,5 +348,6 @@ export default function transformProps(
filterState,
refs,
emitCrossFilters,
+ coltypeMapping,
};
}
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/EchartsMixedTimeseries.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/EchartsMixedTimeseries.tsx
index 02583d4162..8686042611 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/EchartsMixedTimeseries.tsx
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/EchartsMixedTimeseries.tsx
@@ -19,14 +19,17 @@
import React, { useCallback } from 'react';
import {
AxisType,
- DataRecordValue,
- DTTM_ALIAS,
BinaryQueryObjectFilterClause,
+ DTTM_ALIAS,
+ DataRecordValue,
+ getColumnLabel,
+ getNumberFormatter,
+ getTimeFormatter,
} from '@superset-ui/core';
import { EchartsMixedTimeseriesChartTransformedProps } from './types';
import Echart from '../components/Echart';
import { EventHandlers } from '../types';
-import { currentSeries } from '../utils/series';
+import { currentSeries, formatSeriesName } from '../utils/series';
export default function EchartsMixedTimeseries({
height,
@@ -45,6 +48,7 @@ export default function EchartsMixedTimeseries({
xValueFormatter,
xAxis,
refs,
+ coltypeMapping,
}: EchartsMixedTimeseriesChartTransformedProps) {
const isFirstQuery = useCallback(
(seriesIndex: number) => seriesIndex < seriesBreakdown,
@@ -125,7 +129,7 @@ export default function EchartsMixedTimeseries({
mouseover: params => {
currentSeries.name = params.seriesName;
},
- contextmenu: eventParams => {
+ contextmenu: async eventParams => {
if (onContextMenu) {
eventParams.event.stop();
const { data, seriesName, seriesIndex } = eventParams;
@@ -167,6 +171,11 @@ export default function EchartsMixedTimeseries({
col: dimension,
op: '==',
val: values[i],
+ formattedVal: formatSeriesName(values[i], {
+ timeFormatter: getTimeFormatter(formData.dateFormat),
+ numberFormatter: getNumberFormatter(formData.numberFormat),
+ coltype: coltypeMapping?.[getColumnLabel(dimension)],
+ }),
}),
);
onContextMenu(pointerEvent.clientX, pointerEvent.clientY, {
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/transformProps.ts
index fee6183a2c..a924292980 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/transformProps.ts
@@ -105,7 +105,10 @@ export default function transformProps(
const data1 = (queriesData[0].data || []) as TimeseriesDataRecord[];
const data2 = (queriesData[1].data || []) as TimeseriesDataRecord[];
const annotationData = getAnnotationData(chartProps);
-
+ const coltypeMapping = {
+ ...getColtypesMapping(queriesData[0]),
+ ...getColtypesMapping(queriesData[1]),
+ };
const {
area,
areaB,
@@ -523,5 +526,6 @@ export default function transformProps(
type: xAxisType,
},
refs,
+ coltypeMapping,
};
}
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/transformProps.ts
index 76765cd801..7d30917b18 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/transformProps.ts
@@ -345,5 +345,6 @@ export default function transformProps(
onContextMenu,
refs,
emitCrossFilters,
+ coltypeMapping,
};
}
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Radar/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Radar/transformProps.ts
index 56d4be05ce..c8c3c7ed15 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Radar/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Radar/transformProps.ts
@@ -259,5 +259,6 @@ export default function transformProps(
selectedValues,
onContextMenu,
refs,
+ coltypeMapping,
};
}
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Sunburst/EchartsSunburst.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Sunburst/EchartsSunburst.tsx
index 7f40574665..29677d2564 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Sunburst/EchartsSunburst.tsx
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Sunburst/EchartsSunburst.tsx
@@ -17,10 +17,16 @@
* under the License.
*/
import React, { useCallback } from 'react';
-import { BinaryQueryObjectFilterClause } from '@superset-ui/core';
+import {
+ BinaryQueryObjectFilterClause,
+ getColumnLabel,
+ getNumberFormatter,
+ getTimeFormatter,
+} from '@superset-ui/core';
import { SunburstTransformedProps } from './types';
import Echart from '../components/Echart';
import { EventHandlers, TreePathInfo } from '../types';
+import { formatSeriesName } from '../utils/series';
export const extractTreePathInfo = (treePathInfo: TreePathInfo[] | undefined) =>
(treePathInfo ?? [])
@@ -39,6 +45,7 @@ export default function EchartsSunburst(props: SunburstTransformedProps) {
onContextMenu,
refs,
emitCrossFilters,
+ coltypeMapping,
} = props;
const { columns } = formData;
@@ -102,7 +109,7 @@ export default function EchartsSunburst(props: SunburstTransformedProps) {
const { treePathInfo } = props;
handleChange(treePathInfo);
},
- contextmenu: eventParams => {
+ contextmenu: async eventParams => {
if (onContextMenu) {
eventParams.event.stop();
const { data, treePathInfo } = eventParams;
@@ -120,10 +127,17 @@ export default function EchartsSunburst(props: SunburstTransformedProps) {
formattedVal: path,
}),
);
+ const val = treePath[treePath.length - 1];
drillByFilters.push({
col: columns[treePath.length - 1],
op: '==',
- val: treePath[treePath.length - 1],
+ val,
+ formattedVal: formatSeriesName(val, {
+ timeFormatter: getTimeFormatter(formData.dateFormat),
+ numberFormatter: getNumberFormatter(formData.numberFormat),
+ coltype:
+ coltypeMapping?.[getColumnLabel(columns[treePath.length - 1])],
+ }),
});
}
onContextMenu(pointerEvent.clientX, pointerEvent.clientY, {
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Sunburst/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Sunburst/transformProps.ts
index 51e89f8c6c..a12a757e44 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Sunburst/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Sunburst/transformProps.ts
@@ -377,5 +377,6 @@ export default function transformProps(
selectedValues: filterState.selectedValues || [],
onContextMenu,
refs,
+ coltypeMapping,
};
}
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
index 202d627569..7f75d27105 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
@@ -21,6 +21,9 @@ import {
DTTM_ALIAS,
BinaryQueryObjectFilterClause,
AxisType,
+ getTimeFormatter,
+ getColumnLabel,
+ getNumberFormatter,
} from '@superset-ui/core';
import { ViewRootGroup } from 'echarts/types/src/util/types';
import GlobalModel from 'echarts/types/src/model/Global';
@@ -28,7 +31,7 @@ import ComponentModel from 'echarts/types/src/model/Component';
import { EchartsHandler, EventHandlers } from '../types';
import Echart from '../components/Echart';
import { TimeseriesChartTransformedProps } from './types';
-import { currentSeries } from '../utils/series';
+import { currentSeries, formatSeriesName } from '../utils/series';
import { ExtraControls } from '../components/ExtraControls';
const TIMER_DURATION = 300;
@@ -50,6 +53,7 @@ export default function EchartsTimeseries({
xAxis,
refs,
emitCrossFilters,
+ coltypeMapping,
}: TimeseriesChartTransformedProps) {
const { stack } = formData;
const echartRef = useRef<EchartsHandler | null>(null);
@@ -196,7 +200,7 @@ export default function EchartsTimeseries({
handleDoubleClickChange();
}
},
- contextmenu: eventParams => {
+ contextmenu: async eventParams => {
if (onContextMenu) {
eventParams.event.stop();
const { data, seriesName } = eventParams;
@@ -232,10 +236,16 @@ export default function EchartsTimeseries({
}),
);
formData.groupby.forEach((dimension, i) => {
+ const val = labelMap[seriesName][i];
drillByFilters.push({
col: dimension,
op: '==',
- val: labelMap[seriesName][i],
+ val,
+ formattedVal: formatSeriesName(values[i], {
+ timeFormatter: getTimeFormatter(formData.dateFormat),
+ numberFormatter: getNumberFormatter(formData.numberFormat),
+ coltype: coltypeMapping?.[getColumnLabel(dimension)],
+ }),
});
});
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
index 84b97fae52..ac096a0697 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
@@ -533,5 +533,6 @@ export default function transformProps(
type: xAxisType,
},
refs,
+ coltypeMapping: dataTypes,
};
}
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Treemap/EchartsTreemap.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Treemap/EchartsTreemap.tsx
index f9363bd4b6..00dcc11aac 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Treemap/EchartsTreemap.tsx
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Treemap/EchartsTreemap.tsx
@@ -19,6 +19,9 @@
import {
DataRecordValue,
BinaryQueryObjectFilterClause,
+ getTimeFormatter,
+ getColumnLabel,
+ getNumberFormatter,
} from '@superset-ui/core';
import React, { useCallback } from 'react';
import Echart from '../components/Echart';
@@ -26,6 +29,7 @@ import { NULL_STRING } from '../constants';
import { EventHandlers } from '../types';
import { extractTreePathInfo } from './constants';
import { TreemapTransformedProps } from './types';
+import { formatSeriesName } from '../utils/series';
export default function EchartsTreemap({
echartOptions,
@@ -38,6 +42,8 @@ export default function EchartsTreemap({
setDataMask,
selectedValues,
width,
+ formData,
+ coltypeMapping,
}: TreemapTransformedProps) {
const getCrossFilterDataMask = useCallback(
(data, treePathInfo) => {
@@ -108,7 +114,7 @@ export default function EchartsTreemap({
const { data, treePathInfo } = props;
handleChange(data, treePathInfo);
},
- contextmenu: eventParams => {
+ contextmenu: async eventParams => {
if (onContextMenu) {
eventParams.event.stop();
const { data, treePathInfo } = eventParams;
@@ -129,6 +135,11 @@ export default function EchartsTreemap({
col: groupby[i],
op: '==',
val,
+ formattedVal: formatSeriesName(val, {
+ timeFormatter: getTimeFormatter(formData.dateFormat),
+ numberFormatter: getNumberFormatter(formData.numberFormat),
+ coltype: coltypeMapping?.[getColumnLabel(groupby[i])],
+ }),
});
});
onContextMenu(pointerEvent.clientX, pointerEvent.clientY, {
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Treemap/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Treemap/transformProps.ts
index b220b55b3d..89088be5fa 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Treemap/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Treemap/transformProps.ts
@@ -294,5 +294,6 @@ export default function transformProps(
selectedValues: filterState.selectedValues || [],
onContextMenu,
refs,
+ coltypeMapping,
};
}
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/types.ts b/superset-frontend/plugins/plugin-chart-echarts/src/types.ts
index 142c41c17d..4b96f73bb9 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/types.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/types.ts
@@ -131,6 +131,7 @@ export interface BaseTransformedProps<F> {
refs: Refs;
width: number;
emitCrossFilters?: boolean;
+ coltypeMapping?: Record<string, number>;
}
export type CrossFilterTransformedProps = {
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/utils/eventHandlers.ts b/superset-frontend/plugins/plugin-chart-echarts/src/utils/eventHandlers.ts
index 7651bd83bd..98e14d59ed 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/utils/eventHandlers.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/utils/eventHandlers.ts
@@ -21,12 +21,18 @@ import {
ContextMenuFilters,
DataMask,
QueryFormColumn,
+ QueryFormData,
+ getColumnLabel,
+ getNumberFormatter,
+ getTimeFormatter,
} from '@superset-ui/core';
+
import {
BaseTransformedProps,
CrossFilterTransformedProps,
EventHandlers,
} from '../types';
+import { formatSeriesName } from './series';
export type Event = {
name: string;
@@ -106,6 +112,8 @@ export const contextMenuEventHandler =
getCrossFilterDataMask: (
value: string,
) => ContextMenuFilters['crossFilter'],
+ formData: QueryFormData,
+ coltypeMapping?: Record<string, number>,
) =>
(e: Event) => {
if (onContextMenu) {
@@ -114,14 +122,18 @@ export const contextMenuEventHandler =
const drillFilters: BinaryQueryObjectFilterClause[] = [];
if (groupby.length > 0) {
const values = labelMap[e.name];
- groupby.forEach((dimension, i) =>
+ groupby.forEach((dimension, i) => {
drillFilters.push({
col: dimension,
op: '==',
val: values[i],
- formattedVal: String(values[i]),
- }),
- );
+ formattedVal: formatSeriesName(values[i], {
+ timeFormatter: getTimeFormatter(formData.dateFormat),
+ numberFormatter: getNumberFormatter(formData.numberFormat),
+ coltype: coltypeMapping?.[getColumnLabel(dimension)],
+ }),
+ });
+ });
}
onContextMenu(pointerEvent.clientX, pointerEvent.clientY, {
drillToDetail: drillFilters,
@@ -141,6 +153,8 @@ export const allEventHandlers = (
labelMap,
emitCrossFilters,
selectedValues,
+ coltypeMapping,
+ formData,
} = transformedProps;
const eventHandlers: EventHandlers = {
click: clickEventHandler(
@@ -153,6 +167,8 @@ export const allEventHandlers = (
onContextMenu,
labelMap,
getCrossFilterDataMask(selectedValues, groupby, labelMap),
+ formData,
+ coltypeMapping,
),
};
return eventHandlers;