codeant-ai-for-open-source[bot] commented on code in PR #41907:
URL: https://github.com/apache/superset/pull/41907#discussion_r3551970854


##########
superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx:
##########
@@ -244,6 +245,61 @@ export default function EchartsTimeseries({
 
   const eventHandlers: EventHandlers = {
     click: props => {
+      // Drill-down takes priority over cross-filter when a hierarchy is 
configured.
+      // The DrillDownHost provides onDrillDown only when a hierarchy exists.
+      const hasDrillHierarchy = !!onDrillDown;
+
+      if (hasDrillHierarchy) {
+        if (clickTimer.current) {
+          clearTimeout(clickTimer.current);
+        }
+        clickTimer.current = setTimeout(() => {
+          const { seriesName: name } = props;
+          const drillFilters: BinaryQueryObjectFilterClause[] = [];
+          if (hasDimensions) {
+            const values = labelMap[name] ?? [];
+            groupby.forEach((dimension, i) => {
+              drillFilters.push({
+                col: dimension,
+                op: '==',
+                val: values[i],
+                formattedVal: String(values[i]),
+              });
+            });
+            // Cross-filter is emitted by the DrillDownHost with the full
+            // accumulated drill path; here we only report the click upward.
+          } else if (
+            xAxis.type === AxisType.Category &&
+            props.data?.[0] != null
+          ) {
+            // Bar chart with x_axis only (no groupby dimensions)
+            drillFilters.push({
+              col: xAxis.label,
+              op: '==',
+              val: props.data[0],
+              formattedVal: String(props.data[0]),
+            });

Review Comment:
   **Suggestion:** The category drill branch hardcodes `props.data[0]`, but for 
horizontal charts the category axis value is at a different index (already 
handled elsewhere via `getCategoryAxisValue`). This causes drill-down to filter 
on the measure instead of the category for horizontal bars. Reuse the 
orientation-aware category extraction here. [incorrect variable usage]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ❌ Horizontal bar drill-down filters by metric, not category.
   - ⚠️ Dashboard cross-filters inconsistent for horizontal bar charts.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Create a timeseries chart with no groupby (hasDimensions is false in
   EchartsTimeseries.tsx:102) using a Bar series type configured with 
orientation ===
   OrientationType.Horizontal in formData (transformProps sets isHorizontal 
from orientation
   at 
superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts:102
 and
   builds horizontal bar series accordingly).
   
   2. Ensure the X-axis is categorical so xAxis.type === AxisType.Category in
   EchartsTimeseries
   
(superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx:223-224)
   and configure a drilldown_hierarchy so DrillDownHost provides onDrillDown
   (DrillDownHost.tsx:38-71) to the chart renderer and down to 
EchartsTimeseries (props
   onDrillDown at EchartsTimeseries.tsx:64).
   
   3. In this horizontal bar configuration, ECharts data points are shaped such 
that the
   category label is at index 1; EchartsTimeseries already accounts for this via
   categoryAxisValueIndex = formData.orientation === OrientationType.Horizontal 
? 1 : 0 and
   getCategoryAxisValue(data, name) using data[categoryAxisValueIndex]
   (EchartsTimeseries.tsx:225-235), which is reused by cross-filter logic 
elsewhere (click
   cross-filter at 318-323 and context menu cross-filter at 410-415).
   
   4. When you left-click a bar with a drilldown hierarchy active, the click 
handler’s
   drill-down branch for category axes (EchartsTimeseries.tsx:271-281) fires 
and builds
   drillFilters with val: props.data[0]; for horizontal bars props.data[0] 
holds the metric
   value, not the category, so onDrillDown receives filters scoped to the 
measure rather than
   the category, and DrillDownHost (DrillDownHost.tsx:42-63) emits a 
cross-filter that
   mis-scopes the drilled chart and other dashboard charts.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=8de288e52932447182cd718e7e472c74&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=8de288e52932447182cd718e7e472c74&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** 
superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
   **Line:** 271:281
   **Comment:**
        *Incorrect Variable Usage: The category drill branch hardcodes 
`props.data[0]`, but for horizontal charts the category axis value is at a 
different index (already handled elsewhere via `getCategoryAxisValue`). This 
causes drill-down to filter on the measure instead of the category for 
horizontal bars. Reuse the orientation-aware category extraction here.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41907&comment_hash=f90f4438f352d1802fa28f5a180dc2efd294c5fbcf16a8ed887e1fd221891456&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41907&comment_hash=f90f4438f352d1802fa28f5a180dc2efd294c5fbcf16a8ed887e1fd221891456&reaction=dislike'>👎</a>



##########
superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx:
##########
@@ -244,6 +245,61 @@ export default function EchartsTimeseries({
 
   const eventHandlers: EventHandlers = {
     click: props => {
+      // Drill-down takes priority over cross-filter when a hierarchy is 
configured.
+      // The DrillDownHost provides onDrillDown only when a hierarchy exists.
+      const hasDrillHierarchy = !!onDrillDown;
+
+      if (hasDrillHierarchy) {
+        if (clickTimer.current) {
+          clearTimeout(clickTimer.current);
+        }
+        clickTimer.current = setTimeout(() => {
+          const { seriesName: name } = props;
+          const drillFilters: BinaryQueryObjectFilterClause[] = [];
+          if (hasDimensions) {
+            const values = labelMap[name] ?? [];
+            groupby.forEach((dimension, i) => {
+              drillFilters.push({
+                col: dimension,
+                op: '==',
+                val: values[i],
+                formattedVal: String(values[i]),
+              });
+            });

Review Comment:
   **Suggestion:** The drill filter mapping uses `values[i]` directly, but 
timeseries `labelMap` entries can include metric values before dimension values 
(the same file already compensates with a metrics offset in cross-filter 
logic). On multi-metric grouped charts this will drill on the wrong values and 
produce incorrect filters. Compute the dimension index with the metrics offset 
before reading from `values`. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ Multi-metric timeseries drill-down filters on wrong values.
   - ⚠️ Cross-filtered sibling charts show inconsistent scoped data.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Configure a mixed timeseries chart with multiple metrics and at least one 
groupby
   dimension, then enable a drilldown hierarchy in the chart formData so 
DrillDownHost wires
   onDrillDown 
(superset-frontend/src/components/Chart/DrillDown/DrillDownHost.tsx:38-71)
   into the plugin.
   
   2. The Timeseries transform builds labelMap from the backend label_map for 
each series
   
(superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts:79-92),
   where entries contain metric values followed by dimension values; 
cross-filter logic
   elsewhere already compensates by computing metricsCount = v.length - 
groupby.length and
   indexing dimensions at metricsCount + idx (getCrossFilterDataMask at
   EchartsTimeseries.tsx:135-139, and drillByFilters in the context menu at
   EchartsTimeseries.tsx:382-388).
   
   3. On the dashboard, left-click a multi-metric grouped series to drill; the 
click handler
   in EchartsTimeseries
   
(superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx:246-299)
   sees hasDrillHierarchy and hasDimensions, reads const values = 
labelMap[name] ?? [] and
   then for each groupby dimension uses val: values[i] (lines 260-265), which 
for
   multi-metric series resolves to metric or time-offset entries instead of the 
actual
   dimension values.
   
   4. The resulting drillFilters array is passed to onDrillDown
   (EchartsTimeseries.tsx:293-297), and DrillDownHost converts each into 
pathFilters and
   emits a cross-filter (DrillDownHost.tsx:42-63) based on these wrong values, 
causing the
   drilled chart and other dashboard charts to be filtered on 
metric/time-offset tokens
   rather than the intended dimension values.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=8a7a00f340cb4f5e877552cc1c4870a9&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=8a7a00f340cb4f5e877552cc1c4870a9&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** 
superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
   **Line:** 260:268
   **Comment:**
        *Logic Error: The drill filter mapping uses `values[i]` directly, but 
timeseries `labelMap` entries can include metric values before dimension values 
(the same file already compensates with a metrics offset in cross-filter 
logic). On multi-metric grouped charts this will drill on the wrong values and 
produce incorrect filters. Compute the dimension index with the metrics offset 
before reading from `values`.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41907&comment_hash=c5d5754cf522c57e23f44ebc2992c7030d0ee5f2114a5955e65a9aa45077b84d&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41907&comment_hash=c5d5754cf522c57e23f44ebc2992c7030d0ee5f2114a5955e65a9aa45077b84d&reaction=dislike'>👎</a>



##########
superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx:
##########
@@ -244,6 +245,61 @@ export default function EchartsTimeseries({
 
   const eventHandlers: EventHandlers = {
     click: props => {
+      // Drill-down takes priority over cross-filter when a hierarchy is 
configured.
+      // The DrillDownHost provides onDrillDown only when a hierarchy exists.
+      const hasDrillHierarchy = !!onDrillDown;
+
+      if (hasDrillHierarchy) {
+        if (clickTimer.current) {
+          clearTimeout(clickTimer.current);
+        }
+        clickTimer.current = setTimeout(() => {
+          const { seriesName: name } = props;
+          const drillFilters: BinaryQueryObjectFilterClause[] = [];
+          if (hasDimensions) {
+            const values = labelMap[name] ?? [];
+            groupby.forEach((dimension, i) => {
+              drillFilters.push({
+                col: dimension,
+                op: '==',
+                val: values[i],
+                formattedVal: String(values[i]),
+              });
+            });
+            // Cross-filter is emitted by the DrillDownHost with the full
+            // accumulated drill path; here we only report the click upward.
+          } else if (
+            xAxis.type === AxisType.Category &&
+            props.data?.[0] != null
+          ) {
+            // Bar chart with x_axis only (no groupby dimensions)
+            drillFilters.push({
+              col: xAxis.label,
+              op: '==',
+              val: props.data[0],
+              formattedVal: String(props.data[0]),
+            });
+            // Cross-filter is emitted by the DrillDownHost with the full
+            // accumulated drill path; here we only report the click upward.
+          } else if (props.name) {
+            // Fallback: use the event name (typically the x-axis label)
+            drillFilters.push({
+              col: xAxis.label,
+              op: '==',
+              val: props.name,
+              formattedVal: String(props.name),
+            });

Review Comment:
   **Suggestion:** The fallback condition checks `props.name` by truthiness, so 
valid category names like `0` are treated as absent and no drill filter is 
emitted. Use a null/undefined check instead of a truthy check so zero-like 
labels still drill correctly. [falsy zero check]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ⚠️ Drill-down ignores clicks on zero-valued categories.
   - ⚠️ Dashboard cross-filters inconsistent for numeric-zero labels.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Configure a timeseries-based ECharts chart (Bar, Line, etc.) such that 
the clicked
   element’s category or label is the numeric value 0 (for example, a dimension 
containing
   values 0, 1, 2) and enable a drilldown hierarchy so DrillDownHost wires 
onDrillDown into
   the chart (DrillDownHost.tsx:38-71).
   
   2. Ensure the click lands in the drill-down branch where the category-axis 
shortcut does
   not apply — e.g., either xAxis.type is not AxisType.Category or props.data 
is unset for
   the event — so the click handler in EchartsTimeseries falls through to the 
fallback
   condition
   
(superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx:284-291).
   
   3. For the data point whose label is 0, ECharts supplies props.name === 0; 
the fallback
   branch checks else if (props.name) (line 284), which uses a truthiness 
check, so 0 is
   treated as falsy and the drillFilters push logic is skipped entirely, 
leaving drillFilters
   empty for this valid label.
   
   4. Because drillFilters.length === 0, the handler does not call onDrillDown 
(the call at
   EchartsTimeseries.tsx:293-297 is guarded), meaning DrillDownHost never sees 
the drill
   event for label 0, the breadcrumb stack is not updated, and no cross-filters 
are emitted,
   so clicks on zero-valued categories silently fail while other labels drill 
correctly.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=19d6e423485e463ba6b70b8aeb1ada72&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=19d6e423485e463ba6b70b8aeb1ada72&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** 
superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx
   **Line:** 284:291
   **Comment:**
        *Falsy Zero Check: The fallback condition checks `props.name` by 
truthiness, so valid category names like `0` are treated as absent and no drill 
filter is emitted. Use a null/undefined check instead of a truthy check so 
zero-like labels still drill correctly.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41907&comment_hash=43723b7a75c73317f73c89ac83c7cdf65377eaea78b554a31938e13d4cb0e5fd&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41907&comment_hash=43723b7a75c73317f73c89ac83c7cdf65377eaea78b554a31938e13d4cb0e5fd&reaction=dislike'>👎</a>



-- 
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]

Reply via email to