Commit | Line | Data |
---|---|---|
83842d7d | 1 | /********************************************************************** |
60ae41e1 | 2 | * Copyright (c) 2013, 2014 Ericsson |
83842d7d BH |
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 | * Alexandre Montplaisir - Initial API and implementation | |
11 | * Bernd Hufmann - Updated for TMF base chart viewer | |
12 | **********************************************************************/ | |
13 | package org.eclipse.linuxtools.tmf.ui.viewers.xycharts.barcharts; | |
14 | ||
15 | import java.util.ArrayList; | |
16 | import java.util.List; | |
17 | ||
18 | import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.TmfChartTimeStampFormat; | |
19 | import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.TmfXYChartViewer; | |
20 | import org.eclipse.swt.graphics.Color; | |
21 | import org.eclipse.swt.graphics.RGB; | |
22 | import org.eclipse.swt.widgets.Composite; | |
23 | import org.eclipse.swt.widgets.Display; | |
24 | import org.swtchart.Chart; | |
25 | import org.swtchart.IAxisTick; | |
26 | import org.swtchart.IBarSeries; | |
27 | import org.swtchart.ISeries; | |
28 | import org.swtchart.ISeries.SeriesType; | |
29 | ||
30 | /** | |
31 | * Abstract bar chart viewer class implementation. Used for displaying | |
32 | * histograms. | |
33 | * | |
34 | * @author Alexandre Montplaisir | |
35 | * @author Bernd Hufmann | |
36 | * @since 3.0 | |
37 | */ | |
38 | public abstract class TmfBarChartViewer extends TmfXYChartViewer { | |
39 | ||
40 | // ------------------------------------------------------------------------ | |
41 | // Constants | |
42 | // ------------------------------------------------------------------------ | |
43 | /** Width of each histogram bar, in pixels */ | |
44 | public static final int MINIMUM_BAR_WIDTH = 1; | |
45 | ||
46 | // ------------------------------------------------------------------------ | |
47 | // Attributes | |
48 | // ------------------------------------------------------------------------ | |
49 | /** List of series */ | |
50 | private final List<String> seriesNames = new ArrayList<>(); | |
51 | /** List of colors */ | |
52 | private final List<RGB> colors = new ArrayList<>(); | |
53 | /** the bar width */ | |
54 | private int fBarWidth = MINIMUM_BAR_WIDTH; | |
55 | ||
56 | // ------------------------------------------------------------------------ | |
57 | // Constructors | |
58 | // ------------------------------------------------------------------------ | |
59 | /** | |
60 | * Constructs a TmfXYChartViewer. | |
61 | * | |
62 | * @param parent | |
63 | * The parent composite | |
64 | * @param title | |
65 | * The title of the viewer | |
66 | * @param xLabel | |
67 | * The label of the xAxis | |
68 | * @param yLabel | |
69 | * The label of the yAXIS | |
70 | * @param barWidth | |
71 | * The bar width | |
72 | */ | |
73 | public TmfBarChartViewer(Composite parent, String title, String xLabel, String yLabel, int barWidth) { | |
74 | super(parent, title, xLabel, yLabel); | |
75 | fBarWidth = barWidth; | |
76 | ||
77 | setTooltipProvider(new TmfHistogramTooltipProvider(this)); | |
78 | } | |
79 | ||
80 | // ------------------------------------------------------------------------ | |
81 | // Operations | |
82 | // ------------------------------------------------------------------------ | |
83 | @Override | |
84 | protected void updateContent() { | |
85 | ||
86 | getDisplay().asyncExec(new Runnable() { | |
87 | ||
88 | @Override | |
89 | public void run() { | |
90 | Chart swtChart = getSwtChart(); | |
91 | int numRequests = swtChart.getPlotArea().getBounds().width / fBarWidth; | |
92 | ||
93 | for (int i = 0; i < seriesNames.size(); i++) { | |
94 | ISeries series = swtChart.getSeriesSet().getSeries(seriesNames.get(i)); | |
95 | if (series == null) { | |
96 | series = initSeries(seriesNames.get(i), colors.get(i)); | |
97 | } | |
98 | readData(series, getWindowStartTime(), getWindowEndTime(), numRequests); | |
99 | } | |
100 | } | |
101 | }); | |
102 | } | |
103 | ||
104 | /** | |
105 | * Method to add a series to the chart. | |
106 | * | |
107 | * @param name | |
108 | * Name of series | |
109 | * @param color | |
110 | * color to use for series | |
111 | */ | |
112 | protected void addSeries(String name, RGB color) { | |
113 | seriesNames.add(name); | |
114 | colors.add(color); | |
115 | } | |
116 | ||
117 | /** | |
118 | * Clears all series | |
119 | */ | |
120 | protected void clearSeries() { | |
121 | seriesNames.clear(); | |
122 | colors.clear(); | |
123 | } | |
124 | ||
125 | /** | |
126 | * Draw the given series on the chart | |
127 | * | |
128 | * @param series | |
129 | * The series to display | |
130 | * @param x | |
131 | * The X values. It can be computed with | |
132 | * {@link TmfBarChartViewer#getXAxis} | |
133 | * The values are stored in the internal time representation. | |
134 | * To get the trace time one has to add the time offset | |
135 | * {@link #getTimeOffset()}. | |
136 | * @param y | |
137 | * The Y values that were computed by the extended class | |
138 | */ | |
139 | protected void drawChart(final ISeries series, final double[] x, final double[] y) { | |
140 | // Run in GUI thread to make sure that chart is ready after restart | |
141 | final Display display = getDisplay(); | |
142 | if (display.isDisposed()) { | |
143 | return; | |
144 | } | |
145 | ||
146 | display.syncExec(new Runnable() { | |
147 | @Override | |
148 | public void run() { | |
149 | if (display.isDisposed()) { | |
150 | return; | |
151 | } | |
152 | Chart swtChart = getSwtChart(); | |
153 | IAxisTick xTick = swtChart.getAxisSet().getXAxis(0).getTick(); | |
154 | xTick.setFormat(new TmfChartTimeStampFormat(getTimeOffset())); | |
155 | series.setXSeries(x); | |
156 | series.setYSeries(y); | |
157 | xTick.setTickMarkStepHint(256); | |
158 | ||
159 | swtChart.getAxisSet().adjustRange(); | |
160 | swtChart.redraw(); | |
161 | } | |
162 | }); | |
163 | } | |
164 | ||
165 | /** | |
166 | * Convenience method to compute the X axis values for a given time range. | |
167 | * | |
168 | * @param start | |
169 | * Start of the time range | |
170 | * @param end | |
171 | * End of the range | |
172 | * @param nb | |
173 | * Number of steps. This will be the size of the returned array. | |
174 | * @return The time values (converted to double) that match every step | |
175 | */ | |
176 | protected final double[] getXAxis(long start, long end, int nb) { | |
177 | setTimeOffset(start - 1); | |
178 | double timestamps[] = new double[nb]; | |
179 | long steps = (end - start); | |
180 | double step = steps / (double) nb; | |
181 | ||
182 | double curTime = 1; | |
183 | for (int i = 0; i < nb; i++) { | |
184 | timestamps[i] = curTime; | |
185 | curTime += step; | |
186 | } | |
187 | return timestamps; | |
188 | } | |
189 | ||
190 | /** | |
191 | * Load the data for the given series. This method should call | |
192 | * {@link TmfBarChartViewer#drawChart} to return the results when done. | |
193 | * | |
194 | * Careful, this method is called by a signal handler which also happens to | |
195 | * be in the main UI thread. This means any processing will block the UI! In | |
196 | * most cases it's probably better to start a separate Thread/Job to do the | |
197 | * processing, and that one can call drawChart() when done to update the | |
198 | * view. | |
199 | * | |
200 | * @param series | |
201 | * Which series of the chart should the viewer update | |
202 | * @param start | |
203 | * The start time (in nanoseconds) of the range to display | |
204 | * @param end | |
205 | * The end time of the range to display. | |
206 | * @param nb | |
207 | * The number of 'steps' in the bar chart (fewer steps means each | |
208 | * bar is wider). | |
209 | */ | |
210 | protected abstract void readData(ISeries series, long start, long end, int nb); | |
211 | ||
212 | // initializes a series | |
213 | private IBarSeries initSeries(String name, RGB color) { | |
214 | IBarSeries bs = (IBarSeries) getSwtChart().getSeriesSet().createSeries(SeriesType.BAR, name); | |
215 | bs.enableStack(true); | |
216 | bs.setBarColor(new Color(Display.getDefault(), color)); | |
217 | bs.setBarPadding(0); | |
218 | return bs; | |
219 | } | |
220 | } |