tmf: Avoid unnecessary redraw in TmfClosestDataPointTooltipProvider
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / viewers / xycharts / TmfClosestDataPointTooltipProvider.java
1 /**********************************************************************
2 * Copyright (c) 2015 Ericsson
3 *
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
8 *
9 * Contributors:
10 * Bernd Hufmann - Initial API and implementation
11 **********************************************************************/
12 package org.eclipse.tracecompass.tmf.ui.viewers.xycharts;
13
14 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
15
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;
29
30 /**
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.
34 *
35 * @author Bernd Hufmann
36 * @since 2.0
37 */
38 public class TmfClosestDataPointTooltipProvider extends TmfBaseProvider implements MouseTrackListener, MouseMoveListener, PaintListener {
39
40 // ------------------------------------------------------------------------
41 // Constants
42 // ------------------------------------------------------------------------
43 private static final int ALPHA = 128;
44 private static final int HIGHLIGHT_RADIUS = 5;
45
46 // ------------------------------------------------------------------------
47 // Attributes
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;
55
56 // ------------------------------------------------------------------------
57 // Constructors
58 // ------------------------------------------------------------------------
59 /**
60 * Constructor for a tool tip provider.
61 *
62 * @param tmfChartViewer
63 * - the parent chart viewer
64 */
65 public TmfClosestDataPointTooltipProvider(ITmfChartTimeProvider tmfChartViewer) {
66 super(tmfChartViewer);
67 register();
68 }
69
70 // ------------------------------------------------------------------------
71 // TmfBaseProvider
72 // ------------------------------------------------------------------------
73 @Override
74 public void register() {
75 getChart().getPlotArea().addMouseTrackListener(this);
76 getChart().getPlotArea().addMouseMoveListener(this);
77 getChart().getPlotArea().addPaintListener(this);
78 }
79
80 @Override
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);
86 }
87 }
88
89 @Override
90 public void refresh() {
91 // nothing to do
92 }
93
94 // ------------------------------------------------------------------------
95 // MouseTrackListener
96 // ------------------------------------------------------------------------
97 @Override
98 public void mouseEnter(MouseEvent e) {
99 }
100
101 @Override
102 public void mouseExit(MouseEvent e) {
103 }
104
105 @Override
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);
110
111 ISeries[] series = getChart().getSeriesSet().getSeries();
112
113 double smallestDistance = Double.MAX_VALUE;
114 Parameter param = null;
115
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();
121
122 if ((xS == null) || (yS == null)) {
123 continue;
124 }
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;
130
131 /*
132 * Check for smallest distance to mouse position and
133 * only consider it if the mouse is close the data point.
134 */
135 if ((currentDistance < smallestDistance) && (currentDistance < (HIGHLIGHT_RADIUS * HIGHLIGHT_RADIUS))) {
136 smallestDistance = currentDistance;
137 fHighlightX = xs + e.x;
138 fHighlightY = ys + e.y;
139 if (param == null) {
140 param = new Parameter();
141 }
142 param.setSeriesIndex(k);
143 param.setDataIndex(i);
144 }
145 }
146 }
147 String tooltip = null;
148 if (param != null) {
149 tooltip = createToolTipText(param);
150 if (tooltip != null) {
151 fIsHighlight = true;
152 getChart().redraw();
153 }
154 }
155 /*
156 * Note that tooltip might be null which will clear the
157 * previous tooltip string. This is intentional.
158 */
159 getChart().getPlotArea().setToolTipText(tooltip);
160 }
161 }
162
163 // ------------------------------------------------------------------------
164 // MouseMoveListener
165 // ------------------------------------------------------------------------
166 @Override
167 public void mouseMove(@Nullable MouseEvent e) {
168 if (fIsHighlight) {
169 fIsHighlight = false;
170 getChart().redraw();
171 }
172 }
173
174 // ------------------------------------------------------------------------
175 // PaintListener
176 // ------------------------------------------------------------------------
177 @Override
178 public void paintControl(PaintEvent e) {
179 if (fIsHighlight && e != null) {
180 e.gc.setBackground(Display.getDefault().getSystemColor(
181 SWT.COLOR_RED));
182 e.gc.setAlpha(ALPHA);
183
184 e.gc.fillOval(fHighlightX - HIGHLIGHT_RADIUS, fHighlightY - HIGHLIGHT_RADIUS,
185 2 * HIGHLIGHT_RADIUS, 2 * HIGHLIGHT_RADIUS);
186 }
187 }
188
189 /**
190 * Creates the tooltip based on the given parameter.
191 *
192 * @param param
193 * parameter to create the tooltip string
194 * @return the tooltip based on the given parameter.
195 */
196 protected String createToolTipText(@NonNull Parameter param) {
197 ISeries[] series = getChart().getSeriesSet().getSeries();
198 int seriesIndex = param.getSeriesIndex();
199 int dataIndex = param.getDataIndex();
200 if ((series != null) && (seriesIndex < series.length)) {
201 ISeries serie = series[seriesIndex];
202 double[] xS = serie.getXSeries();
203 double[] yS = serie.getYSeries();
204 if ((xS != null) && (yS != null) && (dataIndex < xS.length) && (dataIndex < yS.length)) {
205 StringBuffer buffer = new StringBuffer();
206 buffer.append(checkNotNull("x=")); //$NON-NLS-1$
207 buffer.append(new TmfTimestamp((long) xS[dataIndex] + getChartViewer().getTimeOffset(), ITmfTimestamp.NANOSECOND_SCALE).toString());
208 buffer.append('\n');
209 buffer.append("y="); //$NON-NLS-1$
210 buffer.append((long) yS[dataIndex]);
211 return buffer.toString();
212 }
213 }
214 return null;
215 }
216
217 /**
218 * Parameter class
219 */
220 protected static class Parameter {
221 /* A series index */
222 private int seriesIndex;
223 /* A data point index within a series */
224 private int dataIndex;
225
226 /**
227 * @return the series index
228 */
229 public int getSeriesIndex() {
230 return seriesIndex;
231 }
232
233 /**
234 * @param seriesIndex
235 * index the seriesIndex to set
236 */
237 public void setSeriesIndex(int seriesIndex) {
238 this.seriesIndex = seriesIndex;
239 }
240
241 /**
242 * @return the data index
243 */
244 public int getDataIndex() {
245 return dataIndex;
246 }
247
248 /**
249 * @param dataIndex
250 * the data index to set
251 */
252 public void setDataIndex(int dataIndex) {
253 this.dataIndex = dataIndex;
254 }
255
256 }
257 }
This page took 0.037656 seconds and 5 git commands to generate.