Internalize lttng.ui APIs
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.ui / src / org / eclipse / linuxtools / internal / lttng / ui / views / latency / listeners / HistogramPaintListener.java
1 /*******************************************************************************
2 * Copyright (c) 2010, 2011 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 * Philippe Sawicki (INF4990.A2010@gmail.com) - Initial API and implementation
11 * Mathieu Denis (mathieu.denis55@gmail.com) - Refactored code
12 * Bernd Hufmann - Adapted to new model-view-controller design, display improvements
13 *******************************************************************************/
14 package org.eclipse.linuxtools.internal.lttng.ui.views.latency.listeners;
15
16 import java.text.DecimalFormat;
17 import java.util.Collections;
18 import java.util.Vector;
19
20 import org.eclipse.linuxtools.internal.lttng.ui.views.latency.AbstractViewer;
21 import org.eclipse.linuxtools.internal.lttng.ui.views.latency.HistogramViewer;
22 import org.eclipse.linuxtools.internal.lttng.ui.views.latency.Messages;
23 import org.eclipse.linuxtools.tmf.ui.views.histogram.HistogramScaledData;
24 import org.eclipse.linuxtools.tmf.ui.views.histogram.HistogramUtils;
25 import org.eclipse.linuxtools.tmf.ui.views.histogram.IHistogramDataModel;
26 import org.eclipse.swt.graphics.Image;
27 import org.eclipse.swt.graphics.Point;
28 import org.eclipse.swt.widgets.Display;
29 import org.eclipse.ui.plugin.AbstractUIPlugin;
30
31 /**
32 * <b><u>HistogramPaintListener</u></b>
33 * <p>
34 * Histogram paint listener.
35 *
36 * @author Philippe Sawicki
37 */
38 public class HistogramPaintListener extends AbstractPaintListener {
39
40 // ------------------------------------------------------------------------
41 // Attributes
42 // ------------------------------------------------------------------------
43
44 /**
45 * Is a histogram bar so high that it is clipped from the draw area ?
46 */
47 private boolean fBarIsClipped = false;
48
49 /**
50 * Scaled data from data model
51 */
52 protected HistogramScaledData fScaledData;
53
54 /**
55 * Warning Image
56 */
57 protected Image fWarningImage;
58
59 // ------------------------------------------------------------------------
60 // Constructors
61 // ------------------------------------------------------------------------
62
63 /**
64 * Constructor.
65 * @param view
66 * A reference to the listener's viewer.
67 */
68 public HistogramPaintListener(AbstractViewer viewer) {
69 super(viewer);
70 fWarningImage = AbstractUIPlugin.imageDescriptorFromPlugin(Messages.LatencyView_tmf_UI, "icons/elcl16/warning.gif").createImage(Display.getCurrent()); //$NON-NLS-1$
71 }
72
73 // ------------------------------------------------------------------------
74 // Accessors
75 // ------------------------------------------------------------------------
76
77 /**
78 * Returns the histogram's bar Width.
79 * @return The histogram's bar Width.
80 */
81 public int getBarWidth() {
82 return fBarWith;
83 }
84
85 // ------------------------------------------------------------------------
86 // Operations
87 // ------------------------------------------------------------------------
88
89 /*
90 * (non-Javadoc)
91 * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#dispose()
92 */
93 @Override
94 public void dispose() {
95 fWarningImage.dispose();
96 super.dispose();
97 }
98
99 /*
100 * (non-Javadoc)
101 * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#scale()
102 */
103 @Override
104 public void scale() {
105 // width of the plot area
106 double width = getWidth();
107 // height of the plot area
108 double height = getHeight();
109
110 int barWidth = getBarWidth();
111
112 IHistogramDataModel model = ((HistogramViewer)fViewer).getModel();
113 fScaledData = model.scaleTo((int)width, (int)height, barWidth);
114
115 fYMin = 0;
116 fYMax = fScaledData.fMaxValue;
117
118 fXMin = fScaledData.getFirstBucketTime();
119 fXMin = fXMin > 0 ? fXMin : 0;
120 fXMax = fScaledData.getBucketEndTime(fScaledData.fLastBucket - 1);
121
122 // No data to display - set end time to 0
123 if (fYMax == 0) {
124 fXMax = 0;
125 }
126 }
127
128 /*
129 * (non-Javadoc)
130 * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#paintVerticalTicks(int)
131 */
132 @Override
133 public void paintVerticalTicks(int x) {
134 // done in method paintVerticalAxisValues()
135 }
136
137 /*
138 * (non-Javadoc)
139 * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#paintVerticalAxisValues(int)
140 */
141 @Override
142 public void paintVerticalAxisValues(int x) {
143 int zoomFactor = 1;
144
145 zoomFactor = fViewer.getZoomFactor();
146
147 if (fYMin >= 0L && fYMax != 0L) {
148 fAxisImage.setForeground(fTextColor);
149 fAxisImage.setBackground(fBackgroundColor);
150
151 // Apply the zoom to the max value of the graph for the next calculations
152 long yMax = fYMax / zoomFactor;
153
154 int nbTicks = ((int)getHeight()) / MAX_HEIGHT_BETWEEN_TICKS + 1;
155
156 Vector<Integer> values = new Vector<Integer>();
157 boolean multipleSameValues = true;
158 while (multipleSameValues) {
159 double valueStep = (double) (yMax - fYMin) / (double) (nbTicks);
160
161 for (int i = 0; i < nbTicks; i++) {
162 double currentValue = (double) (fYMin + i * valueStep) / (Math.pow(10, fDelta));
163
164 values.add((int) currentValue);
165 }
166
167 Collections.sort(values);
168 boolean hasRepetition = false;
169 for (int i = 1; i < values.size(); i++) {
170 if (values.get(i) == values.get(i - 1)) {
171 hasRepetition = true;
172 break;
173 }
174 }
175
176 if (hasRepetition) {
177 nbTicks--;
178 values.clear();
179 } else {
180 multipleSameValues = false;
181
182 // Draw rectangle over the old values
183 int height = fViewer.getBounds().height - 2 * fPadding - fPaddingTop - fHorizontalAxisYOffset;
184 fAxisImage.fillRectangle(0, fPadding + fPaddingTop, fPadding + fVerticalAxisOffset, height);
185
186 double pixelStep = (getHeight()) / values.size() + 1;
187
188 for (int i = 0; i < values.size(); i++) {
189 double currentValue = values.get(i);
190
191 int y = (int) (fClientArea.height - fPadding - fHorizontalAxisYOffset - i * pixelStep);
192 String currentLabel = formatStringForVerticalAxis((long) currentValue);
193
194 fAxisImage.setFont(fValuesFont);
195
196 Point textDimensions = fAxisImage.stringExtent(currentLabel);
197 fAxisImage.drawText(currentLabel, x - textDimensions.x - 5, y - textDimensions.y / 2);
198 fAxisImage.drawLine(x - 3, y, x, y);
199 }
200 }
201 }
202 }
203 }
204
205 /*
206 * (non-Javadoc)
207 * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#paintContent()
208 */
209 @Override
210 public void paintContent() {
211 double zoomFactor = fViewer.getZoomFactor();
212
213 // Calculate the vertical axis factor and see if it has changed
214 double tmpDelta = fDelta;
215 fDelta = 0;
216 if (Long.toString(fYMax / (long) zoomFactor).length() > MAX_CHAR_VERTICAL_DISPLAY) {
217 fDelta = Long.toString(fYMax / (long) zoomFactor).length() - MAX_CHAR_VERTICAL_DISPLAY;
218 }
219 if (tmpDelta != fDelta) {
220 fViewer.clearBackground();
221 }
222
223 paintBackground();
224 paintVerticalAxis();
225 paintHorizontalAxis();
226
227 fAxisImage.setForeground(fDataColor);
228 fAxisImage.setBackground(fDataColor);
229
230 // height of the plot area
231 double height = getHeight();
232
233 int barWidth = getBarWidth();
234
235 // axisImage_.setBackground(backgroundColor_);
236 // 1.a Iterate over the points, from 0 to nbPoints
237 // 1.b Find the max counter value
238 // 2. Assign the max value to the "yMax_" class attribute
239 // 3. Draw the histogram bars using "axisImage_.fillRectangle(...)"
240 boolean oneBarIsClipped = false;
241
242 for (int i = 0; i < fScaledData.fData.length; i++) {
243 double pointY = fScaledData.fData[i];
244
245 // in pixels
246 double x = fPadding + i * barWidth + fVerticalAxisOffset + 1;
247
248 if (i == fScaledData.fData.length - 1)
249 x -= 1.0;
250 double barHeight = zoomFactor * ((double)(pointY - fYMin) / (double)(fYMax - fYMin)) * height;
251
252 if (barHeight > height + 1) {
253 barHeight = height;
254 oneBarIsClipped = true;
255
256 fAxisImage.drawImage(fWarningImage, 5, 3);
257 }
258
259 // Only draw the bars that have a barHeight of more than 1 pixel
260 if (barHeight > 0) {
261 double y = fPadding + fPaddingTop + height - barHeight;
262 fAxisImage.setBackground(fDataColor);
263
264 if (barHeight > height - 1) {
265 fAxisImage.fillRectangle((int) x, (int) y, (int) barWidth, (int) (barHeight + 1));
266 } else {
267 fAxisImage.fillRectangle((int) x, (int) y, (int) barWidth, (int) (barHeight + 2));
268 }
269 }
270 }
271
272 if (oneBarIsClipped)
273 fBarIsClipped = true;
274 else
275 fBarIsClipped = false;
276 }
277
278 /**
279 * Paints the histogram horizontal axis values in engineering notation in which the exponent is a multiple of three.
280 * @param value
281 * The numeric value to convert to engineering notation.
282 * @return The given value formatted according to the engineering notation.
283 */
284 @Override
285 public String formatStringForHorizontalAxis(long value) {
286 DecimalFormat formatter = new DecimalFormat("##0.#E0"); //$NON-NLS-1$
287 return formatter.format(value);
288 }
289
290 /**
291 * Sets the bar width.
292 * @param barWidth
293 * bar width to set
294 */
295 public void setBarWidth(int barWidth) {
296 fBarWith = barWidth;
297 }
298
299 /**
300 * Returns "true" if a histogram bar is so high that it cannot be drawn in the draw area, "false" otherwise.
301 * @return "true" if a histogram bar is so high that it cannot be drawn in the draw area, "false" otherwise.
302 */
303 public boolean barIsClipped() {
304 return fBarIsClipped;
305 }
306
307 /*
308 * (non-Javadoc)
309 * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#formatToolTipLabel(int, int)
310 */
311 @Override
312 public String formatToolTipLabel(int x, int y) {
313 if (fScaledData != null) {
314
315 double barWidth = getBarWidth();
316 double height = getHeight(); // height of the plot area
317
318 double zoomFactor = fViewer.getZoomFactor();
319
320 int index = (int) ((x - fPadding - fVerticalAxisOffset - 1) / barWidth);
321
322 double barHeight = 0.0;
323 if (index >= 0 && index <= fScaledData.fLastBucket) {
324 barHeight = (zoomFactor * height * (fScaledData.fData[index] - fYMin) / (fYMax - fYMin));
325 }
326
327 long fMouseY = (long) (height - (y - fPadding - fPaddingTop));
328
329 // Verifying mouse pointer is over histogram bar
330 if (index >= 0 && fScaledData.fLastBucket >= index && fMouseY >= 0 && fMouseY < barHeight && fMouseY < height && x >= (fVerticalAxisOffset + fPadding)) {
331
332 fScaledData.fCurrentBucket = index;
333
334 long startTime = fScaledData.getBucketStartTime(index);
335 // negative values are possible if time values came into the model in decreasing order
336 if (startTime < 0) {
337 startTime = 0;
338 }
339 long endTime = fScaledData.getBucketEndTime(index);
340 int nbEvents = fScaledData.fData[index];
341
342 StringBuffer buffer = new StringBuffer();
343 buffer.append("Latency Range in s = ["); //$NON-NLS-1$
344 buffer.append(HistogramUtils.nanosecondsToString(startTime));
345 buffer.append(","); //$NON-NLS-1$
346 buffer.append(HistogramUtils.nanosecondsToString(endTime));
347 buffer.append("]\n"); //$NON-NLS-1$
348 buffer.append("Latency count = "); //$NON-NLS-1$
349 buffer.append(nbEvents);
350 return buffer.toString();
351 }
352 }
353 return ""; //$NON-NLS-1$
354 }
355 }
This page took 0.038983 seconds and 5 git commands to generate.