package org.eclipse.iee.pad.graph.ui;
import java.awt.BasicStroke;
import java.awt.Color;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.iee.editor.core.pad.common.text.AbstractVisualTextEditor;
import org.eclipse.iee.pad.graph.model.GraphElement;
import org.eclipse.iee.pad.graph.model.GraphModel;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.swt.widgets.Display;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.chart.event.AxisChangeListener;
import org.jfree.chart.plot.DrawingSupplier;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.util.ResourceBundleWrapper;
import org.jfree.data.general.DatasetChangeEvent;
import org.jfree.data.xy.AbstractXYDataset;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.RectangleInsets;
import org.jfree.util.PaintUtilities;
public class ChartEditor extends AbstractVisualTextEditor<GraphModel, ChartFigure> {
private AxisChangeListener fDomainAxisListener;
private AxisChangeListener fRangeAxisListener;
private PropertyChangeListener fListener;
private Map<Integer, double[][]> results = new HashMap<>();
private XYDataset dataset;
private IShellProvider fShellProvider;
private JFreeChart fChart;
/** The resourceBundle for the localization. */
protected static ResourceBundle localizationResources = ResourceBundleWrapper
.getBundle("org.jfree.chart.LocalizationBundle");
public ChartEditor(IShellProvider fShellProvider) {
this.fShellProvider = fShellProvider;
fListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
String propertyName = evt.getPropertyName();
if ("maxX".equals(propertyName) || "minX".equals(propertyName) || "maxY".equals(propertyName)
|| "minY".equals(propertyName)) {
updateAxes(getPlot());
}
}
};
}
@Override
protected ChartFigure createFigure() {
ChartFigure chartFigure = new ChartFigure(getChart(), fShellProvider);
chartFigure.setPreferredSize(new Dimension(500, 250));
return chartFigure;
}
public JFreeChart createChart() {
XYDataset dataset = createDataset("Series 1");
JFreeChart chart = ChartFactory.createXYLineChart(null, null, null, dataset, PlotOrientation.HORIZONTAL, false,
false, false);
chart.setBackgroundPaint(Color.white);
chart.setBorderVisible(true);
chart.setBorderPaint(Color.BLACK);
XYPlot plot = (XYPlot) chart.getPlot();
plot.setOrientation(PlotOrientation.VERTICAL);
plot.setBackgroundPaint(Color.lightGray);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
plot.getRangeAxis().setFixedDimension(15.0);
XYItemRenderer renderer = plot.getRenderer();
renderer.setSeriesPaint(0, Color.black);
updateAxes(plot);
fDomainAxisListener = new AxisChangeListener() {
@Override
public void axisChanged(AxisChangeEvent event) {
ValueAxis axis = (ValueAxis) event.getAxis();
updateXAxis(axis);
}
};
fRangeAxisListener = new AxisChangeListener() {
@Override
public void axisChanged(AxisChangeEvent event) {
ValueAxis axis = (ValueAxis) event.getAxis();
updateYAxis(axis);
}
};
plot.getDomainAxis().addChangeListener(fDomainAxisListener);
plot.getRangeAxis().addChangeListener(fRangeAxisListener);
return chart;
}
@Override
protected void doBindValue(GraphModel value) {
value.addPropertyChangeListener(fListener);
}
@Override
protected void doUnbindValue(GraphModel oldValue) {
oldValue.removePropertyChangeListener(fListener);
}
private void updateAxes(XYPlot plot) {
final GraphModel model = getModel();
if (model != null && model.getMaxX() != null && model.getMinX() != null) {
plot.getDomainAxis().setRange(model.getMinX(), model.getMaxX());
} else {
plot.getDomainAxis().setAutoRange(true);
}
if (model != null && model.getMaxY() != null && model.getMinY() != null) {
plot.getRangeAxis().setRange(model.getMinY(), model.getMaxY());
} else {
plot.getRangeAxis().setAutoRange(true);
}
}
private void updateXAxis(ValueAxis axis) {
GraphModel model = getModel();
if (axis.isAutoRange()) {
model.setMinX(null);
model.setMaxX(null);
} else {
model.setMinX(axis.getRange().getLowerBound());
model.setMaxX(axis.getRange().getUpperBound());
}
}
private void updateYAxis(ValueAxis axis) {
GraphModel model = getModel();
if (axis.isAutoRange()) {
model.setMinY(null);
model.setMaxY(null);
} else {
model.setMinY(axis.getRange().getLowerBound());
model.setMaxY(axis.getRange().getUpperBound());
}
}
public XYDataset createDataset(String name) {
dataset = new AbstractXYDataset() {
private static final long serialVersionUID = 1L;
@Override
public Number getY(int arg0, int arg1) {
return getResult(arg0)[arg1][1];
}
@Override
public Number getX(int arg0, int arg1) {
return getResult(arg0)[arg1][0];
}
@Override
public int getItemCount(int arg0) {
return getResult(arg0).length;
}
@Override
public Comparable<Integer> getSeriesKey(int arg0) {
return Integer.valueOf(arg0);
}
@Override
public int getSeriesCount() {
GraphModel model = getModel();
return model != null ? model.getElements().size() : 0;
}
private double[][] getResult(int number) {
double[][] ds = getResults().get(Integer.valueOf(number));
if (ds == null) {
return new double[0][];
}
return ds;
}
};
return dataset;
}
public Map<Integer, double[][]> getResults() {
if (results == null) {
results = new HashMap<Integer, double[][]>();
}
return results;
}
@Override
public boolean isSelectable() {
// TODO Auto-generated method stub
return false;
}
@Override
public void setSelected(boolean b) {
// TODO Auto-generated method stub
}
@Override
public void setActive(boolean b) {
// TODO Auto-generated method stub
}
public void dispose() {
getModel().removePropertyChangeListener(fListener);
getPlot().getDomainAxis().removeChangeListener(fDomainAxisListener);
getPlot().getRangeAxis().removeChangeListener(fRangeAxisListener);
}
public void setResult(Map<Integer, double[][]> result) {
results = new HashMap<>(result);
Display.getDefault().asyncExec(new Runnable() {
public void run() {
XYItemRenderer renderer = getPlot().getRenderer();
List<GraphElement> elements = getModel().getElements();
for (int i = 0; i < elements.size(); i++) {
GraphElement element = elements.get(i);
String color = element.getColor();
if (color == null) {
color = PaintUtilities.colorToString((Color) getPlot().getDrawingSupplier().getNextPaint());
}
renderer.setSeriesPaint(i, PaintUtilities.stringToColor(color));
int width = element.getWidth();
if (width < 1) {
width = 1;
}
renderer.setSeriesStroke(i, new BasicStroke(width));
}
getPlot().datasetChanged(new DatasetChangeEvent(this, dataset));
}
});
}
public DrawingSupplier getDrawingSupplier() {
return getPlot().getDrawingSupplier();
}
private XYPlot getPlot() {
return (XYPlot) getChart().getPlot();
}
JFreeChart getChart() {
if (fChart == null) {
fChart = createChart();
}
return fChart;
}
}