Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Mostly finished profiling ouput viewer.

  • Loading branch information...
commit f11626cebc96b4716f188711e943ea4aeed7d720 1 parent 5c688d9
@serras serras authored
View
4 net.sf.eclipsefp.haskell.profiler/META-INF/MANIFEST.MF
@@ -8,7 +8,9 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.team.core,
org.eclipse.core.resources,
- org.eclipse.ui.ide
+ org.eclipse.ui.ide,
+ org.eclipse.birt.chart.device.swt,
+ org.eclipse.birt.chart.ui
Eclipse-LazyStart: true
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-Vendor: %bundleVendor
View
206 net.sf.eclipsefp.haskell.profiler/src/net/sf/eclipsefp/haskell/profiler/internal/editors/ChartCanvas.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Qi Liang (IBM Corporation)
+ *
+ * Modified as explained in
+ * http://www.eclipse.org/forums/index.php/mv/msg/171310/557779/#msg_557779
+*******************************************************************************/
+package net.sf.eclipsefp.haskell.profiler.internal.editors;
+
+import org.eclipse.birt.chart.device.IDeviceRenderer;
+import org.eclipse.birt.chart.exception.ChartException;
+import org.eclipse.birt.chart.factory.GeneratedChartState;
+import org.eclipse.birt.chart.factory.Generator;
+import org.eclipse.birt.chart.model.Chart;
+import org.eclipse.birt.chart.model.attribute.Bounds;
+import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl;
+import org.eclipse.birt.chart.util.PluginSettings;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * The canvas to show chart.
+ *
+ * @author Qi Liang
+ */
+public class ChartCanvas extends Canvas {
+
+ /**
+ * The device render for rendering chart.
+ */
+ protected IDeviceRenderer render = null;
+
+ /**
+ * The chart instantce.
+ */
+ protected Chart chart = null;
+
+ /**
+ * The chart state.
+ */
+ protected GeneratedChartState state = null;
+
+ /**
+ * The image which caches the chart image to improve drawing performance.
+ */
+ private Image cachedImage = null;
+
+ /**
+ * Constructs one canvas containing chart.
+ *
+ * @param parent
+ * a composite control which will be the parent of the new
+ * instance (cannot be null)
+ * @param style
+ * the style of control to construct
+ */
+ public ChartCanvas(Composite parent, int style) {
+ super(parent, style);
+
+ // initialize the SWT rendering device
+ try {
+ PluginSettings ps = PluginSettings.instance();
+ render = ps.getDevice("dv.SWT");
+ } catch (ChartException ex) {
+ ex.printStackTrace();
+ }
+
+ addPaintListener(new PaintListener() {
+
+ public void paintControl(PaintEvent e) {
+
+ Composite co = (Composite) e.getSource();
+ final Rectangle rect = co.getClientArea();
+
+ render.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, e.gc);
+
+ if (cachedImage == null) {
+ buildChart();
+ drawToCachedImage(rect);
+ }
+ e.gc.drawImage(cachedImage,
+ 0,
+ 0,
+ cachedImage.getBounds().width,
+ cachedImage.getBounds().height,
+ 0,
+ 0,
+ rect.width,
+ rect.height);
+
+ }
+ });
+
+ addControlListener(new ControlAdapter() {
+
+ public void controlResized(ControlEvent e) {
+
+ render.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, new GC(ChartCanvas.this));
+ buildChart();
+ cachedImage = null;
+ }
+ });
+ }
+
+ /**
+ * Builds the chart state. This method should be call when data is changed.
+ */
+ private void buildChart() {
+ Point size = getSize();
+ Bounds bo = BoundsImpl.create(0, 0, size.x, size.y);
+ int resolution = render.getDisplayServer().getDpiResolution();
+ bo.scale(72d / resolution);
+ try {
+ Generator gr = Generator.instance();
+ state = gr.build(render.getDisplayServer(),
+ chart,
+ bo,
+ null,
+ null,
+ null);
+ } catch (ChartException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * Draws the chart onto the cached image in the area of the given
+ * <code>Rectangle</code>.
+ *
+ * @param size
+ * the area to draw
+ */
+ public void drawToCachedImage(Rectangle size) {
+ GC gc = null;
+ try {
+ if (cachedImage != null)
+ cachedImage.dispose();
+ cachedImage = new Image(Display.getCurrent(), size.width,
+ size.height);
+
+ gc = new GC(cachedImage);
+ render.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, gc);
+
+ Generator gr = Generator.instance();
+
+ gr.render(render, state);
+ } catch (ChartException ex) {
+ ex.printStackTrace();
+ } finally {
+ if (gc != null)
+ gc.dispose();
+ }
+ }
+
+ /**
+ * Returns the chart which is contained in this canvas.
+ *
+ * @return the chart contained in this canvas.
+ */
+ public Chart getChart() {
+ return chart;
+ }
+
+ /**
+ * Sets the chart into this canvas. Note: When the chart is set, the cached
+ * image will be dopped, but this method doesn't reset the flag
+ * <code>cachedImage</code>.
+ *
+ * @param chart
+ * the chart to set
+ */
+ public void setChart(Chart chart) {
+ if (cachedImage != null)
+ cachedImage.dispose();
+
+ cachedImage = null;
+ this.chart = chart;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.widgets.Widget#dispose()
+ */
+ public void dispose() {
+ if (cachedImage != null)
+ cachedImage.dispose();
+ super.dispose();
+ }
+
+}
View
103 ...sefp.haskell.profiler/src/net/sf/eclipsefp/haskell/profiler/internal/editors/ChartWithToolTipCanvas.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Qi Liang (IBM Corporation)
+*******************************************************************************/
+package net.sf.eclipsefp.haskell.profiler.internal.editors;
+
+import org.eclipse.birt.chart.device.IDeviceRenderer;
+import org.eclipse.birt.chart.device.IUpdateNotifier;
+import org.eclipse.birt.chart.model.Chart;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The canvas to draw chart with the tool tip to show the value.
+ *
+ * @author Qi Liang
+ */
+public class ChartWithToolTipCanvas extends ChartCanvas implements
+ IUpdateNotifier {
+
+ public ChartWithToolTipCanvas(Composite parent, int style) {
+ super(parent, style);
+ render.setProperty(IDeviceRenderer.UPDATE_NOTIFIER, this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.birt.chart.device.IUpdateNotifier#regenerateChart()
+ */
+ public void regenerateChart() {
+ redraw();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.birt.chart.device.IUpdateNotifier#repaintChart()
+ */
+ public void repaintChart() {
+ redraw();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.birt.chart.device.IUpdateNotifier#peerInstance()
+ */
+ public Object peerInstance() {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.birt.chart.device.IUpdateNotifier#getDesignTimeModel()
+ */
+ public Chart getDesignTimeModel() {
+ return chart;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.birt.chart.device.IUpdateNotifier#getRunTimeModel()
+ */
+ public Chart getRunTimeModel() {
+ return state.getChartModel();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.birt.chart.device.IUpdateNotifier#getContext(java.lang.Object)
+ */
+ public Object getContext(Object arg0) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.birt.chart.device.IUpdateNotifier#putContext(java.lang.Object,
+ * java.lang.Object)
+ */
+ public Object putContext(Object arg0, Object arg1) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.birt.chart.device.IUpdateNotifier#removeContext(java.lang.Object)
+ */
+ public Object removeContext(Object arg0) {
+ return null;
+ }
+}
View
49 ...sf.eclipsefp.haskell.profiler/src/net/sf/eclipsefp/haskell/profiler/internal/editors/ProfileNumbers.java
@@ -0,0 +1,49 @@
+package net.sf.eclipsefp.haskell.profiler.internal.editors;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.sf.eclipsefp.haskell.profiler.model.Job;
+import net.sf.eclipsefp.haskell.profiler.model.Sample;
+
+public class ProfileNumbers {
+
+ private LinkedHashMap<String, double[]> entries;
+ private double[] rest;
+
+ public ProfileNumbers(List<Map.Entry<String, BigInteger>> entriesApart, int noSamples) {
+ this.entries = new LinkedHashMap<String, double[]>();
+ for (Map.Entry<String, BigInteger> e : entriesApart) {
+ double[] values = new double[noSamples];
+ Arrays.fill(values, 0.0);
+ entries.put(e.getKey(), values);
+ }
+ this.rest = new double[noSamples];
+ Arrays.fill(this.rest, 0.0);
+ }
+
+ public void fillIn(Job job) {
+ int sampleNo = 0;
+ for (Sample s : job.getSamples()) {
+ for (Map.Entry<String, Long> e : s.getEntries()) {
+ if (entries.containsKey(e.getKey())) {
+ entries.get(e.getKey())[sampleNo] = e.getValue();
+ } else {
+ rest[sampleNo] += e.getValue();
+ }
+ }
+ sampleNo++;
+ }
+ }
+
+ public LinkedHashMap<String, double[]> getEntries() {
+ return entries;
+ }
+
+ public double[] getRest() {
+ return rest;
+ }
+}
View
138 ...sf.eclipsefp.haskell.profiler/src/net/sf/eclipsefp/haskell/profiler/internal/editors/ProfilerViewer.java
@@ -2,13 +2,35 @@
import java.io.InputStream;
import java.math.BigInteger;
+import java.util.Collections;
+import java.util.List;
import java.util.Map;
import net.sf.eclipsefp.haskell.profiler.model.Job;
+import net.sf.eclipsefp.haskell.profiler.model.Sample;
+import org.eclipse.birt.chart.model.Chart;
+import org.eclipse.birt.chart.model.ChartWithAxes;
+import org.eclipse.birt.chart.model.attribute.LegendItemType;
+import org.eclipse.birt.chart.model.attribute.TickStyle;
+import org.eclipse.birt.chart.model.component.Axis;
+import org.eclipse.birt.chart.model.component.Series;
+import org.eclipse.birt.chart.model.component.impl.SeriesImpl;
+import org.eclipse.birt.chart.model.data.NumberDataSet;
+import org.eclipse.birt.chart.model.data.SeriesDefinition;
+import org.eclipse.birt.chart.model.data.impl.NumberDataSetImpl;
+import org.eclipse.birt.chart.model.data.impl.SeriesDefinitionImpl;
+import org.eclipse.birt.chart.model.impl.ChartWithAxesImpl;
+import org.eclipse.birt.chart.model.type.AreaSeries;
+import org.eclipse.birt.chart.model.type.impl.AreaSeriesImpl;
+import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Status;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
@@ -18,32 +40,126 @@
public class ProfilerViewer extends EditorPart {
Job job = null;
-
+ double[] samplePoints;
+ List<Map.Entry<String, BigInteger>> entries;
+ ChartCanvas canvas;
+
public ProfilerViewer() {
super();
}
-
+
@Override
public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+ setSite(site);
+ setInput(input);
+
try {
- IFileEditorInput fInput = (IFileEditorInput)input;
- InputStream contents = fInput.getFile().getContents();
+ IFileEditorInput fInput = (IFileEditorInput) input;
+ IFile inputFile = fInput.getFile();
+ setPartName(inputFile.getName());
+ InputStream contents = inputFile.getContents();
job = Job.parse(contents);
contents.close();
- for(Map.Entry<String, BigInteger> entry : job.sortEntriesByTotal()) {
- System.out.print(entry.getKey());
- System.out.print(": ");
- System.out.println(entry.getValue().toString());
+ // Sort entries
+ entries = job.sortEntriesByTotal();
+ // Get sample points
+ samplePoints = new double[job.getSamplesAndTimes().size()];
+ int i = 0;
+ for (Sample s : job.getSamples()) {
+ samplePoints[i] = s.getTime();
+ i++;
}
} catch (Exception e) {
throw new PartInitException(Status.CANCEL_STATUS);
}
}
-
+
@Override
public void createPartControl(Composite parent) {
- // TODO Auto-generated method stub
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ parent.setLayout(layout);
+
+ Label l = new Label(parent, SWT.NONE);
+ l.setText("Placeholder");
+ GridData lGridData = new GridData(GridData.FILL_HORIZONTAL);
+ l.setLayoutData(lGridData);
+
+ Chart chart = createChart(15);
+ canvas = new ChartCanvas(parent, SWT.NONE);
+ canvas.setChart(chart);
+ GridData cGridData = new GridData(GridData.FILL_BOTH);
+ canvas.setLayoutData(cGridData);
+ }
+
+ private Chart createChart(int numberApart) {
+ int n = entries.size() < numberApart ? entries.size() : numberApart;
+ List<Map.Entry<String, BigInteger>> entriesApart = entries.subList(0, n);
+
+ Chart chart = ChartWithAxesImpl.create();
+ // Title
+ chart.getTitle().getLabel().getCaption().setValue(job.getName());
+ // chart.getTitle().getLabel().getCaption().getFont().setSize(14);
+ // chart.getTitle().getLabel().getCaption().getFont().setName("Arial");
+ // Legend
+ chart.getLegend().setItemType(LegendItemType.SERIES_LITERAL);
+ chart.getLegend().setVisible(true);
+ // X-Axis -> time
+ Axis xAxis = ((ChartWithAxes) chart).getPrimaryBaseAxes()[0];
+ // xAxis.setType(AxisType.LINEAR_LITERAL);
+ xAxis.getMajorGrid().setTickStyle(TickStyle.BELOW_LITERAL);
+ xAxis.getTitle().setVisible(true);
+ xAxis.getTitle().getCaption().setValue(job.getSampleUnit());
+ xAxis.getLabel().setVisible(true);
+ // X-Axis data
+ NumberDataSet xDataSet = NumberDataSetImpl.create(samplePoints);
+ Series xCategory = SeriesImpl.create();
+ xCategory.setDataSet(xDataSet);
+ SeriesDefinition sdX = SeriesDefinitionImpl.create();
+ sdX.getSeriesPalette().shift(0);
+ xAxis.getSeriesDefinitions().add(sdX);
+ sdX.getSeries().add(xCategory);
+ // Y-Axis -> memory
+ Axis yAxis = ((ChartWithAxes) chart).getPrimaryOrthogonalAxis(xAxis);
+ yAxis.getMajorGrid().setTickStyle(TickStyle.LEFT_LITERAL);
+ yAxis.getMajorGrid().getLineAttributes().setVisible(true);
+ yAxis.getMinorGrid().getLineAttributes().setVisible(true);
+ yAxis.setPercent(false);
+ yAxis.getTitle().getCaption().setValue(job.getValueUnit());
+ yAxis.getTitle().setVisible(true);
+ yAxis.getTitle().getCaption().getFont().setRotation(90);
+ yAxis.getLabel().setVisible(true);
+ // Y-Axis data
+ SeriesDefinition sdY = SeriesDefinitionImpl.create();
+ sdY.getSeriesPalette().shift(1);
+ yAxis.getSeriesDefinitions().add(sdY);
+ // Get the numbers
+ ProfileNumbers numbers = new ProfileNumbers(entriesApart, samplePoints.length);
+ numbers.fillIn(job);
+ // Add (rest) elements
+ NumberDataSet restDataSet = NumberDataSetImpl.create(numbers.getRest());
+ AreaSeries restSeries = (AreaSeries) AreaSeriesImpl.create();
+ restSeries.setSeriesIdentifier("(rest)");
+ restSeries.setDataSet(restDataSet);
+ restSeries.getLineAttributes().setVisible(false);
+ restSeries.getLabel().setVisible(false);
+ restSeries.setStacked(true);
+ sdY.getSeries().add(restSeries);
+ // Add apart elements, in reverse order
+ Collections.reverse(entriesApart);
+ for (Map.Entry<String, BigInteger> entry : entriesApart) {
+ double[] entryNumbers = numbers.getEntries().get(entry.getKey());
+ NumberDataSet entryDataSet = NumberDataSetImpl.create(entryNumbers);
+ AreaSeries entrySeries = (AreaSeries) AreaSeriesImpl.create();
+ entrySeries.setSeriesIdentifier(entry.getKey());
+ entrySeries.setDataSet(entryDataSet);
+ entrySeries.getLineAttributes().setVisible(false);
+ entrySeries.getLabel().setVisible(false);
+ entrySeries.setStacked(true);
+ sdY.getSeries().add(entrySeries);
+ }
+ return chart;
}
@Override
@@ -71,6 +187,4 @@ public boolean isSaveAsAllowed() {
return false;
}
-
-
}
Please sign in to comment.
Something went wrong with that request. Please try again.