Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

implementation classes: with and without birt

  • Loading branch information...
commit a9d0e2361aa5a29d7fb2e28496270d91b784c0e4 1 parent 0a54ee5
@JPMoresmau authored
View
271 ...psefp.haskell.profiler/src/net/sf/eclipsefp/haskell/profiler/internal/editors/ProfileViewerBirtImpl.java
@@ -0,0 +1,271 @@
+/**
+ * (c) 2011, Alejandro Serrano
+ * Released under the terms of the EPL.
+ */
+package net.sf.eclipsefp.haskell.profiler.internal.editors;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.math.BigInteger;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+
+import net.sf.eclipsefp.haskell.profiler.internal.util.UITexts;
+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.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Scale;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.dialogs.ContainerGenerator;
+import org.eclipse.ui.dialogs.SaveAsDialog;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.ide.FileStoreEditorInput;
+
+/**
+ * Viewer for profiling output generated by GHC.
+ * Uses the BIRT Charting engine.
+ * @author Alejandro Serrano
+ */
+public abstract class ProfileViewerBirtImpl extends ProfileViewerImpl{
+ static int INITIAL_NUMBER_OF_ITEMS = 15;
+
+ String fileContents;
+ Job job = null;
+ double[] samplePoints;
+ List<Map.Entry<String, BigInteger>> entries;
+
+ private FormToolkit toolkit;
+ private ScrolledForm form;
+ private Scale slider;
+ private ChartCanvas canvas;
+
+
+ @Override
+ public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+
+ try {
+ InputStream contents;
+ if (input instanceof FileStoreEditorInput) {
+ FileStoreEditorInput fInput = (FileStoreEditorInput) input;
+ URI path = fInput.getURI();
+ contents = new FileInputStream(new File(path));
+ setPartName(fInput.getName());
+ } else {
+ IFileEditorInput fInput = (IFileEditorInput) input;
+ IFile inputFile = fInput.getFile();
+ setPartName(inputFile.getName());
+ contents = inputFile.getContents();
+ }
+ fileContents = new Scanner(contents).useDelimiter("\\Z").next();
+ contents.close();
+ job = Job.parse(new StringReader(fileContents));
+ // 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) {
+
+ toolkit = new FormToolkit(parent.getDisplay());
+ form = toolkit.createScrolledForm(parent);
+ form.setText(UITexts.bind(UITexts.graph_title, new Object[] { job.getName(), job.getDate() }));
+
+ int n = entries.size() < INITIAL_NUMBER_OF_ITEMS ? entries.size() : INITIAL_NUMBER_OF_ITEMS;
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ form.getBody().setLayout(layout);
+
+ Chart chart = createChart(n);
+ canvas = new ChartCanvas(form.getBody(), SWT.NONE);
+ canvas.setLayoutData(new GridData(GridData.FILL_BOTH));
+ canvas.setChart(chart);
+
+ Section section = toolkit.createSection(form.getBody(),
+ Section.TITLE_BAR | Section.TWISTIE);
+ section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ section.setText(UITexts.graph_options);
+
+ Composite sectionClient = toolkit.createComposite(section);
+ GridLayout hLayout = new GridLayout();
+ hLayout.numColumns = 2;
+ sectionClient.setLayout(hLayout);
+ section.setClient(sectionClient);
+
+ toolkit.createLabel(sectionClient, UITexts.graph_ungroupElements);
+ slider = new Scale(sectionClient, SWT.NONE);
+ slider.setMinimum(0);
+ slider.setMaximum(entries.size());
+ slider.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ slider.setSelection(n);
+ slider.addSelectionListener(new SelectionListener() {
+
+ public void widgetSelected(SelectionEvent e) {
+ Chart chart = createChart(slider.getSelection());
+ canvas.setChart(chart);
+ canvas.redraw();
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ Chart chart = createChart(slider.getSelection());
+ canvas.setChart(chart);
+ canvas.redraw();
+ }
+ });
+
+ toolkit.paintBordersFor(parent);
+ }
+
+ private Chart createChart(int numberApart) {
+ int n = entries.size() < numberApart ? entries.size() : numberApart;
+ List<Map.Entry<String, BigInteger>> entriesApart = new ArrayList<Map.Entry<String, BigInteger>>(
+ entries.subList(0, n));
+
+ Chart chart = ChartWithAxesImpl.create();
+ // Title
+ // chart.getTitle().getLabel().getCaption().setValue(job.getName());
+ chart.getTitle().setVisible(false);
+ // 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(UITexts.graph_restOfTrace);
+ 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
+ public void doSaveAs(Shell shell,String partName) {
+ SaveAsDialog dialog = new SaveAsDialog(shell);
+ dialog.setOriginalName(partName);
+ if (dialog.open() == Window.OK) {
+ try {
+ IPath path = dialog.getResult();
+ IPath folder = path.uptoSegment(path.segmentCount() - 1);
+ ContainerGenerator gen = new ContainerGenerator(folder);
+ IContainer con = gen.generateContainer(null);
+ IFile file = con.getFile(Path.fromPortableString(path.lastSegment()));
+ byte[] bytes = fileContents.getBytes();
+ InputStream source = new ByteArrayInputStream(bytes);
+ if (!file.exists()) {
+ file.create(source, IResource.NONE, null);
+ } else {
+ file.setContents(source, IResource.NONE, null);
+ }
+ source.close();
+ setPartName(path.lastSegment());
+ } catch (Exception e) {
+ // Do nothing
+ }
+ }
+ }
+
+ @Override
+ public boolean isSaveAsAllowed() {
+ return true;
+ }
+}
View
39 ...eclipsefp.haskell.profiler/src/net/sf/eclipsefp/haskell/profiler/internal/editors/ProfileViewerImpl.java
@@ -0,0 +1,39 @@
+package net.sf.eclipsefp.haskell.profiler.internal.editors;
+
+import net.sf.eclipsefp.haskell.profiler.internal.util.UITexts;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.PartInitException;
+
+/**
+ * empty implementation of profile viewer, in case Birt is not available
+ * @author jean-philippem
+ *
+ */
+public abstract class ProfileViewerImpl {
+
+
+ public abstract void setPartName(String name);
+
+ public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+ // NOOP
+ }
+
+ public void createPartControl(Composite parent) {
+ Label l=new Label(parent,SWT.NONE);
+ l.setText(UITexts.graph_requires_birt);
+ }
+
+ public boolean isSaveAsAllowed() {
+ return false;
+ }
+
+ public void doSaveAs(Shell shell,String partName) {
+ // noop
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.