1 /**********************************************************************
2 * Copyright (c) 2015 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Bernd Hufmann - Initial API and implementation
11 **********************************************************************/
12 package org
.eclipse
.tracecompass
.tmf
.ui
.viewers
.xycharts
;
14 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
16 import org
.eclipse
.jdt
.annotation
.NonNull
;
17 import org
.eclipse
.jdt
.annotation
.Nullable
;
18 import org
.eclipse
.swt
.SWT
;
19 import org
.eclipse
.swt
.events
.MouseEvent
;
20 import org
.eclipse
.swt
.events
.MouseMoveListener
;
21 import org
.eclipse
.swt
.events
.MouseTrackListener
;
22 import org
.eclipse
.swt
.events
.PaintEvent
;
23 import org
.eclipse
.swt
.events
.PaintListener
;
24 import org
.eclipse
.swt
.widgets
.Display
;
25 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimestamp
;
26 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestamp
;
27 import org
.swtchart
.IAxis
;
28 import org
.swtchart
.ISeries
;
31 * Abstract tooltip provider for xy chart viewers. It displays the y value and y
32 * value of the data point of the mouse position. Extending classes can provide
33 * a custom tooltip text.
35 * @author Bernd Hufmann
38 public class TmfClosestDataPointTooltipProvider
extends TmfBaseProvider
implements MouseTrackListener
, MouseMoveListener
, PaintListener
{
40 // ------------------------------------------------------------------------
42 // ------------------------------------------------------------------------
43 private static final int ALPHA
= 128;
44 private static final int HIGHLIGHT_RADIUS
= 5;
46 // ------------------------------------------------------------------------
48 // ------------------------------------------------------------------------
49 /** X coordinate for highlighting */
50 private int fHighlightX
;
51 /** y coordinate for highlighting */
52 private int fHighlightY
;
53 /** Flag to do highlighting or not */
54 private boolean fIsHighlight
;
56 // ------------------------------------------------------------------------
58 // ------------------------------------------------------------------------
60 * Constructor for a tool tip provider.
62 * @param tmfChartViewer
63 * - the parent chart viewer
65 public TmfClosestDataPointTooltipProvider(ITmfChartTimeProvider tmfChartViewer
) {
66 super(tmfChartViewer
);
70 // ------------------------------------------------------------------------
72 // ------------------------------------------------------------------------
74 public void register() {
75 getChart().getPlotArea().addMouseTrackListener(this);
76 getChart().getPlotArea().addMouseMoveListener(this);
77 getChart().getPlotArea().addPaintListener(this);
81 public void deregister() {
82 if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) {
83 getChart().getPlotArea().removeMouseTrackListener(this);
84 getChart().getPlotArea().removeMouseMoveListener(this);
85 getChart().getPlotArea().removePaintListener(this);
90 public void refresh() {
94 // ------------------------------------------------------------------------
96 // ------------------------------------------------------------------------
98 public void mouseEnter(MouseEvent e
) {
102 public void mouseExit(MouseEvent e
) {
106 public void mouseHover(MouseEvent e
) {
107 if ((getChartViewer().getWindowDuration() != 0) && (e
!= null)) {
108 IAxis xAxis
= getChart().getAxisSet().getXAxis(0);
109 IAxis yAxis
= getChart().getAxisSet().getYAxis(0);
111 ISeries
[] series
= getChart().getSeriesSet().getSeries();
113 double smallestDistance
= Double
.MAX_VALUE
;
114 Parameter param
= null;
116 // go over all series
117 for (int k
= 0; k
< series
.length
; k
++) {
118 ISeries serie
= series
[k
];
119 double[] xS
= serie
.getXSeries();
120 double[] yS
= serie
.getYSeries();
122 if ((xS
== null) || (yS
== null)) {
125 // go over all data points
126 for (int i
= 0; i
< xS
.length
; i
++) {
127 int xs
= xAxis
.getPixelCoordinate(xS
[i
]) - e
.x
;
128 int ys
= yAxis
.getPixelCoordinate(yS
[i
]) - e
.y
;
129 double currentDistance
= xs
* xs
+ ys
* ys
;
132 * Check for smallest distance to mouse position and
133 * only consider it if the mouse is close the data point.
135 if ((currentDistance
< smallestDistance
) && (currentDistance
< (HIGHLIGHT_RADIUS
* HIGHLIGHT_RADIUS
))) {
136 smallestDistance
= currentDistance
;
137 fHighlightX
= xs
+ e
.x
;
138 fHighlightY
= ys
+ e
.y
;
140 param
= new Parameter();
142 param
.setSeriesIndex(k
);
143 param
.setDataIndex(i
);
147 String tooltip
= null;
149 tooltip
= createToolTipText(param
);
150 if (tooltip
!= null) {
156 * Note that tooltip might be null which will clear the
157 * previous tooltip string. This is intentional.
159 getChart().getPlotArea().setToolTipText(tooltip
);
163 // ------------------------------------------------------------------------
165 // ------------------------------------------------------------------------
167 public void mouseMove(@Nullable MouseEvent e
) {
168 fIsHighlight
= false;
172 // ------------------------------------------------------------------------
174 // ------------------------------------------------------------------------
176 public void paintControl(PaintEvent e
) {
177 if (fIsHighlight
&& e
!= null) {
178 e
.gc
.setBackground(Display
.getDefault().getSystemColor(
180 e
.gc
.setAlpha(ALPHA
);
182 e
.gc
.fillOval(fHighlightX
- HIGHLIGHT_RADIUS
, fHighlightY
- HIGHLIGHT_RADIUS
,
183 2 * HIGHLIGHT_RADIUS
, 2 * HIGHLIGHT_RADIUS
);
188 * Creates the tooltip based on the given parameter.
191 * parameter to create the tooltip string
192 * @return the tooltip based on the given parameter.
194 protected String
createToolTipText(@NonNull Parameter param
) {
195 ISeries
[] series
= getChart().getSeriesSet().getSeries();
196 int seriesIndex
= param
.getSeriesIndex();
197 int dataIndex
= param
.getDataIndex();
198 if ((series
!= null) && (seriesIndex
< series
.length
)) {
199 ISeries serie
= series
[seriesIndex
];
200 double[] xS
= serie
.getXSeries();
201 double[] yS
= serie
.getYSeries();
202 if ((xS
!= null) && (yS
!= null) && (dataIndex
< xS
.length
) && (dataIndex
< yS
.length
)) {
203 StringBuffer buffer
= new StringBuffer();
204 buffer
.append(checkNotNull("x=")); //$NON-NLS-1$
205 buffer
.append(new TmfTimestamp((long) xS
[dataIndex
] + getChartViewer().getTimeOffset(), ITmfTimestamp
.NANOSECOND_SCALE
).toString());
207 buffer
.append("y="); //$NON-NLS-1$
208 buffer
.append((long) yS
[dataIndex
]);
209 return buffer
.toString();
218 protected static class Parameter
{
220 private int seriesIndex
;
221 /* A data point index within a series */
222 private int dataIndex
;
225 * @return the series index
227 public int getSeriesIndex() {
233 * index the seriesIndex to set
235 public void setSeriesIndex(int seriesIndex
) {
236 this.seriesIndex
= seriesIndex
;
240 * @return the data index
242 public int getDataIndex() {
248 * the data index to set
250 public void setDataIndex(int dataIndex
) {
251 this.dataIndex
= dataIndex
;