| package org.eclipse.stem.util.analysis.views; |
| |
| /******************************************************************************* |
| * Copyright (c) 2007 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.birt.chart.device.IDeviceRenderer; |
| import org.eclipse.birt.chart.exception.ChartException; |
| import org.eclipse.birt.chart.factory.Generator; |
| import org.eclipse.birt.chart.model.Chart; |
| import org.eclipse.birt.chart.model.ChartWithAxes; |
| import org.eclipse.birt.chart.model.attribute.Anchor; |
| import org.eclipse.birt.chart.model.attribute.AxisType; |
| import org.eclipse.birt.chart.model.attribute.Bounds; |
| import org.eclipse.birt.chart.model.attribute.ColorDefinition; |
| import org.eclipse.birt.chart.model.attribute.IntersectionType; |
| import org.eclipse.birt.chart.model.attribute.LineAttributes; |
| import org.eclipse.birt.chart.model.attribute.LineStyle; |
| import org.eclipse.birt.chart.model.attribute.Marker; |
| import org.eclipse.birt.chart.model.attribute.MarkerType; |
| import org.eclipse.birt.chart.model.attribute.Position; |
| import org.eclipse.birt.chart.model.attribute.TickStyle; |
| import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl; |
| import org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionImpl; |
| import org.eclipse.birt.chart.model.attribute.impl.MarkerImpl; |
| 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.NumberDataElementImpl; |
| 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.layout.Legend; |
| import org.eclipse.birt.chart.model.layout.Plot; |
| import org.eclipse.birt.chart.model.type.ScatterSeries; |
| import org.eclipse.birt.chart.model.type.impl.ScatterSeriesImpl; |
| import org.eclipse.birt.chart.util.PluginSettings; |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.action.MenuManager; |
| import org.eclipse.jface.action.Separator; |
| import org.eclipse.stem.ui.preferences.VisualizationPreferencePage; |
| import org.eclipse.stem.util.analysis.Activator; |
| 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.GC; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.widgets.Canvas; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Menu; |
| import org.eclipse.swt.widgets.Widget; |
| import org.eclipse.ui.IWorkbenchActionConstants; |
| |
| /** |
| * TimeSeriesCanvas is a subclass of {@link Canvas} suitable for chart drawings. |
| */ |
| public class XYSeriesCanvas extends Canvas { |
| |
| protected IDeviceRenderer idr = null; |
| |
| /** |
| * This is the {@link Chart} that plots the relative values. |
| */ |
| protected Chart cm = null; |
| |
| /** |
| * The provider of relative values. |
| */ |
| //private RelativeValueHistoryProvider rvhp; |
| |
| private AnalysisControl control = null; |
| |
| /** |
| * the index of this Chart |
| */ |
| protected int chartIndex = 0; |
| |
| |
| private static final String DEFAULT_KEY_PREFIX = "XY"; |
| |
| private static String defaultKey = DEFAULT_KEY_PREFIX; |
| |
| /** |
| * some extra colors |
| */ |
| protected static final int[][] colorDefault = { |
| {0, 0, 255}, //Blue |
| {255, 0, 0}, //Red |
| {0, 255, 0}, //Green |
| {255, 255, 0}, //Yellow |
| {0, 0, 0}, //Black |
| {127, 127, 127}, //Grey |
| {255, 255, 255}, //Cyan |
| {255, 197, 41} //Orange |
| }; |
| |
| /** |
| * used to index the line series so we can step through default colors |
| * when a user custom color is not yet assigned |
| */ |
| private int seriesCount = 0; |
| |
| |
| /** |
| * A context menu for this view |
| */ |
| Menu popUpMenu = null; |
| |
| /** |
| * set y axis to a linear scale |
| */ |
| private LinearScaleAction linearTimeAction; |
| /** |
| * set y axis to a log scale |
| */ |
| private LogScaleAction logTimeAction; |
| protected boolean useLinearTimeScale = true; |
| |
| |
| /** |
| * show the legend (true by default) |
| */ |
| private LegendViewAction viewLegend; |
| |
| /** |
| * hide the legend |
| */ |
| private LegendHideAction hideLegend; |
| protected boolean showLegend = true; |
| |
| protected Legend legend = null; |
| |
| |
| /** |
| * this is a map of the DataXYSeries object (keyed by property name) |
| */ |
| protected final Map<String,DataXYSeries> dataSeriesMap = new HashMap<String,DataXYSeries>(); |
| |
| /** |
| * Chart generator instance (reference to a singleton) |
| */ |
| Generator gr; |
| |
| Axis yAxisPrimary; |
| Axis xAxisPrimary; |
| /** |
| * the maxY value for scaling |
| */ |
| double maxY = Double.MIN_VALUE; |
| |
| /** |
| * the maxY value for scaling |
| */ |
| double maxX = Double.MIN_VALUE; |
| |
| /** |
| * the minY value for scaling |
| */ |
| private double minY = Double.MAX_VALUE; |
| |
| /** |
| * the minX value for scaling |
| */ |
| private double minX = Double.MAX_VALUE; |
| |
| |
| /** |
| * Label for line series LEGEND |
| */ |
| public String Ordinate_LEGEND = "Y"; |
| |
| /** |
| * Label for line series Y axis label |
| **/ |
| public String Ordinate_AXIS = "Y"; |
| |
| /** |
| * customizable color definitions |
| */ |
| protected ColorDefinition foreGround = ColorDefinitionImpl.WHITE(); |
| private ColorDefinition backgroundGround = ColorDefinitionImpl.BLACK(); |
| private ColorDefinition frameColor = ColorDefinitionImpl.create(180, 180, 200); |
| |
| Image imgChart = null; |
| |
| /** |
| * This Constructor is used when we want to place the time series in a container |
| * which is a sub component of the actual AnalysisControl |
| * @param analysisControl |
| * |
| * @param parent the SWT parent of the {@link Widget} |
| * @param ordinateString |
| * @param yAxisLabel |
| * @param foreground |
| * @param background |
| * @param framecolor |
| * @param chartIndex the index of this chart (0 if only one) |
| * |
| */ |
| public XYSeriesCanvas(final AnalysisControl analysisControl, final Composite parent, |
| final String ordinateString, |
| final String yAxisLabel, |
| ColorDefinition foreground, |
| ColorDefinition background, |
| ColorDefinition framecolor, |
| int chartIndex) { |
| super(parent, SWT.DOUBLE_BUFFERED | SWT.BORDER); |
| Ordinate_LEGEND = ordinateString; |
| Ordinate_AXIS = yAxisLabel; |
| defaultKey = DEFAULT_KEY_PREFIX+chartIndex; |
| foreGround = foreground; |
| backgroundGround = background; |
| frameColor = framecolor; |
| this.chartIndex = chartIndex; |
| |
| gr = Generator.instance(); |
| |
| try { |
| idr = PluginSettings.instance().getDevice("dv.SWT"); //$NON-NLS-1$ |
| } catch (final ChartException pex) { |
| Activator.logError(Messages.getString("COMMON.ERRORINIT"), pex); //$NON-NLS-1$ |
| return; |
| } |
| |
| control = analysisControl; |
| |
| |
| cm = createSimpleLineChart(dataSeriesMap, Messages.getString("CC.title")); //$NON-NLS-1$ |
| |
| resetData(); |
| addPaintListener(new PaintListener() { |
| public void paintControl(final PaintEvent pe) { |
| |
| final Composite source = (Composite) pe.getSource(); |
| final org.eclipse.swt.graphics.Rectangle d = source |
| .getClientArea(); |
| |
| if(imgChart != null) imgChart.dispose(); |
| imgChart = new Image(source.getDisplay(), d); |
| idr.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, new GC( |
| imgChart)); |
| final Bounds bounds = BoundsImpl.create(d.x, d.y, d.width, |
| d.height); |
| bounds.scale(72d / idr.getDisplayServer().getDpiResolution()); |
| // BOUNDS MUST BE SPECIFIED IN POINTS |
| |
| try { |
| gr.render(idr, gr.build(idr.getDisplayServer(), cm, bounds, |
| null, null, null)); |
| pe.gc.drawImage(imgChart, d.x, d.y); |
| } catch (final ChartException ce) { |
| Activator.logError("Problem rendering chart", ce); //$NON-NLS-1$ |
| } |
| } // paintControl |
| } // PaintListener |
| ); |
| |
| //Create a context menu for the canvas |
| createContextMenu(this); |
| |
| |
| } // TimeSeriesCanvas |
| /** |
| * Constructor. |
| * |
| * @param parent the SWT parent of the {@link Widget} |
| * @param ordinateString |
| * @param yAxisLabel |
| * @param foreground |
| * @param background |
| * @param framecolor |
| * @param chartIndex the index of this chart (0 if only one) |
| * |
| */ |
| public XYSeriesCanvas(final Composite parent, |
| final String ordinateString, |
| final String yAxisLabel, |
| ColorDefinition foreground, |
| ColorDefinition background, |
| ColorDefinition framecolor, |
| int chartIndex) { |
| super(parent, SWT.DOUBLE_BUFFERED | SWT.BORDER); |
| Ordinate_LEGEND = ordinateString; |
| Ordinate_AXIS = yAxisLabel; |
| defaultKey = DEFAULT_KEY_PREFIX+chartIndex; |
| foreGround = foreground; |
| backgroundGround = background; |
| frameColor = framecolor; |
| this.chartIndex = chartIndex; |
| |
| gr = Generator.instance(); |
| |
| try { |
| idr = PluginSettings.instance().getDevice("dv.SWT"); //$NON-NLS-1$ |
| } catch (final ChartException pex) { |
| Activator.logError(Messages.getString("COMMON.ERRORINIT"), pex); //$NON-NLS-1$ |
| return; |
| } |
| |
| control = (AnalysisControl) parent; |
| |
| |
| cm = createSimpleLineChart(dataSeriesMap, Messages |
| .getString("CC.title")); //$NON-NLS-1$ |
| |
| resetData(); |
| addPaintListener(new PaintListener() { |
| public void paintControl(final PaintEvent pe) { |
| |
| final Composite source = (Composite) pe.getSource(); |
| final org.eclipse.swt.graphics.Rectangle d = source |
| .getClientArea(); |
| |
| if(imgChart != null) imgChart.dispose(); |
| imgChart = new Image(source.getDisplay(), d); |
| idr.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, new GC( |
| imgChart)); |
| final Bounds bounds = BoundsImpl.create(d.x, d.y, d.width, |
| d.height); |
| bounds.scale(72d / idr.getDisplayServer().getDpiResolution()); |
| // BOUNDS MUST BE SPECIFIED IN POINTS |
| |
| try { |
| gr.render(idr, gr.build(idr.getDisplayServer(), cm, bounds, |
| null, null, null)); |
| pe.gc.drawImage(imgChart, d.x, d.y); |
| } catch (final ChartException ce) { |
| Activator.logError(Messages.getString("COMMON.ERRORINIT"), ce); //$NON-NLS-1$ |
| } |
| } // paintControl |
| } // PaintListener |
| ); |
| |
| //Create a context menu for the canvas |
| createContextMenu(this); |
| |
| |
| } // TimeSeriesCanvas |
| |
| |
| |
| /** |
| * The method which gets the {@link XYSeriesCanvas}' reports list, and |
| * draws it on the {@link XYSeriesCanvas}. |
| * |
| */ |
| public void draw() { |
| |
| |
| |
| |
| resetData(); |
| |
| maxY = -1.0; |
| minY = 0.0; |
| maxX = -1.0; |
| minX = 0.0; |
| double adjustedMaxY = 0.0; |
| double adjustedMaxX = 0.0; |
| |
| // get the x,y data (i=0) |
| // and the x, fitY data (i=1) |
| for(int i = 0; i <= 1; i ++) { |
| |
| // one XY data set per chart |
| //for (int i = 0; i < maxLines; i ++) { |
| String property = "XY"+chartIndex; |
| if(i==1) property = "FIT"+chartIndex; |
| |
| if(!dataSeriesMap.containsKey(property)) { |
| // new property |
| DataXYSeries series = new DataXYSeries(property); |
| seriesCount ++; |
| dataSeriesMap.put(property, series); |
| } |
| DataXYSeries series = dataSeriesMap.get(property); |
| if(series.isVisible()) { |
| series.show(); |
| } else { |
| series.hide(); |
| } |
| |
| // Get the values for the property to be plotted |
| int maxPoints = 0; |
| |
| final double[] doubleValuesX = control.getValues(chartIndex,(2*i)+2); |
| final double[] doubleValuesY = control.getValues(chartIndex,(2*i)+3); |
| |
| // update the min max scales |
| for (int j = 0; j < doubleValuesX.length; j++) { |
| if(doubleValuesY[j] <= minY) { |
| minY = doubleValuesY[j]; |
| minY = Math.round(minY); |
| } |
| if(doubleValuesX[j] <= minX) { |
| minX = doubleValuesX[j]; |
| minX = Math.round(minX); |
| } |
| |
| if(doubleValuesY[j] >= maxY) { |
| maxY = doubleValuesY[j]; |
| double log = Math.floor(Math.log10(maxY)); |
| adjustedMaxY = (Math.ceil(maxY/Math.pow(10, log)))*Math.pow(10, log); |
| // if(adjustedMaxY <= 1.0) adjustedMaxY = 1.0; |
| }// maxY |
| if(doubleValuesX[j] >= maxX) { |
| maxX = 1.02*doubleValuesX[j]; |
| double log = Math.floor(Math.log10(maxX)); |
| adjustedMaxX = (Math.ceil(maxX/Math.pow(10, log)))*Math.pow(10, log); |
| //if(adjustedMaxX <= 1.0) adjustedMaxX = 1.0; |
| }// maxX |
| }// for all points |
| |
| |
| |
| //System.out.println("adjustedMaxX = "+adjustedMaxX); |
| xAxisPrimary.getScale().setMin(NumberDataElementImpl.create(0.0)); |
| xAxisPrimary.getScale().setMax(NumberDataElementImpl.create(adjustedMaxX)); |
| double stepX = adjustedMaxX / 10.0; |
| //System.out.println("step = "+stepX); |
| xAxisPrimary.getScale().setStep(stepX); |
| xAxisPrimary.setType(AxisType.LINEAR_LITERAL); |
| |
| |
| yAxisPrimary.getScale().setMin(NumberDataElementImpl.create(minY)); |
| yAxisPrimary.getScale().setMax(NumberDataElementImpl.create(adjustedMaxY)); |
| double stepY = adjustedMaxY / 10.0; |
| yAxisPrimary.getScale().setStep(stepY); |
| yAxisPrimary.setType(AxisType.LINEAR_LITERAL); |
| |
| // Any values? |
| if (doubleValuesX.length > 0) { |
| if (maxPoints < doubleValuesX.length) { |
| maxPoints = doubleValuesX.length; |
| } |
| |
| for (int cycleNumber = 0; cycleNumber < doubleValuesX.length; cycleNumber++) { |
| Double valueX = new Double(doubleValuesX[cycleNumber]); |
| Double valueY = new Double(doubleValuesY[cycleNumber]); |
| series.addValue(valueX,valueY); |
| } // for cycleNumber |
| |
| } else { |
| //resetData(); |
| } |
| |
| }// xy data and fit |
| |
| |
| if (!this.isDisposed()) { |
| redraw(); |
| } |
| |
| |
| |
| return; |
| } // paintControl |
| |
| /** |
| * @param dataXYSeriesMap |
| * the {@link List} that will contain the relative values |
| * (0.0-1.0) to plot |
| * @param seriesIdentifier |
| * the title of the chart |
| * @return a <code>Chart</code> |
| */ |
| public final Chart createSimpleLineChart( |
| final Map<String, DataXYSeries> dataXYSeriesMap, final String seriesIdentifier) { |
| |
| final ChartWithAxes retValue = ChartWithAxesImpl.create(); |
| |
| |
| // Plot |
| retValue.getBlock().setBackground(frameColor); |
| final Plot p = retValue.getPlot(); |
| p.getClientArea().setBackground(backgroundGround); |
| |
| // Title |
| // cwaLine.getTitle( ).getLabel( ).getCaption( ).setValue( "Line Chart" |
| // );//$NON-NLS-1$ |
| retValue.getTitle().setVisible(false); |
| |
| // Legend |
| legend = retValue.getLegend(); |
| final LineAttributes lia = legend.getOutline(); |
| legend.getText().getFont().setSize(8); |
| lia.setStyle(LineStyle.SOLID_LITERAL); |
| legend.getInsets().set(10, 5, 0, 0); |
| legend.getOutline().setVisible(false); |
| legend.setAnchor(Anchor.NORTH_LITERAL); |
| legend.setPosition(Position.BELOW_LITERAL); |
| legend.getText().setColor(foreGround); |
| legend.getOutline().setColor(foreGround); |
| |
| // cwaLine.getLegend( ).getText().getFont().setSize(16);; |
| // cwaLine.getLegend( ).setVisible( true ); |
| |
| // ///////// |
| // X-Axis |
| xAxisPrimary = retValue.getPrimaryBaseAxes()[0]; |
| xAxisPrimary.setType(AxisType.TEXT_LITERAL); |
| xAxisPrimary.getMajorGrid().setTickStyle(TickStyle.BELOW_LITERAL); |
| xAxisPrimary.getOrigin().setType(IntersectionType.VALUE_LITERAL); |
| xAxisPrimary.getTitle().setVisible(false); |
| xAxisPrimary.getTitle().getCaption().getFont().setSize(9); |
| xAxisPrimary.getTitle().getCaption().setColor(foreGround); |
| xAxisPrimary.getLabel().getCaption().setColor(foreGround); |
| |
| // //////// |
| // Y-Axis |
| yAxisPrimary = retValue.getPrimaryOrthogonalAxis(xAxisPrimary); |
| yAxisPrimary.getMajorGrid().setTickStyle(TickStyle.LEFT_LITERAL); |
| |
| // NumberDataSet[] orthoValues = new NumberDataSet[MAX_LINES]; |
| // SeriesDefinition[] sdY = new SeriesDefinition[MAX_LINES]; |
| |
| // end Y-Series |
| |
| // xAxis |
| xAxisPrimary.getScale().setMin(NumberDataElementImpl.create(0.0)); |
| xAxisPrimary.getScale().setMax(NumberDataElementImpl.create(1.0)); |
| xAxisPrimary.getScale().setStep(0.1); |
| xAxisPrimary.getLabel().getCaption().getFont().setSize(9); |
| xAxisPrimary.getLabel().getCaption().setColor(foreGround); |
| xAxisPrimary.getTitle().setVisible(true); |
| xAxisPrimary.getTitle().getCaption().setValue(Messages.getString("TS.TIMELABEL")); |
| |
| yAxisPrimary.getScale().setMin(NumberDataElementImpl.create(0.0)); |
| yAxisPrimary.getScale().setMax(NumberDataElementImpl.create(1.0)); |
| yAxisPrimary.getScale().setStep(0.1); |
| yAxisPrimary.getLabel().getCaption().getFont().setSize(9); |
| yAxisPrimary.getLabel().getCaption().setColor(foreGround); |
| yAxisPrimary.getTitle( ).getCaption( ).setValue( Ordinate_AXIS ); |
| yAxisPrimary.getTitle( ).setVisible(true); |
| // yAxisPrimary.getMajorGrid().getLineAttributes().setColor(foreGround); |
| |
| // for now get ready to create only one line - we have no data yet. |
| // we will add more lines as we need them |
| // handle null |
| if(!dataXYSeriesMap.containsKey(defaultKey)) { |
| DataXYSeries series = new DataXYSeries(defaultKey); |
| seriesCount ++; |
| dataXYSeriesMap.put(defaultKey, series); |
| } |
| |
| return retValue; |
| } // createSimpleLineChart |
| |
| |
| /** |
| * Create the view's context menu and add the action handlers to it. |
| */ |
| protected void createContextMenu(final Composite parent) { |
| |
| // Init a Context Menu Manager |
| final MenuManager contextMenuManager = new MenuManager(); |
| |
| // --------------------------------------------------------------------- |
| |
| linearTimeAction = new LinearScaleAction(); |
| logTimeAction = new LogScaleAction(); |
| contextMenuManager.add(linearTimeAction); |
| contextMenuManager.add(logTimeAction); |
| |
| |
| |
| // Place Holder for Menu Additions |
| contextMenuManager.add(new Separator( |
| IWorkbenchActionConstants.MB_ADDITIONS)); |
| |
| // --------------------------------------------------------------------- |
| |
| viewLegend = new LegendViewAction(); |
| hideLegend = new LegendHideAction(); |
| contextMenuManager.add(viewLegend); |
| contextMenuManager.add(hideLegend); |
| |
| // --------------------------------------------------------------------- |
| |
| |
| // Place Holder for Menu Additions |
| contextMenuManager.add(new Separator( |
| IWorkbenchActionConstants.MB_ADDITIONS)); |
| |
| popUpMenu = contextMenuManager.createContextMenu(parent); |
| |
| // Set the context menu for the viewer |
| parent.setMenu(popUpMenu); |
| |
| } // createContextMenu |
| |
| /** |
| * Update the view's context menu and add the action handlers to it. |
| */ |
| @SuppressWarnings("unused") |
| private void updateContextMenu(final Composite parent) { |
| |
| popUpMenu.dispose(); |
| |
| // Init a Context Menu Manager |
| final MenuManager contextMenuManager = new MenuManager(); |
| |
| // --------------------------------------------------------------------- |
| |
| linearTimeAction = new LinearScaleAction(); |
| logTimeAction = new LogScaleAction(); |
| contextMenuManager.add(linearTimeAction); |
| contextMenuManager.add(logTimeAction); |
| |
| // --------------------------------------------------------------------- |
| |
| |
| // Place Holder for Menu Additions |
| contextMenuManager.add(new Separator( |
| IWorkbenchActionConstants.MB_ADDITIONS)); |
| |
| // --------------------------------------------------------------------- |
| |
| viewLegend = new LegendViewAction(); |
| hideLegend = new LegendHideAction(); |
| contextMenuManager.add(viewLegend); |
| contextMenuManager.add(hideLegend); |
| |
| // --------------------------------------------------------------------- |
| |
| |
| // Place Holder for Menu Additions |
| contextMenuManager.add(new Separator( |
| IWorkbenchActionConstants.MB_ADDITIONS)); |
| |
| |
| // --------------------------------------------------------------------- |
| // add the displayable properties |
| for (int i = 0; i < control.getNumProperties(chartIndex); i ++) { |
| |
| String nextProp = control.getProperty(chartIndex,i); |
| DataXYSeries series = dataSeriesMap.get(nextProp); |
| DisplayableProperty property = new DisplayableProperty(nextProp, series.isVisible()); |
| contextMenuManager.add(property); |
| } |
| |
| // --------------------------------------------------------------------- |
| |
| // Place Holder for Menu Additions |
| contextMenuManager.add(new Separator( |
| IWorkbenchActionConstants.MB_ADDITIONS)); |
| |
| // --------------------------------------------------------------------- |
| |
| final Menu popUpMenu = contextMenuManager.createContextMenu(parent); |
| |
| // Set the context menu for the viewer |
| parent.setMenu(popUpMenu); |
| |
| |
| } // updateContextMenu |
| |
| |
| |
| /** |
| * Sets the colors for a n array of ScatterSeries given the property to Plot |
| * for each. Try to set color from the preferences (if specified for that |
| * property) otherwise sets line color to blue. |
| * |
| * @param propertiesToPlot |
| * @param lsList |
| */ |
| public static void setColorDefs( |
| final List<String> propertiesToPlot, |
| final List<ScatterSeries> lsList) { |
| // the default line color |
| |
| // if possible get color from preferences |
| final Map<String, Color> colorMap = VisualizationPreferencePage |
| .getColorMapping(); |
| for (int i = 0; i < lsList.size(); i++) { |
| ColorDefinition color = ColorDefinitionImpl.BLUE(); |
| |
| if ((propertiesToPlot != null) && (propertiesToPlot.size() > i)) { |
| final String key = propertiesToPlot.get(i); |
| // look or the preference color by name |
| if (colorMap.containsKey(key)) { |
| final Color c = colorMap.get(key); |
| color = ColorDefinitionImpl.create(c.getRed(), |
| c.getGreen(), c.getBlue()); |
| } |
| lsList.get(i).setSeriesIdentifier(key); |
| lsList.get(i).getLineAttributes().setColor(color); |
| } else { |
| |
| if (lsList.get(i) != null) { |
| lsList.get(i).setSeriesIdentifier(" "); |
| lsList.get(i).getLineAttributes().setColor(color); |
| } |
| } |
| } |
| return; |
| }// getColorDef |
| |
| |
| |
| |
| /** |
| * Disposes the Color objects |
| */ |
| @Override |
| public void dispose() { |
| super.dispose(); |
| } |
| |
| /** |
| * reset |
| */ |
| public void reset() { |
| resetData(); |
| redraw(); |
| } |
| |
| protected void resetData() { |
| clearData(); |
| } |
| |
| private void clearData() { |
| |
| Iterator<String> iter = dataSeriesMap.keySet().iterator(); |
| while((iter!=null)&&(iter.hasNext())) { |
| String key = iter.next(); |
| DataXYSeries series = dataSeriesMap.get(key); |
| series.yValues.clear(); |
| series.xValues.clear(); |
| series.addValue(new Double(0.0), new Double(0.0)); |
| } |
| |
| } |
| |
| |
| /** |
| * toggle the scale from logarithmic to linear |
| */ |
| void toggleAxisScale() { |
| // if (useLinearTimeScale) { //Switch to logarithmic scale |
| // logTimeAction.setChecked(true); |
| // linearTimeAction.setChecked(false); |
| // //Just using the following axis type, to move to log scale, didn't work |
| // //yAxisPrimary.setType(AxisType.LOGARITHMIC_LITERAL); |
| // yAxisPrimary.getScale().setMin(null); |
| // yAxisPrimary.getScale().setMax(null); |
| // yAxisPrimary.getScale().unsetStep(); |
| // yAxisPrimary.getScale().unsetStepNumber(); |
| // } |
| // else { //Switch to linear scale |
| // logTimeAction.setChecked(false); |
| // linearTimeAction.setChecked(true); |
| // //yAxisPrimary.setType(AxisType.LINEAR_LITERAL); |
| // yAxisPrimary.getScale().setMin(NumberDataElementImpl.create(0.0)); |
| // yAxisPrimary.getScale().setMax(NumberDataElementImpl.create(1.0)); |
| // yAxisPrimary.getScale().setStep(0.25); |
| // } |
| // useLinearTimeScale = !useLinearTimeScale; |
| // draw(); |
| } |
| |
| |
| /** |
| * toggle the scale from logarithmic to linear |
| */ |
| void toggleLegend() { |
| if (showLegend) { //Switch to hide |
| viewLegend.setChecked(false); |
| hideLegend.setChecked(true); |
| legend.setVisible(false); |
| } |
| else { //Switch to view |
| viewLegend.setChecked(true); |
| hideLegend.setChecked(false); |
| legend.setVisible(true); |
| } |
| showLegend = !showLegend; |
| draw(); |
| } |
| |
| |
| /** |
| * Action to show the legend |
| */ |
| protected class LegendViewAction extends Action { |
| public LegendViewAction() |
| { |
| super(Messages.getString("ContextMenu.ShowLegend"), IAction.AS_CHECK_BOX); |
| setChecked(showLegend); |
| } |
| |
| /** |
| * @see org.eclipse.jface.action.Action#getText() |
| */ |
| @Override |
| public String getText() { |
| return Messages.getString("ContextMenu.ShowLegend"); |
| } |
| |
| /** |
| * @see org.eclipse.jface.action.Action#run() |
| */ |
| @Override |
| public void run() { |
| if (showLegend) { |
| setChecked(true); |
| //Nothing to do. It's already linear-time. |
| } |
| else { |
| toggleLegend(); |
| } |
| draw(); |
| } |
| } //LegendViewAction |
| |
| /** |
| * Action to hide the legend |
| */ |
| class LegendHideAction extends Action { |
| public LegendHideAction() |
| { |
| super(Messages.getString("ContextMenu.HideLegend"), IAction.AS_CHECK_BOX); |
| setChecked(!showLegend); |
| } |
| |
| /** |
| * @see org.eclipse.jface.action.Action#getText() |
| */ |
| @Override |
| public String getText() { |
| return Messages.getString("ContextMenu.HideLegend"); |
| } |
| |
| /** |
| * @see org.eclipse.jface.action.Action#run() |
| */ |
| @Override |
| public void run() { |
| if (!showLegend) { |
| setChecked(true); |
| //Nothing to do. It's already log-time. |
| } |
| else { |
| toggleLegend(); |
| } |
| draw(); |
| } |
| }//LegendHideAction |
| |
| |
| /** |
| * switch to linear plot |
| * |
| */ |
| protected class LinearScaleAction extends Action { |
| public LinearScaleAction() |
| { |
| super(Messages.getString("ContextMenu.LinearTimeScale"), IAction.AS_CHECK_BOX); |
| setChecked(useLinearTimeScale); |
| } |
| |
| /** |
| * @see org.eclipse.jface.action.Action#getText() |
| */ |
| @Override |
| public String getText() { |
| return Messages.getString("ContextMenu.LinearTimeScale"); |
| } |
| |
| /** |
| * @see org.eclipse.jface.action.Action#run() |
| */ |
| @Override |
| public void run() { |
| if (useLinearTimeScale) { |
| setChecked(true); |
| //Nothing to do. It's already linear-time. |
| } |
| else { |
| toggleAxisScale(); |
| } |
| draw(); |
| } |
| } //LinearScaleAction |
| |
| /** |
| * switch to semi-log plot (log scale on y axis) |
| * |
| */ |
| class LogScaleAction extends Action { |
| public LogScaleAction() |
| { |
| super(Messages.getString("ContextMenu.LogTimeScale"), IAction.AS_CHECK_BOX); |
| setChecked(!useLinearTimeScale); |
| } |
| |
| /** |
| * @see org.eclipse.jface.action.Action#getText() |
| */ |
| @Override |
| public String getText() { |
| return Messages.getString("ContextMenu.LogTimeScale"); |
| } |
| |
| /** |
| * @see org.eclipse.jface.action.Action#run() |
| */ |
| @Override |
| public void run() { |
| if (!useLinearTimeScale) { |
| setChecked(true); |
| //Nothing to do. It's already log-time. |
| } |
| else { |
| toggleAxisScale(); |
| } |
| draw(); |
| } |
| }//LogScaleAction |
| |
| /** |
| * DisplayableProperty |
| * |
| */ |
| protected class DisplayableProperty extends Action |
| { |
| String property = null; |
| public DisplayableProperty(String property, boolean visibility) |
| { |
| super(property, IAction.AS_CHECK_BOX); |
| this.property = property; |
| setChecked(visibility); |
| } |
| |
| |
| |
| /** |
| * @see org.eclipse.jface.action.Action#getText() |
| */ |
| @Override |
| public String getText() { |
| return property; |
| } |
| |
| /** |
| * Toggle the state |
| * @see org.eclipse.jface.action.Action#run() |
| */ |
| @Override |
| public void run() { |
| DataXYSeries series = dataSeriesMap.get(property); |
| series.toggleVisible(); |
| dataSeriesMap.put(property,series); |
| setChecked(series.isVisible()); |
| draw(); |
| } |
| }// DisplayableProperty |
| |
| |
| /** |
| * Inner class DataXYSeries |
| * all the data objects for a plot |
| * |
| */ |
| protected class DataXYSeries |
| { |
| public String propertyName = ""; |
| |
| public List<Double> yValues = new ArrayList<Double>(); |
| public List<Double> xValues = new ArrayList<Double>(); |
| |
| public Series seriesX = null; |
| public ScatterSeries scatterSeriesY = null; |
| private boolean visible = true; |
| private SeriesDefinition sdY = null; |
| private SeriesDefinition sdX = null; |
| |
| |
| public boolean isVisible() { |
| return visible; |
| } |
| public void setVisible(boolean state) { |
| visible = state; |
| } |
| |
| public void toggleVisible() { |
| visible = !visible; |
| } |
| |
| /** |
| * |
| * @param propertyName |
| */ |
| public DataXYSeries(String propertyName) { |
| this.propertyName = propertyName; |
| yValues = new ArrayList<Double>(); |
| yValues.add(new Double(0.0)); |
| |
| xValues = new ArrayList<Double>(); |
| xValues.add(new Double(0.0)); |
| |
| addScatterSeries(propertyName); |
| } |
| |
| /** |
| * add an XY value pair |
| * @param valX |
| * @param valY |
| */ |
| public void addValue(Double valX, Double valY) { |
| if(yValues==null) yValues = new ArrayList<Double>(); |
| if(xValues==null) xValues = new ArrayList<Double>(); |
| xValues.add(valX); |
| yValues.add(valY); |
| } |
| |
| /** |
| * @param propertyName |
| * |
| */ |
| public void addScatterSeries(final String propertyName) { |
| |
| final NumberDataSet orthoValues = NumberDataSetImpl.create(yValues); |
| final NumberDataSet xAxisValues = NumberDataSetImpl.create(xValues); |
| |
| sdX = SeriesDefinitionImpl.create(); |
| //FractionNumberFormatSpecifier sf = FractionNumberFormatSpecifierImpl.create(); |
| //sf.setPrecise(true); |
| //sdX.setFormatSpecifier(sf); |
| xAxisPrimary.getSeriesDefinitions().add(sdX); |
| |
| |
| if(scatterSeriesY == null) { |
| sdY = SeriesDefinitionImpl.create(); |
| |
| scatterSeriesY = (ScatterSeries)ScatterSeriesImpl.create(); |
| seriesX = SeriesImpl.create(); |
| } // if scatterSeriesY==null |
| // new colors |
| seriesX.getLabel().getCaption().setColor(foreGround); |
| seriesX.getLabel().getOutline().setColor(foreGround); |
| seriesX.setDataSet(xAxisValues); |
| sdX.getSeries().add(seriesX); |
| |
| scatterSeriesY.setDataSet(orthoValues); |
| |
| // Assign the line color |
| // based on selected property. Default is Blue |
| setColorDefs(propertyName); |
| // If this is the "selected" region of a graph set the marker type |
| |
| // the series def |
| ColorDefinition color = ColorDefinitionImpl.create( |
| colorDefault[chartIndex][0], |
| colorDefault[chartIndex][1], |
| colorDefault[chartIndex][2]); |
| sdY.getSeriesPalette().update(color); |
| sdY.getSeries().add(scatterSeriesY); |
| yAxisPrimary.getSeriesDefinitions().add(sdY); |
| |
| return; |
| }// addScatterSeries |
| |
| /** |
| * in response to user action temporarily remove the line series from the graph |
| */ |
| public void hide() { |
| scatterSeriesY.setVisible(false); |
| visible = false; |
| }// hide |
| |
| /** |
| * in response to user action add back the line series to the graph |
| */ |
| public void show() { |
| scatterSeriesY.setVisible(true); |
| visible = true; |
| }// show |
| |
| |
| /** |
| * Sets the colors for a n array of ScatterSeries given the property to Plot |
| * for each. Try to set color from the preferences (if specified for that |
| * property) otherwise sets line color to blue. |
| * @param propertyName |
| * |
| */ |
| @SuppressWarnings("cast") |
| public void setColorDefs(String propertyName) { |
| this.scatterSeriesY.setSeriesIdentifier(propertyName); |
| if(propertyName.indexOf("XY")>=0) { |
| // the data |
| scatterSeriesY.setPaletteLineColor(true); |
| //scatterSeriesY.getLineAttributes().setColor(color); |
| //scatterSeriesY.getLineAttributes().setStyle(LineStyle.SOLID_LITERAL); |
| Marker marker = MarkerImpl.create(MarkerType.CIRCLE_LITERAL, 2); |
| scatterSeriesY.getMarkers().clear(); |
| scatterSeriesY.getMarkers().add(marker); |
| scatterSeriesY.getLineAttributes().setVisible(false); |
| } else { |
| // the fit |
| scatterSeriesY.getLineAttributes().setColor(ColorDefinitionImpl.BLACK()); |
| scatterSeriesY.getLineAttributes().setStyle(LineStyle.DOTTED_LITERAL); |
| scatterSeriesY.getLineAttributes().setVisible(true); |
| if (!scatterSeriesY.getMarkers().isEmpty()) { |
| Marker marker = (Marker)scatterSeriesY.getMarkers().get(0); |
| marker.setVisible(false); |
| } |
| } |
| |
| }// getColorDefs |
| |
| /** |
| * length of the series |
| * @return number of data points |
| */ |
| public int getDataSize() { |
| return yValues.size(); |
| } |
| // Accessors |
| public String getPropertyName() { |
| return propertyName; |
| } |
| |
| public void setPropertyName(String propertyName) { |
| this.propertyName = propertyName; |
| } |
| |
| public List<Double> getyValues() { |
| return yValues; |
| } |
| |
| public void setyValues(List<Double> yValues) { |
| this.yValues = yValues; |
| } |
| |
| |
| |
| public void setScatterSeries(ScatterSeries lineSeries) { |
| this.scatterSeriesY = lineSeries; |
| } |
| }// DataXYSeries |
| //////////////////////////////////////////////////////// |
| |
| } // XYSeriesCanvas |