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 org
.eclipse
.jdt
.annotation
.NonNull
;
15 import org
.eclipse
.jdt
.annotation
.Nullable
;
16 import org
.eclipse
.swt
.SWT
;
17 import org
.eclipse
.swt
.events
.MouseEvent
;
18 import org
.eclipse
.swt
.events
.MouseMoveListener
;
19 import org
.eclipse
.swt
.events
.MouseTrackListener
;
20 import org
.eclipse
.swt
.events
.PaintEvent
;
21 import org
.eclipse
.swt
.events
.PaintListener
;
22 import org
.eclipse
.swt
.widgets
.Display
;
23 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestamp
;
24 import org
.swtchart
.IAxis
;
25 import org
.swtchart
.ISeries
;
28 * Abstract tooltip provider for xy chart viewers. It displays the y value and y
29 * value of the data point of the mouse position. Extending classes can provide
30 * a custom tooltip text.
32 * @author Bernd Hufmann
35 public class TmfClosestDataPointTooltipProvider
extends TmfBaseProvider
implements MouseTrackListener
, MouseMoveListener
, PaintListener
{
37 // ------------------------------------------------------------------------
39 // ------------------------------------------------------------------------
40 private static final int ALPHA
= 128;
41 private static final int HIGHLIGHT_RADIUS
= 5;
43 // ------------------------------------------------------------------------
45 // ------------------------------------------------------------------------
46 /** X coordinate for highlighting */
47 private int fHighlightX
;
48 /** y coordinate for highlighting */
49 private int fHighlightY
;
50 /** Flag to do highlighting or not */
51 private boolean fIsHighlight
;
53 // ------------------------------------------------------------------------
55 // ------------------------------------------------------------------------
57 * Constructor for a tool tip provider.
59 * @param tmfChartViewer
60 * - the parent chart viewer
62 public TmfClosestDataPointTooltipProvider(ITmfChartTimeProvider tmfChartViewer
) {
63 super(tmfChartViewer
);
67 // ------------------------------------------------------------------------
69 // ------------------------------------------------------------------------
71 public void register() {
72 getChart().getPlotArea().addMouseTrackListener(this);
73 getChart().getPlotArea().addMouseMoveListener(this);
74 getChart().getPlotArea().addPaintListener(this);
78 public void deregister() {
79 if ((getChartViewer().getControl() != null) && !getChartViewer().getControl().isDisposed()) {
80 getChart().getPlotArea().removeMouseTrackListener(this);
81 getChart().getPlotArea().removeMouseMoveListener(this);
82 getChart().getPlotArea().removePaintListener(this);
87 public void refresh() {
91 // ------------------------------------------------------------------------
93 // ------------------------------------------------------------------------
95 public void mouseEnter(MouseEvent e
) {
99 public void mouseExit(MouseEvent e
) {
103 public void mouseHover(MouseEvent e
) {
104 if ((getChartViewer().getWindowDuration() != 0) && (e
!= null)) {
105 IAxis xAxis
= getChart().getAxisSet().getXAxis(0);
106 IAxis yAxis
= getChart().getAxisSet().getYAxis(0);
108 ISeries
[] series
= getChart().getSeriesSet().getSeries();
110 double smallestDistance
= Double
.MAX_VALUE
;
111 Parameter param
= null;
113 // go over all series
114 for (int k
= 0; k
< series
.length
; k
++) {
115 ISeries serie
= series
[k
];
116 double[] xS
= serie
.getXSeries();
117 double[] yS
= serie
.getYSeries();
119 if ((xS
== null) || (yS
== null)) {
122 // go over all data points
123 for (int i
= 0; i
< xS
.length
; i
++) {
124 int xs
= xAxis
.getPixelCoordinate(xS
[i
]) - e
.x
;
125 int ys
= yAxis
.getPixelCoordinate(yS
[i
]) - e
.y
;
126 double currentDistance
= xs
* xs
+ ys
* ys
;
129 * Check for smallest distance to mouse position and only
130 * consider it if the mouse is close the data point.
132 if ((currentDistance
< smallestDistance
) && (currentDistance
< (HIGHLIGHT_RADIUS
* HIGHLIGHT_RADIUS
))) {
133 smallestDistance
= currentDistance
;
134 fHighlightX
= xs
+ e
.x
;
135 fHighlightY
= ys
+ e
.y
;
137 param
= new Parameter();
139 param
.setSeriesIndex(k
);
140 param
.setDataIndex(i
);
144 String tooltip
= null;
146 tooltip
= createToolTipText(param
);
147 if (tooltip
!= null) {
153 * Note that tooltip might be null which will clear the previous
154 * tooltip string. This is intentional.
156 getChart().getPlotArea().setToolTipText(tooltip
);
160 // ------------------------------------------------------------------------
162 // ------------------------------------------------------------------------
164 public void mouseMove(@Nullable MouseEvent e
) {
166 fIsHighlight
= false;
171 // ------------------------------------------------------------------------
173 // ------------------------------------------------------------------------
175 public void paintControl(PaintEvent e
) {
176 if (fIsHighlight
&& e
!= null) {
177 e
.gc
.setBackground(Display
.getDefault().getSystemColor(
179 e
.gc
.setAlpha(ALPHA
);
181 e
.gc
.fillOval(fHighlightX
- HIGHLIGHT_RADIUS
, fHighlightY
- HIGHLIGHT_RADIUS
,
182 2 * HIGHLIGHT_RADIUS
, 2 * HIGHLIGHT_RADIUS
);
187 * Creates the tooltip based on the given parameter.
190 * parameter to create the tooltip string
191 * @return the tooltip based on the given parameter.
193 protected String
createToolTipText(@NonNull Parameter param
) {
194 ISeries
[] series
= getChart().getSeriesSet().getSeries();
195 int seriesIndex
= param
.getSeriesIndex();
196 int dataIndex
= param
.getDataIndex();
197 if ((series
!= null) && (seriesIndex
< series
.length
)) {
198 ISeries serie
= series
[seriesIndex
];
199 double[] xS
= serie
.getXSeries();
200 double[] yS
= serie
.getYSeries();
201 if ((xS
!= null) && (yS
!= null) && (dataIndex
< xS
.length
) && (dataIndex
< yS
.length
)) {
202 StringBuffer buffer
= new StringBuffer();
203 buffer
.append("x="); //$NON-NLS-1$
204 buffer
.append(TmfTimestamp
.fromNanos((long) xS
[dataIndex
] + getChartViewer().getTimeOffset()).toString());
206 buffer
.append("y="); //$NON-NLS-1$
207 buffer
.append((long) yS
[dataIndex
]);
208 return buffer
.toString();
217 protected static class Parameter
{
219 private int seriesIndex
;
220 /* A data point index within a series */
221 private int dataIndex
;
224 * @return the series index
226 public int getSeriesIndex() {
232 * index the seriesIndex to set
234 public void setSeriesIndex(int seriesIndex
) {
235 this.seriesIndex
= seriesIndex
;
239 * @return the data index
241 public int getDataIndex() {
247 * the data index to set
249 public void setDataIndex(int dataIndex
) {
250 this.dataIndex
= dataIndex
;