tmf.ui: Bug 469644: Clear axises of chart when trace is closed
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / viewers / xycharts / TmfXYChartViewer.java
1 /**********************************************************************
2 * Copyright (c) 2013, 2015 Ericsson, École Polytechnique de Montréal
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 * Geneviève Bastien - Moved some methods to TmfTimeViewer
12 * Patrick Tasse - Fix setFocus
13 **********************************************************************/
14 package org.eclipse.tracecompass.tmf.ui.viewers.xycharts;
15
16 import org.eclipse.swt.SWT;
17 import org.eclipse.swt.events.MouseAdapter;
18 import org.eclipse.swt.events.MouseEvent;
19 import org.eclipse.swt.widgets.Composite;
20 import org.eclipse.swt.widgets.Control;
21 import org.eclipse.swt.widgets.Display;
22 import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
23 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
24 import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal;
25 import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal;
26 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
27 import org.eclipse.tracecompass.tmf.ui.viewers.TmfTimeViewer;
28 import org.swtchart.Chart;
29 import org.swtchart.IAxis;
30 import org.swtchart.ISeries;
31 import org.swtchart.ISeriesSet;
32 import org.swtchart.Range;
33
34 /**
35 * Base class for a XY-Chart based on SWT chart. It provides a methods to define
36 * zoom, selection and tool tip providers. It also provides call backs to be
37 * notified by any changes caused by selection and zoom.
38 *
39 * @author Bernd Hufmann
40 */
41 public abstract class TmfXYChartViewer extends TmfTimeViewer implements ITmfChartTimeProvider {
42
43 // ------------------------------------------------------------------------
44 // Attributes
45 // ------------------------------------------------------------------------
46 /** The SWT Chart reference */
47 private Chart fSwtChart;
48 /** The mouse selection provider */
49 private TmfBaseProvider fMouseSelectionProvider;
50 /** The mouse drag zoom provider */
51 private TmfBaseProvider fMouseDragZoomProvider;
52 /** The mouse wheel zoom provider */
53 private TmfBaseProvider fMouseWheelZoomProvider;
54 /** The tooltip provider */
55 private TmfBaseProvider fToolTipProvider;
56 /** The middle mouse drag provider */
57 private TmfBaseProvider fMouseDragProvider;
58 /**
59 * Whether or not to send time alignment signals. This should be set to true
60 * for viewers that are part of an aligned view.
61 */
62 private boolean fSendTimeAlignSignals = false;
63
64
65 // ------------------------------------------------------------------------
66 // Constructors
67 // ------------------------------------------------------------------------
68
69 /**
70 * Constructs a TmfXYChartViewer.
71 *
72 * @param parent
73 * The parent composite
74 * @param title
75 * The title of the viewer
76 * @param xLabel
77 * The label of the xAxis
78 * @param yLabel
79 * The label of the yAXIS
80 */
81 public TmfXYChartViewer(Composite parent, String title, String xLabel, String yLabel) {
82 super(parent, title);
83 fSwtChart = new Chart(parent, SWT.NONE) {
84 @Override
85 public boolean setFocus() {
86 return fSwtChart.getPlotArea().setFocus();
87 }
88 };
89 fSwtChart.getPlotArea().addMouseListener(new MouseAdapter() {
90 @Override
91 public void mouseDown(MouseEvent e) {
92 fSwtChart.getPlotArea().setFocus();
93 }
94 });
95
96 IAxis xAxis = fSwtChart.getAxisSet().getXAxis(0);
97 IAxis yAxis = fSwtChart.getAxisSet().getYAxis(0);
98
99 /* Set the title/labels, or hide them if they are not provided */
100 if (title == null) {
101 fSwtChart.getTitle().setVisible(false);
102 } else {
103 fSwtChart.getTitle().setText(title);
104 }
105 if (xLabel == null) {
106 xAxis.getTitle().setVisible(false);
107 } else {
108 xAxis.getTitle().setText(xLabel);
109 }
110 if (yLabel == null) {
111 yAxis.getTitle().setVisible(false);
112 } else {
113 yAxis.getTitle().setText(yLabel);
114 }
115
116 fMouseSelectionProvider = new TmfMouseSelectionProvider(this);
117 fMouseDragZoomProvider = new TmfMouseDragZoomProvider(this);
118 fMouseWheelZoomProvider = new TmfMouseWheelZoomProvider(this);
119 fToolTipProvider = new TmfSimpleTooltipProvider(this);
120 fMouseDragProvider = new TmfMouseDragProvider(this);
121 }
122
123 // ------------------------------------------------------------------------
124 // Getter/Setters
125 // ------------------------------------------------------------------------
126
127 /**
128 * Sets the SWT Chart reference
129 *
130 * @param chart
131 * The SWT chart to set.
132 */
133 protected void setSwtChart(Chart chart) {
134 fSwtChart = chart;
135 }
136
137 /**
138 * Gets the SWT Chart reference
139 *
140 * @return the SWT chart to set.
141 */
142 protected Chart getSwtChart() {
143 return fSwtChart;
144 }
145
146 /**
147 * Sets a mouse selection provider. An existing provider will be
148 * disposed. Use <code>null</code> to disable the mouse selection provider.
149 *
150 * @param provider
151 * The selection provider to set
152 */
153 public void setSelectionProvider(TmfBaseProvider provider) {
154 if (fMouseSelectionProvider != null) {
155 fMouseSelectionProvider.dispose();
156 }
157 fMouseSelectionProvider = provider;
158 }
159
160 /**
161 * Sets a mouse drag zoom provider. An existing provider will be
162 * disposed. Use <code>null</code> to disable the mouse drag zoom provider.
163 *
164 * @param provider
165 * The mouse drag zoom provider to set
166 */
167 public void setMouseDragZoomProvider(TmfBaseProvider provider) {
168 if (fMouseDragZoomProvider != null) {
169 fMouseDragZoomProvider.dispose();
170 }
171 fMouseDragZoomProvider = provider;
172 }
173
174 /**
175 * Sets a mouse wheel zoom provider. An existing provider will be
176 * disposed. Use <code>null</code> to disable the mouse wheel zoom
177 * provider.
178 *
179 * @param provider
180 * The mouse wheel zoom provider to set
181 */
182 public void setMouseWheelZoomProvider(TmfBaseProvider provider) {
183 if (fMouseWheelZoomProvider != null) {
184 fMouseWheelZoomProvider.dispose();
185 }
186 fMouseWheelZoomProvider = provider;
187 }
188
189 /**
190 * Sets a tooltip provider. An existing provider will be
191 * disposed. Use <code>null</code> to disable the tooltip provider.
192 *
193 * @param provider
194 * The tooltip provider to set
195 */
196 public void setTooltipProvider(TmfBaseProvider provider) {
197 if (fToolTipProvider != null) {
198 fToolTipProvider.dispose();
199 }
200 fToolTipProvider = provider;
201 }
202
203 /**
204 * Sets a mouse drag provider. An existing provider will be
205 * disposed. Use <code>null</code> to disable the mouse drag provider.
206 *
207 * @param provider
208 * The mouse drag provider to set
209 */
210 public void setMouseDrageProvider(TmfBaseProvider provider) {
211 if (fMouseDragProvider != null) {
212 fMouseDragProvider.dispose();
213 }
214 fMouseDragProvider = provider;
215 }
216
217 // ------------------------------------------------------------------------
218 // ITmfChartTimeProvider
219 // ------------------------------------------------------------------------
220
221 @Override
222 public long getTimeOffset() {
223 return getWindowStartTime() - 1;
224 }
225
226 // ------------------------------------------------------------------------
227 // ITmfViewer interface
228 // ------------------------------------------------------------------------
229 @Override
230 public Control getControl() {
231 return fSwtChart;
232 }
233
234 @Override
235 public void refresh() {
236 fSwtChart.redraw();
237 }
238
239 // ------------------------------------------------------------------------
240 // TmfComponent
241 // ------------------------------------------------------------------------
242 @Override
243 public void dispose() {
244 super.dispose();
245 fSwtChart.dispose();
246
247 if (fMouseSelectionProvider != null) {
248 fMouseSelectionProvider.dispose();
249 }
250
251 if (fMouseDragZoomProvider != null) {
252 fMouseDragZoomProvider.dispose();
253 }
254
255 if (fMouseWheelZoomProvider != null) {
256 fMouseWheelZoomProvider.dispose();
257 }
258
259 if (fToolTipProvider != null) {
260 fToolTipProvider.dispose();
261 }
262
263 if (fMouseDragProvider != null) {
264 fMouseDragProvider.dispose();
265 }
266 }
267
268 // ------------------------------------------------------------------------
269 // Operations
270 // ------------------------------------------------------------------------
271 /**
272 * A Method to load a trace into the viewer.
273 *
274 * @param trace
275 * A trace to apply in the viewer
276 */
277 @Override
278 public void loadTrace(ITmfTrace trace) {
279 super.loadTrace(trace);
280 clearContent();
281 updateContent();
282 }
283
284 /**
285 * Resets the content of the viewer
286 */
287 @Override
288 public void reset() {
289 super.reset();
290 setStartTime(0);
291 setEndTime(0);
292 clearContent();
293 }
294
295 /**
296 * Method to implement to update the chart content.
297 */
298 protected abstract void updateContent();
299
300 // ------------------------------------------------------------------------
301 // Signal Handler
302 // ------------------------------------------------------------------------
303
304 /**
305 * Signal handler for handling of the time synch signal.
306 *
307 * @param signal
308 * The time synch signal {@link TmfSelectionRangeUpdatedSignal}
309 */
310 @Override
311 @TmfSignalHandler
312 public void selectionRangeUpdated(TmfSelectionRangeUpdatedSignal signal) {
313 super.selectionRangeUpdated(signal);
314 if ((signal.getSource() != this) && (getTrace() != null)) {
315 if (fMouseSelectionProvider != null) {
316 fMouseSelectionProvider.refresh();
317 }
318 }
319 }
320
321 /**
322 * Signal handler for handling of the window range signal.
323 *
324 * @param signal
325 * The {@link TmfWindowRangeUpdatedSignal}
326 */
327 @Override
328 @TmfSignalHandler
329 public void windowRangeUpdated(TmfWindowRangeUpdatedSignal signal) {
330 super.windowRangeUpdated(signal);
331 updateContent();
332 }
333
334 /**
335 * Signal handler for handling the signal that notifies about an updated
336 * timestamp format.
337 *
338 * @param signal
339 * The trace updated signal
340 * {@link TmfTimestampFormatUpdateSignal}
341 */
342 @TmfSignalHandler
343 public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) {
344 fSwtChart.getAxisSet().adjustRange();
345 fSwtChart.redraw();
346 }
347
348 // ------------------------------------------------------------------------
349 // Helper Methods
350 // ------------------------------------------------------------------------
351
352 /**
353 * Clears the view content.
354 */
355 protected void clearContent() {
356 if (!fSwtChart.isDisposed()) {
357 ISeriesSet set = fSwtChart.getSeriesSet();
358 ISeries[] series = set.getSeries();
359 for (int i = 0; i < series.length; i++) {
360 set.deleteSeries(series[i].getId());
361 }
362 for (IAxis axis: fSwtChart.getAxisSet().getAxes()){
363 axis.setRange(new Range(0,1));
364 }
365 fSwtChart.redraw();
366 }
367 }
368
369 /**
370 * Returns the current or default display.
371 *
372 * @return the current or default display
373 */
374 protected static Display getDisplay() {
375 Display display = Display.getCurrent();
376 // may be null if outside the UI thread
377 if (display == null) {
378 display = Display.getDefault();
379 }
380 return display;
381 }
382
383 /**
384 * Get the offset of the point area, relative to the XY chart viewer
385 * control. We consider the point area to be from where the first point
386 * could be drawn to where the last point could be drawn.
387 *
388 * @return the offset in pixels
389 *
390 * @since 1.0
391 */
392 public int getPointAreaOffset() {
393
394 int pixelCoordinate = 0;
395 IAxis[] xAxes = getSwtChart().getAxisSet().getXAxes();
396 ISeries[] series = fSwtChart.getSeriesSet().getSeries();
397 if ((xAxes.length > 0) && (series.length > 0) &&
398 (series[0].getXSeries() != null) && (series[0].getXSeries().length > 0)) {
399 IAxis axis = xAxes[0];
400 // All series have the same X series
401 double[] xSeries = series[0].getXSeries();
402 pixelCoordinate = axis.getPixelCoordinate(xSeries[0]);
403 }
404 return getSwtChart().toControl(getSwtChart().getPlotArea().toDisplay(pixelCoordinate, 0)).x;
405 }
406
407 /**
408 * Get the width of the point area. We consider the point area to be from
409 * where the first point could be drawn to where the last point could be
410 * drawn. The point area differs from the plot area because there might be a
411 * gap between where the plot area start and where the fist point is drawn.
412 * This also matches the width that the use can select.
413 *
414 * @return the width in pixels
415 *
416 * @since 1.0
417 */
418 public int getPointAreaWidth() {
419 IAxis[] xAxes = getSwtChart().getAxisSet().getXAxes();
420 ISeries[] series = fSwtChart.getSeriesSet().getSeries();
421 if ((xAxes.length > 0) && (series.length > 0) &&
422 (series[0].getXSeries() != null) && (series[0].getXSeries().length > 0)) {
423 IAxis axis = xAxes[0];
424 // All series have the same X series
425 double[] xSeries = series[0].getXSeries();
426 int x1 = getPointAreaOffset();
427 int x2 = axis.getPixelCoordinate(xSeries[xSeries.length - 1]);
428 x2 = getSwtChart().toControl(getSwtChart().getPlotArea().toDisplay(x2, 0)).x;
429 int width = x2 - x1;
430 return width;
431 }
432
433 return getSwtChart().getPlotArea().getSize().x;
434 }
435
436 /**
437 * Sets whether or not to send time alignment signals. This should be set to
438 * true for viewers that are part of an aligned view.
439 *
440 * @param sendTimeAlignSignals
441 * whether or not to send time alignment signals
442 * @since 1.0
443 */
444 public void setSendTimeAlignSignals(boolean sendTimeAlignSignals) {
445 fSendTimeAlignSignals = sendTimeAlignSignals;
446 }
447
448 /**
449 * Returns whether or not to send time alignment signals.
450 *
451 * @return whether or not to send time alignment signals.
452 * @since 1.0
453 */
454 public boolean isSendTimeAlignSignals() {
455 return fSendTimeAlignSignals;
456 }
457 }
This page took 0.042354 seconds and 5 git commands to generate.