rusackas commented on code in PR #37407:
URL: https://github.com/apache/superset/pull/37407#discussion_r2737537815
##########
superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx:
##########
@@ -154,6 +154,43 @@ export default function EchartsTimeseries({
[groupby, labelMap, selectedValues],
);
+ // Cross-filter using X-axis value when no dimensions are set (issue #25334)
+ const getXAxisCrossFilterDataMask = useCallback(
+ (xAxisValue: string | number) => {
+ const stringValue = String(xAxisValue);
+ const selected: string[] = Object.values(selectedValues);
+ let values: string[];
+ if (selected.includes(stringValue)) {
+ values = selected.filter(v => v !== stringValue);
+ } else {
+ values = [stringValue];
+ }
+ return {
+ dataMask: {
+ extraFormData: {
+ filters:
+ values.length === 0
+ ? []
+ : [
+ {
+ col: xAxis.label,
+ op: 'IN' as const,
+ val: values,
+ },
+ ],
+ },
+ filterState: {
+ label: values.length ? values : undefined,
+ value: values.length ? values : null,
+ selectedValues: values.length ? values : null,
+ },
+ },
+ isCurrentValueSelected: selected.includes(stringValue),
Review Comment:
This follows the established pattern in the codebase where filter values are
converted to strings. The existing dimension-based cross-filter code already
uses `String()` throughout for consistency. Since Superset's filter framework
handles type coercion at the database layer, keeping string values in the
filter state is the expected behavior here.
##########
superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx:
##########
@@ -164,18 +201,41 @@ export default function EchartsTimeseries({
[emitCrossFilters, setDataMask, getCrossFilterDataMask],
);
+ // Handle cross-filter using X-axis value when no dimensions (issue #25334)
+ const handleXAxisChange = useCallback(
+ (xAxisValue: string | number) => {
+ if (!emitCrossFilters) {
+ return;
+ }
+ setDataMask(getXAxisCrossFilterDataMask(xAxisValue).dataMask);
+ },
+ [emitCrossFilters, setDataMask, getXAxisCrossFilterDataMask],
+ );
+
+ // Determine if X-axis can be used for cross-filtering (categorical axis
without dimensions)
+ const canCrossFilterByXAxis =
+ !hasDimensions && xAxis.type === AxisType.Category;
+
const eventHandlers: EventHandlers = {
click: props => {
- if (!hasDimensions) {
+ // Allow cross-filter by dimensions OR by categorical X-axis (issue
#25334)
+ if (!hasDimensions && !canCrossFilterByXAxis) {
return;
}
if (clickTimer.current) {
clearTimeout(clickTimer.current);
}
// Ensure that double-click events do not trigger single click event. So
we put it in the timer.
clickTimer.current = setTimeout(() => {
- const { seriesName: name } = props;
- handleChange(name);
+ if (hasDimensions) {
+ // Cross-filter by dimension (original behavior)
+ const { seriesName: name } = props;
+ handleChange(name);
+ } else if (canCrossFilterByXAxis && props.data) {
+ // Cross-filter by X-axis value when no dimensions (issue #25334)
+ const xAxisValue = props.data[0];
+ handleXAxisChange(xAxisValue);
Review Comment:
Addressed in commit 343185a — added guard `props.data?.[0] != null` to
ensure we only proceed when valid data exists.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]