1 /**********************************************************************
2 * Copyright (c) 2013, 2015 Ericsson, École Polytechnique de Montréal
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 * Geneviève Bastien - Moved some methods to TmfTimeViewer
12 * Patrick Tasse - Fix setFocus
13 **********************************************************************/
14 package org
.eclipse
.tracecompass
.tmf
.ui
.viewers
.xycharts
;
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
;
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.
39 * @author Bernd Hufmann
41 public abstract class TmfXYChartViewer
extends TmfTimeViewer
implements ITmfChartTimeProvider
{
43 // ------------------------------------------------------------------------
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
;
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.
62 private boolean fSendTimeAlignSignals
= false;
65 // ------------------------------------------------------------------------
67 // ------------------------------------------------------------------------
70 * Constructs a TmfXYChartViewer.
73 * The parent composite
75 * The title of the viewer
77 * The label of the xAxis
79 * The label of the yAXIS
81 public TmfXYChartViewer(Composite parent
, String title
, String xLabel
, String yLabel
) {
83 fSwtChart
= new Chart(parent
, SWT
.NONE
) {
85 public boolean setFocus() {
86 return fSwtChart
.getPlotArea().setFocus();
89 fSwtChart
.getPlotArea().addMouseListener(new MouseAdapter() {
91 public void mouseDown(MouseEvent e
) {
92 fSwtChart
.getPlotArea().setFocus();
96 IAxis xAxis
= fSwtChart
.getAxisSet().getXAxis(0);
97 IAxis yAxis
= fSwtChart
.getAxisSet().getYAxis(0);
99 /* Set the title/labels, or hide them if they are not provided */
101 fSwtChart
.getTitle().setVisible(false);
103 fSwtChart
.getTitle().setText(title
);
105 if (xLabel
== null) {
106 xAxis
.getTitle().setVisible(false);
108 xAxis
.getTitle().setText(xLabel
);
110 if (yLabel
== null) {
111 yAxis
.getTitle().setVisible(false);
113 yAxis
.getTitle().setText(yLabel
);
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);
123 // ------------------------------------------------------------------------
125 // ------------------------------------------------------------------------
128 * Sets the SWT Chart reference
131 * The SWT chart to set.
133 protected void setSwtChart(Chart chart
) {
138 * Gets the SWT Chart reference
140 * @return the SWT chart to set.
142 protected Chart
getSwtChart() {
147 * Sets a mouse selection provider. An existing provider will be
148 * disposed. Use <code>null</code> to disable the mouse selection provider.
151 * The selection provider to set
153 public void setSelectionProvider(TmfBaseProvider provider
) {
154 if (fMouseSelectionProvider
!= null) {
155 fMouseSelectionProvider
.dispose();
157 fMouseSelectionProvider
= provider
;
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.
165 * The mouse drag zoom provider to set
167 public void setMouseDragZoomProvider(TmfBaseProvider provider
) {
168 if (fMouseDragZoomProvider
!= null) {
169 fMouseDragZoomProvider
.dispose();
171 fMouseDragZoomProvider
= provider
;
175 * Sets a mouse wheel zoom provider. An existing provider will be
176 * disposed. Use <code>null</code> to disable the mouse wheel zoom
180 * The mouse wheel zoom provider to set
182 public void setMouseWheelZoomProvider(TmfBaseProvider provider
) {
183 if (fMouseWheelZoomProvider
!= null) {
184 fMouseWheelZoomProvider
.dispose();
186 fMouseWheelZoomProvider
= provider
;
190 * Sets a tooltip provider. An existing provider will be
191 * disposed. Use <code>null</code> to disable the tooltip provider.
194 * The tooltip provider to set
196 public void setTooltipProvider(TmfBaseProvider provider
) {
197 if (fToolTipProvider
!= null) {
198 fToolTipProvider
.dispose();
200 fToolTipProvider
= provider
;
204 * Sets a mouse drag provider. An existing provider will be
205 * disposed. Use <code>null</code> to disable the mouse drag provider.
208 * The mouse drag provider to set
210 public void setMouseDrageProvider(TmfBaseProvider provider
) {
211 if (fMouseDragProvider
!= null) {
212 fMouseDragProvider
.dispose();
214 fMouseDragProvider
= provider
;
217 // ------------------------------------------------------------------------
218 // ITmfChartTimeProvider
219 // ------------------------------------------------------------------------
222 public long getTimeOffset() {
223 return getWindowStartTime() - 1;
226 // ------------------------------------------------------------------------
227 // ITmfViewer interface
228 // ------------------------------------------------------------------------
230 public Control
getControl() {
235 public void refresh() {
239 // ------------------------------------------------------------------------
241 // ------------------------------------------------------------------------
243 public void dispose() {
247 if (fMouseSelectionProvider
!= null) {
248 fMouseSelectionProvider
.dispose();
251 if (fMouseDragZoomProvider
!= null) {
252 fMouseDragZoomProvider
.dispose();
255 if (fMouseWheelZoomProvider
!= null) {
256 fMouseWheelZoomProvider
.dispose();
259 if (fToolTipProvider
!= null) {
260 fToolTipProvider
.dispose();
263 if (fMouseDragProvider
!= null) {
264 fMouseDragProvider
.dispose();
268 // ------------------------------------------------------------------------
270 // ------------------------------------------------------------------------
272 * A Method to load a trace into the viewer.
275 * A trace to apply in the viewer
278 public void loadTrace(ITmfTrace trace
) {
279 super.loadTrace(trace
);
285 * Resets the content of the viewer
288 public void reset() {
296 * Method to implement to update the chart content.
298 protected abstract void updateContent();
300 // ------------------------------------------------------------------------
302 // ------------------------------------------------------------------------
305 * Signal handler for handling of the time synch signal.
308 * The time synch signal {@link TmfSelectionRangeUpdatedSignal}
312 public void selectionRangeUpdated(TmfSelectionRangeUpdatedSignal signal
) {
313 super.selectionRangeUpdated(signal
);
314 if ((signal
.getSource() != this) && (getTrace() != null)) {
315 if (fMouseSelectionProvider
!= null) {
316 fMouseSelectionProvider
.refresh();
322 * Signal handler for handling of the window range signal.
325 * The {@link TmfWindowRangeUpdatedSignal}
329 public void windowRangeUpdated(TmfWindowRangeUpdatedSignal signal
) {
330 super.windowRangeUpdated(signal
);
335 * Signal handler for handling the signal that notifies about an updated
339 * The trace updated signal
340 * {@link TmfTimestampFormatUpdateSignal}
343 public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal
) {
344 fSwtChart
.getAxisSet().adjustRange();
348 // ------------------------------------------------------------------------
350 // ------------------------------------------------------------------------
353 * Clears the view content.
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());
362 for (IAxis axis
: fSwtChart
.getAxisSet().getAxes()){
363 axis
.setRange(new Range(0,1));
370 * Returns the current or default display.
372 * @return the current or default display
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();
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.
388 * @return the offset in pixels
392 public int getPointAreaOffset() {
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 double minX
= Double
.MAX_VALUE
;
403 for (double x
: xSeries
) {
409 pixelCoordinate
= axis
.getPixelCoordinate(minX
);
411 return getSwtChart().toControl(getSwtChart().getPlotArea().toDisplay(pixelCoordinate
, 0)).x
;
415 * Get the width of the point area. We consider the point area to be from
416 * where the first point could be drawn to where the last point could be
417 * drawn. The point area differs from the plot area because there might be a
418 * gap between where the plot area start and where the fist point is drawn.
419 * This also matches the width that the use can select.
421 * @return the width in pixels
425 public int getPointAreaWidth() {
426 IAxis
[] xAxes
= getSwtChart().getAxisSet().getXAxes();
427 ISeries
[] series
= fSwtChart
.getSeriesSet().getSeries();
428 if ((xAxes
.length
> 0) && (series
.length
> 0) &&
429 (series
[0].getXSeries() != null) && (series
[0].getXSeries().length
> 0)) {
430 IAxis axis
= xAxes
[0];
431 // All series have the same X series
432 double[] xSeries
= series
[0].getXSeries();
433 double maxX
= Double
.MIN_VALUE
;
434 for (double x
: xSeries
) {
440 int x1
= getPointAreaOffset();
441 int x2
= axis
.getPixelCoordinate(maxX
);
442 x2
= getSwtChart().toControl(getSwtChart().getPlotArea().toDisplay(x2
, 0)).x
;
447 return getSwtChart().getPlotArea().getSize().x
;
451 * Sets whether or not to send time alignment signals. This should be set to
452 * true for viewers that are part of an aligned view.
454 * @param sendTimeAlignSignals
455 * whether or not to send time alignment signals
458 public void setSendTimeAlignSignals(boolean sendTimeAlignSignals
) {
459 fSendTimeAlignSignals
= sendTimeAlignSignals
;
463 * Returns whether or not to send time alignment signals.
465 * @return whether or not to send time alignment signals.
468 public boolean isSendTimeAlignSignals() {
469 return fSendTimeAlignSignals
;