blob: 49416d578549145ac41b2902bb715d9dcce51b4e [file] [log] [blame]
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.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Vector;
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.ChartDimension;
import org.eclipse.birt.chart.model.attribute.ColorDefinition;
import org.eclipse.birt.chart.model.attribute.IntersectionType;
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.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.TextDataSet;
import org.eclipse.birt.chart.model.data.impl.NumberDataSetImpl;
import org.eclipse.birt.chart.model.data.impl.SeriesDefinitionImpl;
import org.eclipse.birt.chart.model.data.impl.TextDataSetImpl;
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.BarSeries;
import org.eclipse.birt.chart.model.type.impl.BarSeriesImpl;
import org.eclipse.birt.chart.util.PluginSettings;
import org.eclipse.stem.util.analysis.Activator;
import org.eclipse.stem.util.analysis.Parameter;
import org.eclipse.swt.SWT;
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.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Widget;
/**
* TimeSeriesCanvas is a subclass of {@link Canvas} suitable for chart drawings.
*/
public class EstimatorCanvas extends Canvas {
protected IDeviceRenderer idr = null;
/**
* This is the {@link Chart} that plots the relative values.
*/
protected Chart cm = null;
//private EstimatorControl control = null;
static ColorDefinition[] barColors = {ColorDefinitionImpl.RED(),
ColorDefinitionImpl.BLUE(),
ColorDefinitionImpl.ORANGE(),
ColorDefinitionImpl.YELLOW(),
ColorDefinitionImpl.GREEN(),
ColorDefinitionImpl.PINK(),
ColorDefinitionImpl.BLACK() };
/**
* the chart title
*/
private static final String TITLE = "Estimated Parameters";
/**
* the legend
*/
private static final String VALUES = "Parameter Values";
private static final String VALUES_LOWER = "Value - Std.Dev.";
private static final String VALUES_HIGHER = "Value + Std.Dev.";
private static final boolean SHOW_STD_DEV = false;
/**
* Collection of values for the X-SERIES bar labels
**/
private static Vector<String> xAxisParameterNames = new Vector<String>();
/**
* Collection of values for the Y-SERIES bars
**/
private static ArrayList<Double> barValues = new ArrayList<Double>();
private static NumberDataSet barOrthoValues;
/**
* Collection of values for the Y-SERIES2 standard deviation lower and higher bars
**/
private static ArrayList<Double> barStdDevLower = new ArrayList<Double>();
private static ArrayList<Double> barStdDevHigher = new ArrayList<Double>();
private static NumberDataSet barOrthoStdDevLower;
private static NumberDataSet barOrthoStdDevHigher
;
/**
* Chart generator instance (reference to a singleton)
*/
Generator gr;
Image imgChart = null;
/**
* Constructor.
*
* @param parent
* the SWT parent of the {@link Widget}
*/
public EstimatorCanvas(final Composite parent) {
super(parent, SWT.DOUBLE_BUFFERED | SWT.BORDER);
gr = Generator.instance();
try {
idr = PluginSettings.instance().getDevice("dv.SWT"); //$NON-NLS-1$
} catch (final ChartException pex) {
Activator.logError("Problem initializing chart", pex); //$NON-NLS-1$
return;
}
//control = (EstimatorControl) parent;
Vector<String> xAxisParameters = new Vector<String>();
xAxisParameters.add("beta");
xAxisParameters.add("alpha");
xAxisParameters.add("epsilon");
xAxisParameters.add("gamma");
//Map<String,Double> initMap = ModelParameters;
//cm = createBarChart(initMap);
addPaintListener(new PaintListener() {
public void paintControl(final PaintEvent pe) {
if(cm == null) return;
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
);
} // EstimatorCanvas constructor
/**
* * creates the chart
* @param barDataMap
* @return a bar chart
*/
@SuppressWarnings("deprecation")
public static Chart createBarChart(Map<String,Parameter> barDataMap) {
// Reset everything
xAxisParameterNames.clear();
barValues.clear();
barStdDevLower.clear();
barStdDevHigher.clear();
// BAR CHARTS ARE BASED ON CHARTS THAT CONTAIN AXES
ChartWithAxes cwaBar = ChartWithAxesImpl.create();
cwaBar.getBlock().setBackground(ColorDefinitionImpl.WHITE());
cwaBar.getBlock().getOutline().setVisible(true);
cwaBar.setDimension(ChartDimension.TWO_DIMENSIONAL_WITH_DEPTH_LITERAL);
// CUSTOMIZE THE PLOT
Plot p = cwaBar.getPlot();
p.getClientArea().setBackground(ColorDefinitionImpl.create(255, 255, 225));
p.getOutline().setVisible(false);
cwaBar.getTitle().getLabel().getCaption().setValue(TITLE);
// CUSTOMIZE THE LEGEND
Legend lg = cwaBar.getLegend();
lg.getText().getFont().setSize(16);
lg.getInsets().set(10, 5, 0, 0);
lg.setAnchor(Anchor.NORTH_LITERAL);
// CUSTOMIZE THE X-AXIS
Axis xAxisPrimary = cwaBar.getPrimaryBaseAxes()[0];
xAxisPrimary.setType(AxisType.TEXT_LITERAL);
xAxisPrimary.getMajorGrid().setTickStyle(TickStyle.BELOW_LITERAL);
xAxisPrimary.getOrigin().setType(IntersectionType.VALUE_LITERAL);
xAxisPrimary.getTitle().setVisible(false);
// CUSTOMIZE THE Y-AXIS
Axis yAxisPrimary = cwaBar.getPrimaryOrthogonalAxis(xAxisPrimary);
yAxisPrimary.getMajorGrid().setTickStyle(TickStyle.LEFT_LITERAL);
yAxisPrimary.setType(AxisType.LINEAR_LITERAL);
yAxisPrimary.getLabel().getCaption().getFont().setRotation(90);
// populate from the map
Set<String> keySet = barDataMap.keySet();
String[] keys = new String[keySet.size()];
Iterator<String> iter = keySet.iterator();
int icount = 0;
while(iter.hasNext()) {
keys[icount] = iter.next();
icount ++;
}
Arrays.sort(keys);
for (int i = 0; i < keys.length; i++) {
String paramName = keys[i];
xAxisParameterNames.add(paramName);
Double dValue = new Double(barDataMap.get(paramName).value);
barStdDevLower.add(dValue);
barValues.add(dValue);
barStdDevHigher.add(dValue);
}
TextDataSet categoryValues = TextDataSetImpl.create(xAxisParameterNames);
barOrthoValues = NumberDataSetImpl.create(barValues);
barOrthoStdDevLower = NumberDataSetImpl.create(barStdDevLower);
barOrthoStdDevHigher = NumberDataSetImpl.create(barStdDevHigher);
// CREATE THE CATEGORY BASE SERIES
Series seCategory = SeriesImpl.create();
seCategory.setDataSet(categoryValues);
// Create the first series of dataValues the ORTHOGONAL Value-Statndard deviations LOWER SERIES
BarSeries bsLower = (BarSeries) BarSeriesImpl.create();
bsLower.setSeriesIdentifier(VALUES_LOWER);
bsLower.setDataSet(barOrthoStdDevLower);
bsLower.setRiserOutline(null);
bsLower.getLabel().setVisible(true);
bsLower.setLabelPosition(Position.INSIDE_LITERAL);
// Create the Values series of dataValues the ORTHOGONAL SERIES
BarSeries bsValues = (BarSeries) BarSeriesImpl.create();
bsValues.setSeriesIdentifier(VALUES);
bsValues.setDataSet(barOrthoValues);
bsValues.setRiserOutline(null);
bsValues.getLabel().setVisible(true);
bsValues.setLabelPosition(Position.INSIDE_LITERAL);
// Create the THIRD series of dataValues the ORTHOGONAL Value+StdDev HIGHER SERIES
BarSeries bsHigher = (BarSeries) BarSeriesImpl.create();
bsHigher.setSeriesIdentifier(VALUES_HIGHER);
bsHigher.setDataSet(barOrthoStdDevHigher);
bsHigher.setRiserOutline(null);
bsHigher.getLabel().setVisible(true);
bsHigher.setLabelPosition(Position.INSIDE_LITERAL);
// WRAP THE BASE SERIES IN THE X-AXIS SERIES DEFINITION
SeriesDefinition sdX = SeriesDefinitionImpl.create();
sdX.getSeriesPalette().update(0); // SET THE COLORS IN THE PALETTE
xAxisPrimary.getSeriesDefinitions().add(sdX);
sdX.getSeries().add(seCategory);
if (SHOW_STD_DEV) {
// One THE ORTHOGONAL VALUES-STD-DEV lower SERIES For the Y-AXIS SERIES DEFINITION
SeriesDefinition sdYlower = SeriesDefinitionImpl.create();
sdYlower.getSeriesPalette().update(1); // SET THE COLOR IN THE PALETTE
yAxisPrimary.getSeriesDefinitions().add(sdYlower);
sdYlower.getSeries().add(bsLower);
}
// Two THE ORTHOGONAL VALUES SERIES For the Y-AXIS SERIES DEFINITION
SeriesDefinition sdY1 = SeriesDefinitionImpl.create();
sdY1.getSeriesPalette().update(1); // SET THE COLOR IN THE PALETTE
yAxisPrimary.getSeriesDefinitions().add(sdY1);
sdY1.getSeries().add(bsValues);
if (SHOW_STD_DEV) {
// Three THE ORTHOGONAL VALUES+STDDEV Higher SERIES For the Y-AXIS SERIES DEFINITION
SeriesDefinition sdYHigher = SeriesDefinitionImpl.create();
sdYHigher.getSeriesPalette().update(1); // SET THE COLOR IN THE PALETTE
yAxisPrimary.getSeriesDefinitions().add(sdYHigher);
sdYHigher.getSeries().add(bsHigher);
}
return cwaBar;
}// createBarChart
/**
* refreshes (some of) the data in the bar chart by key values
* @param barDataMap All parameters
*/
public static void refresh(Map<String,Parameter> barDataMap) {
//Iterator<String> iter = barDataMap.keySet().iterator();
//while(iter.hasNext()) {
for (Entry<String,Parameter> entry : barDataMap.entrySet()) {
int icount = xAxisParameterNames.indexOf(entry.getKey());
if (icount >= 0) {
double value = entry.getValue().value;
// and the higher/lower values
double deviation = entry.getValue().stddev;
Double lower = new Double(value-deviation);
Double higher = new Double(value + deviation);
barValues.set(icount,new Double(value));
barStdDevLower.set(icount,lower);
barStdDevHigher.set(icount,higher);
}
}// while have keys
}// refresh
/**
* The method which gets the {@link EstimatorCanvas}' reports list, and
* draws it on the {@link EstimatorCanvas}.
* @param barDataMap Parameter map
*
*/
public void draw(Map<String,Parameter> barDataMap) {
cm = EstimatorCanvas.createBarChart(barDataMap);
//refresh(barDataMap);
if (!this.isDisposed()) {
redraw();
}
} // paintControl
/**
* Disposes the Color objects
*/
@Override
public void dispose() {
super.dispose();
}
} // TimeSeriesCanvas