Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Kurtakov2020-02-13 08:39:52 +0000
committerAlexander Kurtakov2020-02-13 09:13:45 +0000
commit438cbdd2e3908d8799457165198a19dcc0bcc1f5 (patch)
treead07620f3001f73e2b1fc5e2926bc229d355e1db /profiling
parent65e7395bc5e100dc5529eee38ee700351cfd63e8 (diff)
downloadorg.eclipse.linuxtools-438cbdd2e3908d8799457165198a19dcc0bcc1f5.tar.gz
org.eclipse.linuxtools-438cbdd2e3908d8799457165198a19dcc0bcc1f5.tar.xz
org.eclipse.linuxtools-438cbdd2e3908d8799457165198a19dcc0bcc1f5.zip
Bug 560077 - Deprecate and remove dataviewers.chart and
dataviewers.piechart bundles Bring back the old org.swtchart api. Introduce the new eclipse swtchart as internal package so we can progress on it till removal. Change-Id: Ibe1adf8b0a35f0f78e208eff452f65b5afb1bc5b Signed-off-by: Alexander Kurtakov <akurtako@redhat.com> Reviewed-on: https://git.eclipse.org/r/157622 Tested-by: Linux Tools Bot <linuxtools-bot@eclipse.org>
Diffstat (limited to 'profiling')
-rwxr-xr-xprofiling/org.eclipse.linuxtools.dataviewers.charts/META-INF/MANIFEST.MF2
-rwxr-xr-xprofiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/actions/ChartAction.java2
-rwxr-xr-xprofiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/actions/SaveChartAction.java2
-rwxr-xr-xprofiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/provider/ChartFactory.java12
-rwxr-xr-xprofiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/internal/dataviewers/charts/dialogs/ChartDialog.java2
-rwxr-xr-xprofiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/internal/dataviewers/charts/view/ChartView.java2
-rw-r--r--profiling/org.eclipse.linuxtools.dataviewers.piechart/META-INF/MANIFEST.MF3
-rw-r--r--profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/dataviewers/piechart/PieChart.java14
-rw-r--r--profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/dataviewers/piechart/PieChartPaintListener.java10
-rw-r--r--profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/internal/dataviewers/piechart/PieChart.java167
-rw-r--r--profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/internal/dataviewers/piechart/PieChartPaintListener.java266
11 files changed, 458 insertions, 24 deletions
diff --git a/profiling/org.eclipse.linuxtools.dataviewers.charts/META-INF/MANIFEST.MF b/profiling/org.eclipse.linuxtools.dataviewers.charts/META-INF/MANIFEST.MF
index 17e08eba0c..d756273843 100755
--- a/profiling/org.eclipse.linuxtools.dataviewers.charts/META-INF/MANIFEST.MF
+++ b/profiling/org.eclipse.linuxtools.dataviewers.charts/META-INF/MANIFEST.MF
@@ -13,6 +13,6 @@ Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.linuxtools.dataviewers.charts.actions,
org.eclipse.linuxtools.dataviewers.charts.provider
Import-Package: org.eclipse.linuxtools.dataviewers.piechart,
- org.eclipse.swtchart
+ org.swtchart
Bundle-Localization: plugin
Automatic-Module-Name: org.eclipse.linuxtools.dataviewers.charts
diff --git a/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/actions/ChartAction.java b/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/actions/ChartAction.java
index 4d1f672c1c..0bc979ef80 100755
--- a/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/actions/ChartAction.java
+++ b/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/actions/ChartAction.java
@@ -19,7 +19,7 @@ import org.eclipse.linuxtools.internal.dataviewers.charts.Messages;
import org.eclipse.linuxtools.internal.dataviewers.charts.dialogs.ChartDialog;
import org.eclipse.linuxtools.internal.dataviewers.charts.view.ChartView;
import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swtchart.Chart;
+import org.swtchart.Chart;
/**
* An action that open a chart dialog from an <code>AbstractSTViewer</code>.
diff --git a/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/actions/SaveChartAction.java b/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/actions/SaveChartAction.java
index 89d69a66e3..3e9d85001f 100755
--- a/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/actions/SaveChartAction.java
+++ b/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/actions/SaveChartAction.java
@@ -36,7 +36,7 @@ import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
-import org.eclipse.swtchart.Chart;
+import org.swtchart.Chart;
/**
* An action to save any {@link Composite} (typically a {@link Chart}) as an image (jpeg/jpg, bmp, png).
diff --git a/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/provider/ChartFactory.java b/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/provider/ChartFactory.java
index 377d8b9ad3..e304cbf38d 100755
--- a/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/provider/ChartFactory.java
+++ b/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/dataviewers/charts/provider/ChartFactory.java
@@ -24,12 +24,12 @@ import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
-import org.eclipse.swtchart.Chart;
-import org.eclipse.swtchart.IAxis;
-import org.eclipse.swtchart.IBarSeries;
-import org.eclipse.swtchart.ISeries.SeriesType;
-import org.eclipse.swtchart.ITitle;
-import org.eclipse.swtchart.LineStyle;
+import org.swtchart.Chart;
+import org.swtchart.IAxis;
+import org.swtchart.IBarSeries;
+import org.swtchart.ISeries.SeriesType;
+import org.swtchart.ITitle;
+import org.swtchart.LineStyle;
/**
* A utility class that handles the charts creation (pie chart and bar chart)
diff --git a/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/internal/dataviewers/charts/dialogs/ChartDialog.java b/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/internal/dataviewers/charts/dialogs/ChartDialog.java
index b3dd31d93e..b344d3a97a 100755
--- a/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/internal/dataviewers/charts/dialogs/ChartDialog.java
+++ b/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/internal/dataviewers/charts/dialogs/ChartDialog.java
@@ -41,7 +41,7 @@ import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
-import org.eclipse.swtchart.Chart;
+import org.swtchart.Chart;
/**
* The dialog used to customize the chart before creating it.
diff --git a/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/internal/dataviewers/charts/view/ChartView.java b/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/internal/dataviewers/charts/view/ChartView.java
index 9bee28b104..6389c3fd81 100755
--- a/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/internal/dataviewers/charts/view/ChartView.java
+++ b/profiling/org.eclipse.linuxtools.dataviewers.charts/src/org/eclipse/linuxtools/internal/dataviewers/charts/view/ChartView.java
@@ -24,7 +24,7 @@ import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
-import org.eclipse.swtchart.Chart;
+import org.swtchart.Chart;
/**
* The chart view.
diff --git a/profiling/org.eclipse.linuxtools.dataviewers.piechart/META-INF/MANIFEST.MF b/profiling/org.eclipse.linuxtools.dataviewers.piechart/META-INF/MANIFEST.MF
index 890b92c74e..aa30e25073 100644
--- a/profiling/org.eclipse.linuxtools.dataviewers.piechart/META-INF/MANIFEST.MF
+++ b/profiling/org.eclipse.linuxtools.dataviewers.piechart/META-INF/MANIFEST.MF
@@ -6,8 +6,9 @@ Bundle-Version: 2.0.1.qualifier
Bundle-Vendor: %bundleProvider
Bundle-Localization: plugin
Require-Bundle: org.eclipse.ui,
+ org.swtchart,
org.eclipse.swtchart
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
-Export-Package: org.eclipse.linuxtools.dataviewers.piechart
+Export-Package: org.eclipse.linuxtools.dataviewers.piechart, org.eclipse.linuxtools.internal.dataviewers.piechart;x-internal:=true
Automatic-Module-Name: org.eclipse.linuxtools.dataviewers.piechart
diff --git a/profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/dataviewers/piechart/PieChart.java b/profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/dataviewers/piechart/PieChart.java
index df96a1ff6b..4ae832febb 100644
--- a/profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/dataviewers/piechart/PieChart.java
+++ b/profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/dataviewers/piechart/PieChart.java
@@ -20,11 +20,11 @@ import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
-import org.eclipse.swtchart.Chart;
-import org.eclipse.swtchart.IAxis;
-import org.eclipse.swtchart.IBarSeries;
-import org.eclipse.swtchart.ISeries;
-import org.eclipse.swtchart.ITitle;
+import org.swtchart.Chart;
+import org.swtchart.IAxis;
+import org.swtchart.IBarSeries;
+import org.swtchart.ISeries;
+import org.swtchart.ITitle;
public class PieChart extends Chart {
@@ -38,7 +38,7 @@ public class PieChart extends Chart {
for (IAxis axis : getAxisSet().getAxes()) {
axis.getTitle().setVisible(false);
}
- getPlotArea().getControl().setVisible(false);
+ getPlotArea().setVisible(false);
// Make the title draw after the pie-chart itself so we can modify the title
// to center over the pie-chart area
ITitle title = getTitle();
@@ -61,7 +61,7 @@ public class PieChart extends Chart {
@Override
public void addPaintListener(PaintListener listener) {
- if (!listener.getClass().getName().startsWith("org.eclipse.swtchart.internal.axis")) { //$NON-NLS-1$
+ if (!listener.getClass().getName().startsWith("org.swtchart.internal.axis")) { //$NON-NLS-1$
super.addPaintListener(listener);
}
}
diff --git a/profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/dataviewers/piechart/PieChartPaintListener.java b/profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/dataviewers/piechart/PieChartPaintListener.java
index 46e61a7019..b47f787eb3 100644
--- a/profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/dataviewers/piechart/PieChartPaintListener.java
+++ b/profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/dataviewers/piechart/PieChartPaintListener.java
@@ -22,10 +22,10 @@ import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
-import org.eclipse.swtchart.IBarSeries;
-import org.eclipse.swtchart.ISeries;
-import org.eclipse.swtchart.ITitle;
-import org.eclipse.swtchart.Range;
+import org.swtchart.IBarSeries;
+import org.swtchart.ISeries;
+import org.swtchart.ITitle;
+import org.swtchart.Range;
public class PieChartPaintListener implements PaintListener {
@@ -53,7 +53,7 @@ public class PieChartPaintListener implements PaintListener {
*/
public PieChartPaintListener(PieChart chart) {
this.chart = chart;
- this.plotArea = chart.getPlotArea().getControl();
+ this.plotArea = chart.getPlotArea();
}
@Override
diff --git a/profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/internal/dataviewers/piechart/PieChart.java b/profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/internal/dataviewers/piechart/PieChart.java
new file mode 100644
index 0000000000..abc0e46fe5
--- /dev/null
+++ b/profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/internal/dataviewers/piechart/PieChart.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - Renato Stoffalette Joao <rsjoao@br.ibm.com>
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.dataviewers.piechart;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.linuxtools.dataviewers.piechart.IColorsConstants;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swtchart.Chart;
+import org.eclipse.swtchart.IAxis;
+import org.eclipse.swtchart.IBarSeries;
+import org.eclipse.swtchart.ISeries;
+import org.eclipse.swtchart.ITitle;
+
+public class PieChart extends Chart {
+
+ protected List<RGB> colorList = new ArrayList<>();
+ private Color[] customColors = null;
+ private PieChartPaintListener pieChartPaintListener;
+
+ public PieChart(Composite parent, int style) {
+ super(parent, style);
+ // Hide all original axes and plot area
+ for (IAxis axis : getAxisSet().getAxes()) {
+ axis.getTitle().setVisible(false);
+ }
+ getPlotArea().getControl().setVisible(false);
+ // Make the title draw after the pie-chart itself so we can modify the title
+ // to center over the pie-chart area
+ ITitle title = getTitle();
+ // Underlying SWT Chart implementation changes from the title being a Control to just
+ // a PaintListener. In the Control class case, we can move it's location to
+ // center over a PieChart, but in the latter case, we need to alter the title
+ // with blanks in the PieChartPaintListener and have the title paint after it
+ // once the title has been altered.
+ if (title instanceof Control) {
+ addPaintListener(pieChartPaintListener = new PieChartPaintListener(this));
+ } else {
+ removePaintListener((PaintListener)title);
+ addPaintListener(pieChartPaintListener = new PieChartPaintListener(this));
+ addPaintListener((PaintListener)title);
+ }
+ IAxis xAxis = getAxisSet().getXAxis(0);
+ xAxis.enableCategory(true);
+ xAxis.setCategorySeries(new String[]{""}); //$NON-NLS-1$
+ }
+
+ @Override
+ public void addPaintListener(PaintListener listener) {
+ if (!listener.getClass().getName().startsWith("org.eclipse.swtchart.internal.axis")) { //$NON-NLS-1$
+ super.addPaintListener(listener);
+ }
+ }
+
+ /**
+ * Sets the custom colors to use.
+ * @param customColors The custom colors to use.
+ * @since 2.0
+ */
+ public void setCustomColors(Color[] customColors) {
+ this.customColors = customColors.clone();
+ }
+
+ /**
+ * Add data to this Pie Chart. We'll build one pie chart for each value in the array provided. The val matrix must
+ * have an array of an array of values. Ex. labels = {'a', 'b'} val = {{1,2,3}, {4,5,6}} This will create 3 pie
+ * charts. For the first one, 'a' will be 1 and 'b' will be 4. For the second chart 'a' will be 2 and 'b' will be 5.
+ * For the third 'a' will be 3 and 'b' will be 6.
+ * @param labels The titles of each series. (These are not the same as titles given to pies.)
+ * @param val New values.
+ */
+ public void addPieChartSeries(String labels[], double val[][]) {
+ setSeriesNames(val[0].length);
+ for (ISeries s : this.getSeriesSet().getSeries()) {
+ this.getSeriesSet().deleteSeries(s.getId());
+ }
+
+ int size = Math.min(labels.length, val.length);
+ for (int i = 0; i < size; i++) {
+ IBarSeries s = (IBarSeries) this.getSeriesSet().createSeries(ISeries.SeriesType.BAR, labels[i]);
+ double d[] = new double[val[i].length];
+ for (int j = 0; j < val[i].length; j++) {
+ d[j] = val[i][j];
+ }
+ s.setXSeries(d);
+ if (customColors != null) {
+ s.setBarColor(customColors[i % customColors.length]);
+ } else {
+ s.setBarColor(new Color(this.getDisplay(), sliceColor(i)));
+ }
+ }
+ }
+
+ /**
+ * Sets this chart's category names such that the number of names
+ * is equal to the number of pies. This method will only make changes
+ * to category series if they are not already properly set.
+ * @param numExpected The number of pies / the expected number of category names.
+ */
+ private void setSeriesNames(int numExpected) {
+ IAxis xAxis = getAxisSet().getXAxis(0);
+ if (xAxis.getCategorySeries().length != numExpected) {
+ String[] seriesNames = new String[numExpected];
+ for (int i = 0, n = Math.min(xAxis.getCategorySeries().length, numExpected); i < n; i++) {
+ seriesNames[i] = xAxis.getCategorySeries()[i];
+ }
+ for (int i = xAxis.getCategorySeries().length; i < numExpected; i++) {
+ seriesNames[i] = ""; //$NON-NLS-1$
+ }
+ xAxis.setCategorySeries(seriesNames);
+ }
+ }
+
+ protected RGB sliceColor(int i) {
+ if (colorList.size() > i) {
+ return colorList.get(i);
+ }
+
+ RGB next = IColorsConstants.COLORS[i % IColorsConstants.COLORS.length];
+ colorList.add(next);
+ return next;
+ }
+
+ /**
+ * Given a set of 2D pixel coordinates (typically those of a mouse cursor), return the
+ * index of the given pie's slice that those coordinates reside in.
+ * @param pieIndex The index of the pie to get the slice of.
+ * @param x The x-coordinate to test.
+ * @param y The y-coordinate to test.
+ * @return The slice that contains the point with coordinates (x,y).
+ * @since 2.0
+ */
+ public int getSliceIndexFromPosition(int pieIndex, int x, int y) {
+ return pieChartPaintListener.getSliceIndexFromPosition(pieIndex, x, y);
+ }
+
+ /**
+ * Given a pie and one of its slices, returns the size of the slice as a percentage of the pie.
+ * @param pieIndex The index of the pie to check.
+ * @param sliceIndex The slice of the pie to get the percentage of.
+ * @return The percentage of the entire pie taken up by the slice.
+ * @since 2.0
+ */
+ public double getSlicePercent(int pieIndex, int sliceIndex) {
+ double max = 0;
+ ISeries series[] = getSeriesSet().getSeries();
+ for (int i = 0; i < series.length; i++) {
+ max += series[i].getXSeries()[pieIndex];
+ }
+ return series[sliceIndex].getXSeries()[pieIndex] / max * 100;
+ }
+}
diff --git a/profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/internal/dataviewers/piechart/PieChartPaintListener.java b/profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/internal/dataviewers/piechart/PieChartPaintListener.java
new file mode 100644
index 0000000000..09e4ae6376
--- /dev/null
+++ b/profiling/org.eclipse.linuxtools.dataviewers.piechart/src/org/eclipse/linuxtools/internal/dataviewers/piechart/PieChartPaintListener.java
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - Renato Stoffalette Joao <rsjoao@br.ibm.com>
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.dataviewers.piechart;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swtchart.IBarSeries;
+import org.eclipse.swtchart.ISeries;
+import org.eclipse.swtchart.ITitle;
+import org.eclipse.swtchart.Range;
+
+public class PieChartPaintListener implements PaintListener {
+
+ private PieChart chart;
+ private Control plotArea;
+ private double[][] seriesValues;
+ private String[] seriesNames;
+ private static final int X_GAP = 10;
+
+ private static final Color WHITE = Display.getDefault().getSystemColor(SWT.COLOR_WHITE);
+ private static final Color BLACK = Display.getDefault().getSystemColor(SWT.COLOR_BLACK);
+ private static final String FONT = "Arial"; //$NON-NLS-1$
+
+ private Point[] pieCenters;
+ private int[][] pieSliceAngles;
+ private int pieWidth;
+
+ private String origTitleText;
+
+ /**
+ * Handles drawing and updating of a PieChart, with titles given to its legend and
+ * to each of its pies. Pies will be drawn in the given chart's plot area.
+ * @param chart The PieChart to draw and update.
+ * @since 2.0
+ */
+ public PieChartPaintListener(PieChart chart) {
+ this.chart = chart;
+ this.plotArea = chart.getPlotArea().getControl();
+ }
+
+ @Override
+ public void paintControl(PaintEvent e) {
+ GC gc = e.gc;
+ Rectangle bounds;
+ this.getPieSeriesArray();
+ pieCenters = new Point[seriesValues.length];
+ pieSliceAngles = new int[seriesValues.length][];
+ if (seriesValues.length == 0) {
+ bounds = gc.getClipping();
+ Font oldFont = gc.getFont();
+ Font font = new Font(Display.getDefault(), FONT, 15, SWT.BOLD);
+ gc.setForeground(BLACK);
+ gc.setFont(font);
+ String text = "No data"; //$NON-NLS-1$
+ Point textSize = e.gc.textExtent(text);
+ gc.drawText(text, (bounds.width - textSize.x) / 2, (bounds.height - textSize.y) / 2);
+ gc.setFont(oldFont);
+ font.dispose();
+ return;
+ }
+ bounds = plotArea.getBounds();
+ // Adjust the title so it centers in the plot area
+ if (origTitleText == null) {
+ origTitleText = chart.getTitle().getText();
+ }
+
+ // We want to center the title in the plot area rather than the entire view which includes
+ // the legend. To force this, we have two algorithms depending on what level of the
+ // underlying SWT Chart software we are using. If the title is an SWT Control, we simply
+ // set the title's location manually. If the title is just a PaintListener, we center it
+ // by adding a number of trailing spaces which we calculate.
+ if (chart.getTitle() instanceof Control) {
+ setTitleBounds(bounds);
+ } else {
+ adjustTitle(e);
+ }
+ int width = bounds.width / seriesValues.length;
+ int x = bounds.x;
+
+ if (chart.getLegend().isVisible()) {
+ Rectangle legendBounds = ((Control) chart.getLegend()).getBounds();
+ Font oldFont = gc.getFont();
+ Font font = new Font(Display.getDefault(), FONT, 10, SWT.BOLD);
+ gc.setForeground(BLACK);
+ gc.setFont(font);
+ String text = chart.getAxisSet().getXAxis(0).getTitle().getText();
+ Point textSize = e.gc.textExtent(text);
+ gc.drawText(text, legendBounds.x + (legendBounds.width - textSize.x) / 2, legendBounds.y - textSize.y);
+ gc.setFont(oldFont);
+ font.dispose();
+ }
+
+ pieWidth = Math.min(width - X_GAP, bounds.height);
+ for (int i = 0; i < seriesValues.length; i++) {
+ drawPieChart(e, i, new Rectangle(x, bounds.y, width, bounds.height));
+ x += width;
+ }
+ }
+
+ // For a title which is a Control, position it appropriately to center in the plot area.
+ private void setTitleBounds(Rectangle bounds) {
+ Control title = (Control) chart.getTitle();
+ Rectangle titleBounds = title.getBounds();
+ title.setLocation(new Point(bounds.x + (bounds.width - titleBounds.width) / 2, title.getLocation().y));
+ }
+
+ // Adjust the title with trailing blanks so it centers in the plot area
+ // rather than for the entire chart view which looks odd when not
+ // centered above the pie-charts themselves.
+ private void adjustTitle(PaintEvent pe) {
+ ITitle title = chart.getTitle();
+ Font font = title.getFont();
+ Font oldFont = pe.gc.getFont();
+ pe.gc.setFont(font);
+ Control legend = (Control)chart.getLegend();
+ Rectangle legendBounds = legend.getBounds();
+ int adjustment = legendBounds.width - 15;
+ Point blankSize = pe.gc.textExtent(" "); //$NON-NLS-1$
+ int numBlanks = ((adjustment / blankSize.x) >> 1) << 1;
+ String text = origTitleText;
+ for (int i = 0; i < numBlanks; ++i)
+ text += " "; //$NON-NLS-1$
+ pe.gc.setFont(oldFont);
+ title.setText(text);
+ }
+
+ private void drawPieChart(PaintEvent e, int chartnum, Rectangle bounds) {
+ double series[] = seriesValues[chartnum];
+ int nelemSeries = series.length;
+ double sumTotal = 0;
+
+ pieSliceAngles[chartnum] = new int[nelemSeries - 1]; // Don't need first angle; it's always 0
+ for (int i = 0; i < nelemSeries; i++) {
+ sumTotal += series[i];
+ }
+
+ GC gc = e.gc;
+ Font oldFont = gc.getFont();
+ gc.setLineWidth(1);
+
+ int pieX = bounds.x + (bounds.width - pieWidth) / 2;
+ int pieY = bounds.y + (bounds.height - pieWidth) / 2;
+ pieCenters[chartnum] = new Point(pieX + pieWidth / 2, pieY + pieWidth / 2);
+ if (sumTotal == 0) {
+ gc.drawOval(pieX, pieY, pieWidth, pieWidth);
+ } else {
+ double factor = 100 / sumTotal;
+ int sweepAngle = 0;
+ int incrementAngle = 0;
+ int initialAngle = 90;
+ for (int i = 0; i < nelemSeries; i++) {
+ // Stored angles increase in clockwise direction from 0 degrees at 12:00
+ if (i > 0) {
+ pieSliceAngles[chartnum][i - 1] = 90 - initialAngle;
+ }
+
+ gc.setBackground(((IBarSeries) chart.getSeriesSet().getSeries()[i]).getBarColor());
+
+ if (i == (nelemSeries - 1)) {
+ sweepAngle = 360 - incrementAngle;
+ } else {
+ double angle = series[i] * factor * 3.6;
+ sweepAngle = (int) Math.round(angle);
+ }
+ gc.fillArc(pieX, pieY, pieWidth, pieWidth, initialAngle, (-sweepAngle));
+ gc.drawArc(pieX, pieY, pieWidth, pieWidth, initialAngle, (-sweepAngle));
+ incrementAngle += sweepAngle;
+ initialAngle += (-sweepAngle);
+ }
+ gc.drawLine(pieCenters[chartnum].x, pieCenters[chartnum].y, pieCenters[chartnum].x, pieCenters[chartnum].y - pieWidth / 2);
+ }
+
+ Font font = new Font(Display.getDefault(), FONT, 12, SWT.BOLD);
+ gc.setForeground(BLACK);
+ gc.setBackground(WHITE);
+ gc.setFont(font);
+ String text = seriesNames[chartnum];
+ Point textSize = e.gc.textExtent(text);
+ gc.drawText(text, pieX + (pieWidth - textSize.x) / 2, pieY + pieWidth + textSize.y);
+ gc.setFont(oldFont);
+ font.dispose();
+ }
+
+ private void getPieSeriesArray() {
+ ISeries series[] = this.chart.getSeriesSet().getSeries();
+ if (series == null || series.length == 0) {
+ seriesValues = new double[0][0];
+ seriesNames = new String[0];
+ return;
+ }
+ String names[] = this.chart.getAxisSet().getXAxis(0).getCategorySeries();
+ Range range = chart.getAxisSet().getXAxis(0).getRange();
+ int itemRange = (int) range.upper - (int) range.lower + 1;
+ int itemOffset = (int) range.lower;
+ seriesValues = new double[itemRange][series.length];
+ seriesNames = new String[itemRange];
+
+ for (int i = 0; i < seriesValues.length; i++) {
+ seriesNames[i] = names[i + itemOffset];
+ for (int j = 0; j < seriesValues[i].length; j++) {
+ double d[] = series[j].getXSeries();
+ if (d != null && d.length > 0) {
+ seriesValues[i][j] = d[i + itemOffset];
+ } else {
+ seriesValues[i][j] = 0;
+ }
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * Given a set of 2D pixel coordinates (typically those of a mouse cursor), return the
+ * index of the given pie's slice that those coordinates reside in.
+ * @param chartnum The id of the chart.
+ * @param x The x-coordinate to test.
+ * @param y The y-coordinate to test.
+ * @return The slice that contains the point with coordinates (x,y).
+ * @since 2.0
+ */
+ public int getSliceIndexFromPosition(int chartnum, int x, int y) {
+ Range range = chart.getAxisSet().getXAxis(0).getRange();
+ chartnum -= (int) range.lower;
+ if (chartnum >= pieCenters.length || chartnum < 0) {
+ return -1;
+ }
+ // Only continue if the point is inside the pie circle
+ double rad = Math.sqrt(Math.pow(pieCenters[chartnum].x - x, 2) + Math.pow(pieCenters[chartnum].y - y, 2));
+ if (2 * rad > pieWidth) {
+ return -1;
+ }
+ // Angle is relative to 12:00 position, increases clockwise
+ double angle = Math.acos((pieCenters[chartnum].y - y) / rad) / Math.PI * 180.0;
+ if (x - pieCenters[chartnum].x < 0) {
+ angle = 360 - angle;
+ }
+ if (pieSliceAngles[chartnum].length == 0 || angle < pieSliceAngles[chartnum][0]) {
+ return 0;
+ }
+ for (int s = 0; s < pieSliceAngles[chartnum].length - 1; s++) {
+ if (pieSliceAngles[chartnum][s] <= angle && angle < pieSliceAngles[chartnum][s+1]) {
+ return s + 1;
+ }
+ }
+ return pieSliceAngles[chartnum].length;
+ }
+}

Back to the top