Skip to content

Refactor tooltip handling in TmfCommonXLineChart#383

Open
TranHoangThanhDuy wants to merge 1 commit intoeclipse-tracecompass:masterfrom
TranHoangThanhDuy:patch-1
Open

Refactor tooltip handling in TmfCommonXLineChart#383
TranHoangThanhDuy wants to merge 1 commit intoeclipse-tracecompass:masterfrom
TranHoangThanhDuy:patch-1

Conversation

@TranHoangThanhDuy
Copy link
Copy Markdown

@TranHoangThanhDuy TranHoangThanhDuy commented Mar 17, 2026

Refactor TmfCommonXLineChartTooltipProvider to make the tooltip population logic extensible for subclasses via protected hooks, while preserving the default tooltip behavior.

Also remove unused maxLen calculation that was left over from an earlier implementation.

Files:

  • org.eclipse.tracecompass.tmf.ui.viewers.xychart.linechart.TmfCommonXLineChartTooltipProvider

What it does

How to test

Follow-ups

Review checklist

  • As an author, I have thoroughly tested my changes and carefully followed the instructions in this template

Summary by CodeRabbit

  • Refactor
    • Centralized and simplified line-chart tooltip internals for easier maintenance and clearer control flow.
    • Tooltip eligibility and hovered-point detection were made more robust to avoid invalid or out-of-range renders.
  • New Features
    • Richer, color-aware tooltip formatting with consistent label handling.
    • Improved per-series value formatting and clearer timeline item presentation.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 17, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Refactors tooltip generation in TmfCommonXLineChartTooltipProvider: replaces the internal XYToolTipHandler with CommonToolTipHandler, extracts protected helper methods for hovered-index calculation, series validation, label/HTML formatting, and modularizes tooltip item construction; public API signatures remain unchanged.

Changes

Cohort / File(s) Summary
Tooltip handler refactor
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf.ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java
Replaces XYToolTipHandler with CommonToolTipHandler. Adds protected helpers: isTooltipAvailable, getHoveredIndex, isValidSeriesIndex, addAdditionalTooltipItems, addSeriesTooltipItem, formatSeriesLabel and a private inner class. Centralizes time/format retrieval, gates tooltip rendering, normalizes null series ids, and applies HTML color only when series color exists. No public API signature changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I hopped through lines of tooltip lore,
Pruned the handlers, opened the door,
Helpers snugly in a row,
Same surface, cleaner flow,
I twitch my nose — code sings once more!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Refactor tooltip handling in TmfCommonXLineChart' directly and accurately describes the main change: refactoring the tooltip generation logic in the TmfCommonXLineChartTooltipProvider class.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java (1)

138-177: Add focused regression tests for default parity and hook behavior.

Given the internal flow rewrite, tests should assert: (1) default tooltip content parity, and (2) subclass overrides (addAdditionalTooltipItems, formatSeriesLabel, isValidSeriesIndex) are invoked as intended.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java`
around lines 138 - 177, Add focused regression tests for
TmfCommonXLineChartTooltipProvider to assert default tooltip content parity and
to verify subclass hook invocation: create tests that exercise fill(...) by
simulating mouse events and compare tooltip content produced by
TmfCommonXLineChartTooltipProvider against the previous/default expected output
(default parity), and create a test subclass/mock of
TmfCommonXLineChartTooltipProvider that overrides addAdditionalTooltipItems,
formatSeriesLabel, and isValidSeriesIndex to record invocations; then assert
those overrides are called with the expected parameters when fill(...) runs (use
getXAxis(), getSeries(), and getHoveredIndex behavior to drive the hovered
index). Ensure tests cover the case where xCoordinate < 0 and index < 0 as well
to confirm no hooks are invoked.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java`:
- Around line 124-134: The series label `key` is embedded into HTML unescaped in
formatSeriesLabel (class TmfCommonXLineChartTooltipProvider), which can break
tooltip rendering or allow markup injection; fix by HTML-escaping `key` before
building the label (e.g., compute an escapedKey from `key` that replaces & < > "
' or use a standard utility such as StringEscapeUtils.escapeHtml4) and then use
escapedKey (not raw key) when calling String.format(HTML_COLOR_TOOLTIP, ... ,
label) so the tooltip HTML is safe.

---

Nitpick comments:
In
`@tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java`:
- Around line 138-177: Add focused regression tests for
TmfCommonXLineChartTooltipProvider to assert default tooltip content parity and
to verify subclass hook invocation: create tests that exercise fill(...) by
simulating mouse events and compare tooltip content produced by
TmfCommonXLineChartTooltipProvider against the previous/default expected output
(default parity), and create a test subclass/mock of
TmfCommonXLineChartTooltipProvider that overrides addAdditionalTooltipItems,
formatSeriesLabel, and isValidSeriesIndex to record invocations; then assert
those overrides are called with the expected parameters when fill(...) runs (use
getXAxis(), getSeries(), and getHoveredIndex behavior to drive the hovered
index). Ensure tests cover the case where xCoordinate < 0 and index < 0 as well
to confirm no hooks are invoked.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a71cc108-a85e-4bb3-a590-55efb4311739

📥 Commits

Reviewing files that changed from the base of the PR and between d2fde0d and cf91de6.

📒 Files selected for processing (1)
  • tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java

Comment on lines +124 to +134
protected String formatSeriesLabel(
IXYSeries series,
String key) {

String label = (key == null) ? "" : key; //$NON-NLS-1$
Color color = series.getColor();
if (color != null) {
RGBA rgba = color.getRGBA();
RGBAColor rgbaColor = new RGBAColor(rgba.rgb.red, rgba.rgb.green, rgba.rgb.blue, rgba.alpha);
label = String.format(HTML_COLOR_TOOLTIP, rgbaColor, label);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Escape series labels before embedding into HTML tooltip content.

key is inserted into HTML directly. If a series ID contains <, &, or quotes, tooltip rendering can break and allow unintended markup injection.

Proposed fix
 protected String formatSeriesLabel(
         IXYSeries series,
         String key) {
 
-    String label = (key == null) ? "" : key; //$NON-NLS-1$
+    String label = escapeHtml((key == null) ? "" : key); //$NON-NLS-1$
     Color color = series.getColor();
     if (color != null) {
         RGBA rgba = color.getRGBA();
         RGBAColor rgbaColor = new RGBAColor(rgba.rgb.red, rgba.rgb.green, rgba.rgb.blue, rgba.alpha);
         label = String.format(HTML_COLOR_TOOLTIP, rgbaColor, label);
     }
     return label;
 }
+
+private static String escapeHtml(String value) {
+    return value
+            .replace("&", "&amp;") //$NON-NLS-1$ //$NON-NLS-2$
+            .replace("<", "&lt;") //$NON-NLS-1$ //$NON-NLS-2$
+            .replace(">", "&gt;") //$NON-NLS-1$ //$NON-NLS-2$
+            .replace("\"", "&quot;") //$NON-NLS-1$ //$NON-NLS-2$
+            .replace("'", "&#39;"); //$NON-NLS-1$ //$NON-NLS-2$
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
protected String formatSeriesLabel(
IXYSeries series,
String key) {
String label = (key == null) ? "" : key; //$NON-NLS-1$
Color color = series.getColor();
if (color != null) {
RGBA rgba = color.getRGBA();
RGBAColor rgbaColor = new RGBAColor(rgba.rgb.red, rgba.rgb.green, rgba.rgb.blue, rgba.alpha);
label = String.format(HTML_COLOR_TOOLTIP, rgbaColor, label);
}
protected String formatSeriesLabel(
IXYSeries series,
String key) {
String label = escapeHtml((key == null) ? "" : key); //$NON-NLS-1$
Color color = series.getColor();
if (color != null) {
RGBA rgba = color.getRGBA();
RGBAColor rgbaColor = new RGBAColor(rgba.rgb.red, rgba.rgb.green, rgba.rgb.blue, rgba.alpha);
label = String.format(HTML_COLOR_TOOLTIP, rgbaColor, label);
}
return label;
}
private static String escapeHtml(String value) {
return value
.replace("&", "&amp;") //$NON-NLS-1$ //$NON-NLS-2$
.replace("<", "&lt;") //$NON-NLS-1$ //$NON-NLS-2$
.replace(">", "&gt;") //$NON-NLS-1$ //$NON-NLS-2$
.replace("\"", "&quot;") //$NON-NLS-1$ //$NON-NLS-2$
.replace("'", "&#39;"); //$NON-NLS-1$ //$NON-NLS-2$
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java`
around lines 124 - 134, The series label `key` is embedded into HTML unescaped
in formatSeriesLabel (class TmfCommonXLineChartTooltipProvider), which can break
tooltip rendering or allow markup injection; fix by HTML-escaping `key` before
building the label (e.g., compute an escapedKey from `key` that replaces & < > "
' or use a standard utility such as StringEscapeUtils.escapeHtml4) and then use
escapedKey (not raw key) when calling String.format(HTML_COLOR_TOOLTIP, ... ,
label) so the tooltip HTML is safe.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java (1)

145-148: Consider adding defensive null/bounds check for Y-axis array access.

The access chartViewer.getSwtChart().getAxisSet().getYAxes()[0] assumes at least one Y-axis exists and that the array is non-null. While this pattern appears consistent with other code in the codebase (e.g., TmfCommonXAxisChartViewer uses similar access), a defensive check would prevent potential ArrayIndexOutOfBoundsException in edge cases.

♻️ Optional defensive check
             Format format = null;
             if (getChartViewer() instanceof TmfCommonXAxisChartViewer chartViewer) {
-                format = chartViewer.getSwtChart().getAxisSet().getYAxes()[0].getTick().getFormat();
+                IAxis[] yAxes = chartViewer.getSwtChart().getAxisSet().getYAxes();
+                if (yAxes != null && yAxes.length > 0) {
+                    format = yAxes[0].getTick().getFormat();
+                }
             }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java`
around lines 145 - 148, The code in TmfCommonXLineChartTooltipProvider assumes a
non-null, non-empty Y-axes array when calling
chartViewer.getSwtChart().getAxisSet().getYAxes()[0]; add defensive checks to
ensure getSwtChart(), getAxisSet(), and getYAxes() are non-null and that
getYAxes().length > 0 before indexing, and fall back to a safe default (e.g.,
leave format null or use a sensible fallback format) so the code in the block
that uses `format` cannot throw ArrayIndexOutOfBoundsException or NPE; locate
this logic around the getChartViewer() instanceof TmfCommonXAxisChartViewer
branch and update there.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java`:
- Around line 99-112: The compilation fails because addSeriesTooltipItem() in
TmfCommonXLineChartTooltipProvider calls addItem() which is defined on
TmfAbstractToolTipHandler, not the outer class; update addSeriesTooltipItem(...)
to use the tooltip handler instance (fToolTipHandler) to add items instead of
calling addItem() directly: replace the direct addItem(...) calls with
fToolTipHandler.addItem(...) (or change the method signature to accept a
TmfAbstractToolTipHandler parameter and call handler.addItem(...)); ensure
formatSeriesLabel(...) remains accessible (move into CommonToolTipHandler or
make it package-private/static if needed) and update any callers accordingly
(e.g., CommonToolTipHandler.fill() should call
addSeriesTooltipItem(fToolTipHandler, ... ) or the modified method that accepts
the handler).

---

Nitpick comments:
In
`@tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java`:
- Around line 145-148: The code in TmfCommonXLineChartTooltipProvider assumes a
non-null, non-empty Y-axes array when calling
chartViewer.getSwtChart().getAxisSet().getYAxes()[0]; add defensive checks to
ensure getSwtChart(), getAxisSet(), and getYAxes() are non-null and that
getYAxes().length > 0 before indexing, and fall back to a safe default (e.g.,
leave format null or use a sensible fallback format) so the code in the block
that uses `format` cannot throw ArrayIndexOutOfBoundsException or NPE; locate
this logic around the getChartViewer() instanceof TmfCommonXAxisChartViewer
branch and update there.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ca319e3b-06f6-4599-b24c-c1d18902f2af

📥 Commits

Reviewing files that changed from the base of the PR and between cf91de6 and f7a2611.

📒 Files selected for processing (1)
  • tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java

Comment on lines +99 to +112
protected void addSeriesTooltipItem(IXYSeries series, String key, int index, Format format) {
double[] ySeries = series.getYSeries();
if (ySeries == null || index < 0 || index >= ySeries.length) {
return;
}

String label = formatSeriesLabel(series, key);
double yValue = ySeries[index];
if (format == null) {
addItem(null, ToolTipString.fromHtml(label), ToolTipString.fromDecimal(yValue));
} else {
addItem(null, ToolTipString.fromHtml(label), ToolTipString.fromString(format.format(yValue)));
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify if addItem method is defined in TmfBaseProvider or inherited from elsewhere
ast-grep --pattern $'class TmfBaseProvider {
  $$$
  addItem($$$) {
    $$$
  }
  $$$
}'

# Also check TmfAbstractToolTipHandler for addItem signature
ast-grep --pattern $'class TmfAbstractToolTipHandler {
  $$$
  addItem($$$) {
    $$$
  }
  $$$
}'

# Search for addItem method definition more broadly
rg -n "protected.*void.*addItem\(" --type java -C2

Repository: eclipse-tracecompass/org.eclipse.tracecompass

Length of output: 2646


🏁 Script executed:

# Find and examine the TmfCommonXLineChartTooltipProvider class definition
fd -t f "TmfCommonXLineChartTooltipProvider.java" --exec cat -n {}

Repository: eclipse-tracecompass/org.eclipse.tracecompass

Length of output: 7363


🏁 Script executed:

# Find TmfBaseProvider and examine its class definition
fd -t f "TmfBaseProvider.java" --exec wc -l {} \;

Repository: eclipse-tracecompass/org.eclipse.tracecompass

Length of output: 203


🏁 Script executed:

# Read TmfBaseProvider to understand class hierarchy and addItem delegation
cat -n ./tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/TmfBaseProvider.java

Repository: eclipse-tracecompass/org.eclipse.tracecompass

Length of output: 10970


🏁 Script executed:

# Search for addItem calls in the codebase to see the pattern
rg -n "addItem\(" tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/ --type java -B2 -A1

# Also check if TmfCommonXLineChartTooltipProvider has any other addItem delegation
rg -n "addItem" tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java

Repository: eclipse-tracecompass/org.eclipse.tracecompass

Length of output: 4141


🏁 Script executed:

# Check TmfSimpleTooltipProvider structure to understand the pattern
fd -t f "TmfSimpleTooltipProvider.java" --exec cat -n {}

Repository: eclipse-tracecompass/org.eclipse.tracecompass

Length of output: 4135


🏁 Script executed:

# Check TmfClosestDataPointTooltipProvider structure
fd -t f "TmfClosestDataPointTooltipProvider.java" --exec head -150 {} \;

Repository: eclipse-tracecompass/org.eclipse.tracecompass

Length of output: 6622


🏁 Script executed:

# Check if TmfCommonXLineChartTooltipProvider might override addItem or delegate
rg -n "protected.*void.*addItem|private.*void.*addItem|public.*void.*addItem" tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/ --type java

# Check complete inheritance chain for any delegation mechanism
fd -t f "TmfCommonXLineChartTooltipProvider.java" -exec grep -n "extends\|implements" {}

Repository: eclipse-tracecompass/org.eclipse.tracecompass

Length of output: 319


🏁 Script executed:

# Check if TmfCommonXLineChartTooltipProvider might override addItem
rg "protected.*void.*addItem|private.*void.*addItem|public.*void.*addItem" tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java --type java

# Check complete inheritance chain
cat -n tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java | head -50

Repository: eclipse-tracecompass/org.eclipse.tracecompass

Length of output: 2575


🏁 Script executed:

# Verify if this code actually compiles - check for build artifacts or compilation results
find . -name "TmfCommonXLineChartTooltipProvider.class" 2>/dev/null

# Check git history to see if this code was recently changed
cd tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/ && git log --oneline -n 20 TmfCommonXLineChartTooltipProvider.java 2>/dev/null || echo "Git history not available"

Repository: eclipse-tracecompass/org.eclipse.tracecompass

Length of output: 146


🏁 Script executed:

# Check the recent refactoring commit to understand the change
cd tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/ && git show f7a2611d --stat

Repository: eclipse-tracecompass/org.eclipse.tracecompass

Length of output: 50402


🏁 Script executed:

# Get just the diff for the specific file in the commit
cd tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/ && git show f7a2611d -- TmfCommonXLineChartTooltipProvider.java

Repository: eclipse-tracecompass/org.eclipse.tracecompass

Length of output: 7502


🏁 Script executed:

# Verify if this file might have been changed or if there's an override of addItem
rg -B5 -A5 "protected.*void.*addItem\|private.*void.*addItem\|public.*void.*addItem" tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/TmfBaseProvider.java

Repository: eclipse-tracecompass/org.eclipse.tracecompass

Length of output: 71


🏁 Script executed:

# Final check: search for any delegation pattern that might make addItem accessible
rg "addItem" tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/TmfBaseProvider.java

Repository: eclipse-tracecompass/org.eclipse.tracecompass

Length of output: 71


Fix method accessibility issue in addSeriesTooltipItem()

The addSeriesTooltipItem() method on the outer class calls addItem() at lines 108 and 110, but addItem() is defined in TmfAbstractToolTipHandler, which only the inner class CommonToolTipHandler extends. The outer class TmfCommonXLineChartTooltipProvider extends TmfBaseProvider, which does not provide access to addItem(). This results in a compilation error.

To resolve, either:

  1. Move addSeriesTooltipItem() and formatSeriesLabel() logic into the CommonToolTipHandler.fill() method
  2. Pass the handler instance as a parameter: addSeriesTooltipItem(fToolTipHandler, ...)
  3. Delegate calls through the handler: fToolTipHandler.addItem(...) instead of direct addItem() calls
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java`
around lines 99 - 112, The compilation fails because addSeriesTooltipItem() in
TmfCommonXLineChartTooltipProvider calls addItem() which is defined on
TmfAbstractToolTipHandler, not the outer class; update addSeriesTooltipItem(...)
to use the tooltip handler instance (fToolTipHandler) to add items instead of
calling addItem() directly: replace the direct addItem(...) calls with
fToolTipHandler.addItem(...) (or change the method signature to accept a
TmfAbstractToolTipHandler parameter and call handler.addItem(...)); ensure
formatSeriesLabel(...) remains accessible (move into CommonToolTipHandler or
make it package-private/static if needed) and update any callers accordingly
(e.g., CommonToolTipHandler.fill() should call
addSeriesTooltipItem(fToolTipHandler, ... ) or the modified method that accepts
the handler).

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java (1)

145-148: Add defensive check before accessing getYAxes()[0].

The code accesses getYAxes()[0] without verifying the array is non-empty. While line charts typically have at least one Y axis, a defensive check would prevent a potential ArrayIndexOutOfBoundsException in edge cases.

🛡️ Proposed fix
             Format format = null;
             if (getChartViewer() instanceof TmfCommonXAxisChartViewer chartViewer) {
-                format = chartViewer.getSwtChart().getAxisSet().getYAxes()[0].getTick().getFormat();
+                org.eclipse.swtchart.IAxis[] yAxes = chartViewer.getSwtChart().getAxisSet().getYAxes();
+                if (yAxes.length > 0) {
+                    format = yAxes[0].getTick().getFormat();
+                }
             }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java`
around lines 145 - 148, The code in TmfCommonXLineChartTooltipProvider accesses
chartViewer.getSwtChart().getAxisSet().getYAxes()[0] without verifying the Y
axes array is present or non-empty; change the logic to fetch the YAxes array
into a local variable (e.g., Axis[] yAxes =
chartViewer.getSwtChart().getAxisSet().getYAxes()), check that yAxes != null &&
yAxes.length > 0 before calling yAxes[0].getTick().getFormat(), and leave format
as null or use a safe fallback if the check fails so no
ArrayIndexOutOfBoundsException occurs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java`:
- Around line 145-148: The code in TmfCommonXLineChartTooltipProvider accesses
chartViewer.getSwtChart().getAxisSet().getYAxes()[0] without verifying the Y
axes array is present or non-empty; change the logic to fetch the YAxes array
into a local variable (e.g., Axis[] yAxes =
chartViewer.getSwtChart().getAxisSet().getYAxes()), check that yAxes != null &&
yAxes.length > 0 before calling yAxes[0].getTick().getFormat(), and leave format
as null or use a safe fallback if the check fails so no
ArrayIndexOutOfBoundsException occurs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8b222e55-2bb7-4f10-8689-e68af601c08c

📥 Commits

Reviewing files that changed from the base of the PR and between f7a2611 and 38d85da.

📒 Files selected for processing (1)
  • tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (2)
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java (2)

114-121: ⚠️ Potential issue | 🟠 Major

Escape key before embedding it into HTML tooltip markup.

Line 115/Line 120 uses raw series IDs inside HTML. Labels containing <, &, or quotes can break rendering and inject unintended markup.

Proposed fix
     protected String formatSeriesLabel(IXYSeries series, String key) {
-        String label = (key == null) ? "" : key; //$NON-NLS-1$
+        String label = escapeHtml((key == null) ? "" : key); //$NON-NLS-1$
         Color color = series.getColor();
         if (color != null) {
             RGBA rgba = color.getRGBA();
             RGBAColor rgbaColor = new RGBAColor(rgba.rgb.red, rgba.rgb.green, rgba.rgb.blue, rgba.alpha);
             label = String.format(TmfCommonXLineChartTooltipProvider.HTML_COLOR_TOOLTIP, rgbaColor, label);
         }
         return label;
     }
+
+    private static String escapeHtml(String value) {
+        return value
+                .replace("&", "&amp;") //$NON-NLS-1$ //$NON-NLS-2$
+                .replace("<", "&lt;") //$NON-NLS-1$ //$NON-NLS-2$
+                .replace(">", "&gt;") //$NON-NLS-1$ //$NON-NLS-2$
+                .replace("\"", "&quot;") //$NON-NLS-1$ //$NON-NLS-2$
+                .replace("'", "&#39;"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java`
around lines 114 - 121, The series label is inserted raw into HTML in
formatSeriesLabel(IXYSeries series, String key), which can break rendering or
allow injection; before using key (the series ID) in the String.format(...) with
HTML_COLOR_TOOLTIP, HTML-escape special characters (&, <, >, " and ') and
preserve the existing null/empty handling so the escaped value is used instead
of the raw key; update formatSeriesLabel to replace or use a utility to perform
HTML escaping on key prior to embedding it in the tooltip string.

99-112: ⚠️ Potential issue | 🔴 Critical

Compilation issue: addItem(...) is invoked outside TmfAbstractToolTipHandler context.

At Line 108 and Line 110, addItem(...) is called from TmfCommonXLineChartTooltipProvider. That method is defined on the tooltip handler, so this call site is invalid and breaks compilation.

Proposed fix
+    `@FunctionalInterface`
+    protected interface TooltipItemSink {
+        void add(ToolTipString label, ToolTipString value);
+    }
+
-    protected void addSeriesTooltipItem(IXYSeries series, String key, int index, Format format) {
+    protected void addSeriesTooltipItem(IXYSeries series, String key, int index, Format format, TooltipItemSink sink) {
         double[] ySeries = series.getYSeries();
         if (ySeries == null || index < 0 || index >= ySeries.length) {
             return;
         }

         String label = formatSeriesLabel(series, key);
         double yValue = ySeries[index];
-        if (format == null) {
-            addItem(null, ToolTipString.fromHtml(label), ToolTipString.fromDecimal(yValue));
-        } else {
-            addItem(null, ToolTipString.fromHtml(label), ToolTipString.fromString(format.format(yValue)));
-        }
+        ToolTipString value = (format == null)
+                ? ToolTipString.fromDecimal(yValue)
+                : ToolTipString.fromString(format.format(yValue));
+        sink.add(ToolTipString.fromHtml(label), value);
     }
@@
-                addSeriesTooltipItem(xySeries, key, index, format);
+                addSeriesTooltipItem(xySeries, key, index, format, (label, value) -> addItem(null, label, value));

Also applies to: 162-162

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java`
around lines 99 - 112, The calls to addItem(...) inside
TmfCommonXLineChartTooltipProvider are invalid because addItem is a method on
TmfAbstractToolTipHandler; update addSeriesTooltipItem (and the similar call in
addEventsTooltipItem) to obtain the tooltip handler (via getToolTipHandler())
and invoke handler.addItem(...), guarding with a null check on the handler
before calling; ensure you pass the same arguments
(ToolTipString.fromHtml(label), ToolTipString.fromDecimal/
fromString(format...)) and remove the direct addItem(...) calls in
TmfCommonXLineChartTooltipProvider.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In
`@tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java`:
- Around line 114-121: The series label is inserted raw into HTML in
formatSeriesLabel(IXYSeries series, String key), which can break rendering or
allow injection; before using key (the series ID) in the String.format(...) with
HTML_COLOR_TOOLTIP, HTML-escape special characters (&, <, >, " and ') and
preserve the existing null/empty handling so the escaped value is used instead
of the raw key; update formatSeriesLabel to replace or use a utility to perform
HTML escaping on key prior to embedding it in the tooltip string.
- Around line 99-112: The calls to addItem(...) inside
TmfCommonXLineChartTooltipProvider are invalid because addItem is a method on
TmfAbstractToolTipHandler; update addSeriesTooltipItem (and the similar call in
addEventsTooltipItem) to obtain the tooltip handler (via getToolTipHandler())
and invoke handler.addItem(...), guarding with a null check on the handler
before calling; ensure you pass the same arguments
(ToolTipString.fromHtml(label), ToolTipString.fromDecimal/
fromString(format...)) and remove the direct addItem(...) calls in
TmfCommonXLineChartTooltipProvider.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6527fdc3-f10e-4b10-9d1f-1a74fb0812fc

📥 Commits

Reviewing files that changed from the base of the PR and between 38d85da and 7e4f1aa.

📒 Files selected for processing (1)
  • tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java

Refactor TmfCommonXLineChartTooltipProvider to make the tooltip population logic extensible for subclasses via protected hooks, while preserving the default tooltip behavior.

Also remove unused maxLen calculation that was left over from an earlier implementation.

Files:
- org.eclipse.tracecompass.tmf.ui.viewers.xychart.linechart.TmfCommonXLineChartTooltipProvider
@TranHoangThanhDuy
Copy link
Copy Markdown
Author

Hello @jonahgraham , @MatthewKhouzam ,

This is a refactor of TmfCommonXLineChartTooltipProvider.
The goal is to make the tooltip handling easier to extend (via small overridable hooks) while preserving the existing default behavior (time item + per-series value).
I’d appreciate a quick check for any functional regressions or API/style concerns.

Could someone please review my change?
Thank you in advance.
Duy Tran

Copy link
Copy Markdown
Contributor

@jonahgraham jonahgraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @TranHoangThanhDuy

The goal is to make the tooltip handling easier to extend (via small overridable hooks) while preserving the existing default behavior (time item + per-series value).

Thanks for the PR - the general idea seems good to me. In addition I like removing the calculation of maxLen that was no longer used anymore.

I am concerned that too much new API is added that isn't maintainable in the future, or makes this class too hard to update/evolve. Each new API method should be documented for its purpose and only make methods API that are need to be API.

Therefore, please change the new protected methods to private or document them.

Additionally, can you also complete the "what it does/how to test/etc" fields from the PR template in the top comment.

return getChartViewer().getWindowDuration() != 0;
}

protected int getHoveredIndex(List<IXYSeries> series, double xCoordinate) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be new API? Can extenders have a different algorithm to calculate the index?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. It doesn’t strictly need to be new API. I extracted it mainly to keep fill() smaller/readable and to avoid repeating the index calculation logic.
If you prefer not to expose this as an extension point, I can make getHoveredIndex(...) private.
How about this idea?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea - having the functionality extracted to make fill easier to read is a good idea. Lets keep all these new methods private unless explicitly needed to support extenders.

Copy link
Copy Markdown
Contributor

@MatthewKhouzam MatthewKhouzam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this, let's get it in. I gave a light nit on the logic.

}

String firstValidSeriesKey = null;
for (IXYSeries xySeries : series) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you make a copy of the list which is valid only? this could simplify the logic

@MatthewKhouzam
Copy link
Copy Markdown
Contributor

Also, please ssh / gpg sign your commit to prevent impersonation attacks.

@jonahgraham
Copy link
Copy Markdown
Contributor

Note that this code does not compile. Please let me know if you are having trouble setting up the development environment so you can develop and test your changes properly

Error from the build log:

Error: Failed to execute goal org.eclipse.tycho:tycho-compiler-plugin:4.0.11:compile (default-compile) on project org.eclipse.tracecompass.tmf.ui: Compilation failure: Compilation failure:
Error: /home/runner/work/org.eclipse.tracecompass/org.eclipse.tracecompass/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java:[99]
Error: addItem(null,
Error: ^^^^^^^
Error: The method addItem(null, TmfAbstractToolTipHandler.ToolTipString, TmfAbstractToolTipHandler.ToolTipString) is undefined for the type TmfCommonXLineChartTooltipProvider
Error: /home/runner/work/org.eclipse.tracecompass/org.eclipse.tracecompass/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java:[113]
Error: addItem(null, ToolTipString.fromHtml(label), ToolTipString.fromDecimal(yValue));
Error: ^^^^^^^
Error: The method addItem(null, TmfAbstractToolTipHandler.ToolTipString, TmfAbstractToolTipHandler.ToolTipString) is undefined for the type TmfCommonXLineChartTooltipProvider
Error: /home/runner/work/org.eclipse.tracecompass/org.eclipse.tracecompass/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xychart/linechart/TmfCommonXLineChartTooltipProvider.java:[115]
Error: addItem(null, ToolTipString.fromHtml(label), ToolTipString.fromString(format.format(yValue)));
Error: ^^^^^^^
Error: The method addItem(null, TmfAbstractToolTipHandler.ToolTipString, TmfAbstractToolTipHandler.ToolTipString) is undefined for the type TmfCommonXLineChartTooltipProvider

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants