2828import org .eclipse .tracecompass .tmf .core .timestamp .ITmfTimestamp ;
2929import org .eclipse .tracecompass .tmf .core .timestamp .TmfTimestamp ;
3030import org .eclipse .tracecompass .tmf .ui .viewers .TmfAbstractToolTipHandler ;
31+ import org .eclipse .tracecompass .tmf .ui .viewers .TmfAbstractToolTipHandler .ToolTipString ;
3132import org .eclipse .tracecompass .tmf .ui .viewers .xychart .IAxis ;
3233import org .eclipse .tracecompass .tmf .ui .viewers .xychart .ITmfChartTimeProvider ;
3334import org .eclipse .tracecompass .tmf .ui .viewers .xychart .IXYSeries ;
4344 */
4445public class TmfCommonXLineChartTooltipProvider extends TmfBaseProvider {
4546
46- private final class XYToolTipHandler extends TmfAbstractToolTipHandler {
47- private static final String HTML_COLOR_TOOLTIP = "<span style=\" color:%s;\" >%s</span>" ; //$NON-NLS-1$
48-
49- private boolean isValid (int index , IXYSeries serie ) {
50- double [] ySeries = serie .getYSeries ();
51- return serie .isVisible () && ySeries != null && ySeries .length > index ;
52- }
53-
54- @ Override
55- public void fill (Control control , MouseEvent event , Point pt ) {
56- if (getChartViewer ().getWindowDuration () != 0 ) {
57- IAxis xAxis = getXAxis ();
58-
59- double xCoordinate = xAxis .getDataCoordinate (pt .x );
60-
61- List <IXYSeries > series = getSeries ();
62-
63- if ((xCoordinate < 0 ) || (series .isEmpty ())) {
64- return ;
65- }
66-
67- /* Find the index of the value we want */
68- double [] xS = series .get (0 ).getXSeries ();
69- if (xS == null ) {
70- return ;
71- }
72- int index = Arrays .binarySearch (xS , xCoordinate );
73- index = index >= 0 ? index : -index - 1 ;
74- int maxLen = 0 ;
75- for (IXYSeries serie : series ) {
76- /* Make sure the series values and the value at index exist */
77- if (isValid (index , serie )) {
78- maxLen = Math .max (maxLen , serie .getId ().length ());
79- }
80- }
81-
82- TmfCommonXAxisChartViewer viewer = null ;
83- Format format = null ;
84- ITmfChartTimeProvider timeProvider = getChartViewer ();
85- if (timeProvider instanceof TmfCommonXAxisChartViewer ) {
86- viewer = (TmfCommonXAxisChartViewer ) timeProvider ;
87- format = viewer .getSwtChart ().getAxisSet ().getYAxes ()[0 ].getTick ().getFormat ();
88- }
89- ITmfTimestamp time = TmfTimestamp .fromNanos ((long ) xCoordinate + getChartViewer ().getTimeOffset ());
90- addItem (null , ToolTipString .fromString (Messages .TmfCommonXLineChartTooltipProvider_time ), ToolTipString .fromTimestamp (time .toString (), time .toNanos ()));
91- /* For each series, get the value at the index */
92- for (IXYSeries serie : series ) {
93- double [] yS = serie .getYSeries ();
94- /* Make sure the series values and the value at index exist */
95- if (isValid (index , serie )) {
96- String key = serie .getId ();
97- Color color = serie .getColor ();
98- if (key != null && color != null && viewer != null ) {
99- RGBA rgba = color .getRGBA ();
100- RGBAColor rgbaColor = new RGBAColor (rgba .rgb .red , rgba .rgb .green , rgba .rgb .blue , rgba .alpha );
101- key = String .format (HTML_COLOR_TOOLTIP , rgbaColor , key );
102- }
103- if (key == null ) {
104- key = "" ; //$NON-NLS-1$
105- }
106- double yValue = yS [index ];
107- if (format == null ) {
108- addItem (null , ToolTipString .fromHtml (key ), ToolTipString .fromDecimal (yValue ));
109- } else {
110- addItem (null , ToolTipString .fromHtml (key ), ToolTipString .fromString (format .format (yValue )));
111- }
112- }
113- }
114- }
115- }
116-
117- }
118-
119- private XYToolTipHandler fToolTipHandler = new XYToolTipHandler ();
47+ private static final String HTML_COLOR_TOOLTIP = "<span style=\" color:%s;\" >%s</span>" ; //$NON-NLS-1$
48+ private final CommonToolTipHandler fToolTipHandler = new CommonToolTipHandler ();
12049
12150 /**
12251 * Constructor for the tooltip provider
@@ -142,4 +71,139 @@ public TmfAbstractToolTipHandler getTooltipHandler() {
14271 public void refresh () {
14372 // nothing to do
14473 }
74+
75+ // ======================================================================
76+ // HOOK METHODS
77+ // ======================================================================
78+
79+ @ FunctionalInterface
80+ protected interface ITooltipItemAdder {
81+ void addItem (ToolTipString key , ToolTipString value );
82+ }
83+
84+ protected void addAdditionalTooltipItems (ITooltipItemAdder adder , double xCoordinate ) {
85+ long timeNanos = Math .round (xCoordinate ) + getChartViewer ().getTimeOffset ();
86+ ITmfTimestamp time = TmfTimestamp .fromNanos (timeNanos );
87+ adder .addItem (
88+ ToolTipString .fromString (Messages .TmfCommonXLineChartTooltipProvider_time ),
89+ ToolTipString .fromTimestamp (time .toString (), time .toNanos ()));
90+ }
91+
92+ protected void addSeriesTooltipItem (ITooltipItemAdder adder , IXYSeries xySeries , int index , Format format ) {
93+ double [] ySeries = xySeries .getYSeries ();
94+ if (ySeries == null || index < 0 || index >= ySeries .length ) {
95+ return ;
96+ }
97+
98+ String label = formatSeriesLabel (xySeries );
99+ double yValue = ySeries [index ];
100+ if (format == null ) {
101+ adder .addItem (
102+ ToolTipString .fromHtml (label ),
103+ ToolTipString .fromDecimal (yValue ));
104+ } else {
105+ adder .addItem (
106+ ToolTipString .fromHtml (label ),
107+ ToolTipString .fromString (format .format (yValue )));
108+ }
109+ }
110+
111+ protected String formatSeriesLabel (IXYSeries xySeries ) {
112+ String label = xySeries .getId ();
113+ if (label == null ) {
114+ label = "" ; //$NON-NLS-1$
115+ }
116+
117+ Color color = xySeries .getColor ();
118+ if (color != null ) {
119+ RGBA rgba = color .getRGBA ();
120+ RGBAColor rgbaColor = new RGBAColor (rgba .rgb .red , rgba .rgb .green , rgba .rgb .blue , rgba .alpha );
121+ label = String .format (TmfCommonXLineChartTooltipProvider .HTML_COLOR_TOOLTIP , rgbaColor , label );
122+ }
123+
124+ return label ;
125+ }
126+
127+ protected String getFirstValidSeriesKey () {
128+ return fToolTipHandler .firstValidSeriesKey ;
129+ }
130+
131+ // ======================================================================
132+ // TOOLTIP HANDLER
133+ // ======================================================================
134+
135+ private final class CommonToolTipHandler extends TmfAbstractToolTipHandler {
136+
137+ private String firstValidSeriesKey ;
138+
139+ @ Override
140+ public void fill (Control control , MouseEvent event , Point pt ) {
141+ if (!isTooltipAvailable ()) {
142+ return ;
143+ }
144+
145+ IAxis xAxis = getXAxis ();
146+ double xCoordinate = xAxis .getDataCoordinate (pt .x );
147+ if (xCoordinate < 0 ) {
148+ return ;
149+ }
150+
151+ List <IXYSeries > series = getSeries ();
152+ int index = getHoveredIndex (series , xCoordinate );
153+ if (index < 0 ) {
154+ return ;
155+ }
156+
157+ Format format = null ;
158+ if (getChartViewer () instanceof TmfCommonXAxisChartViewer chartViewer ) {
159+ format = chartViewer .getSwtChart ().getAxisSet ().getYAxes ()[0 ].getTick ().getFormat ();
160+ }
161+
162+ boolean firstValid = true ;
163+ for (IXYSeries xySeries : series ) {
164+ if (!isValidSeriesIndex (xySeries , index )) {
165+ continue ;
166+ }
167+
168+ if (firstValid ) {
169+ firstValid = false ;
170+ firstValidSeriesKey = xySeries .getId ();
171+ addAdditionalTooltipItems ((key , value ) -> addItem (null , key , value ), xCoordinate );
172+ }
173+
174+ addSeriesTooltipItem ((key , value ) -> addItem (null , key , value ), xySeries , index , format );
175+ }
176+ }
177+
178+ private boolean isTooltipAvailable () {
179+ return getChartViewer ().getWindowDuration () != 0 ;
180+ }
181+
182+ private int getHoveredIndex (List <IXYSeries > series , double xCoordinate ) {
183+ if (series .isEmpty ()) {
184+ return -1 ;
185+ }
186+
187+ double [] xSeries = series .get (0 ).getXSeries ();
188+ if (xSeries == null || xSeries .length == 0 ) {
189+ return -1 ;
190+ }
191+
192+ int index = Arrays .binarySearch (xSeries , xCoordinate );
193+ if (index < 0 ) {
194+ index = -index - 1 ;
195+ index = Math .max (0 , index - 1 );
196+ }
197+
198+ return index < xSeries .length ? index : -1 ;
199+ }
200+
201+ private boolean isValidSeriesIndex (IXYSeries series , int index ) {
202+ double [] ySeries = series .getYSeries ();
203+ return series .isVisible ()
204+ && ySeries != null
205+ && index >= 0
206+ && index < ySeries .length ;
207+ }
208+ }
145209}
0 commit comments