Java tutorial
/******************************************************************************* * Copyright (c) 2015 Federal Institute for Risk Assessment (BfR), Germany * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Department Biological Safety - BfR *******************************************************************************/ package de.bund.bfr.knime.pmm.common.chart; import java.awt.Color; import java.awt.Shape; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.swing.JFileChooser; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.filechooser.FileFilter; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.labels.StandardXYToolTipGenerator; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.DeviationRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.data.Range; import org.jfree.data.xy.DefaultXYDataset; import org.jfree.data.xy.YIntervalSeries; import org.jfree.data.xy.YIntervalSeriesCollection; import de.bund.bfr.knime.pmm.common.pmmtablemodel.AttributeUtilities; import de.bund.bfr.knime.pmm.common.units.ConvertException; public class ChartCreator extends ChartPanel { private static final long serialVersionUID = 1L; private List<ZoomListener> zoomListeners; private Map<String, Plotable> plotables; private Map<String, String> shortLegend; private Map<String, String> longLegend; private Map<String, Color> colors; private Map<String, Shape> shapes; private Map<String, List<Color>> colorLists; private Map<String, List<Shape>> shapeLists; private String paramX; private String paramY; private String unitX; private String unitY; private String transformX; private String transformY; private boolean useManualRange; private double minX; private double minY; private double maxX; private double maxY; private boolean drawLines; private boolean showLegend; private boolean addInfoInLegend; private boolean showConfidenceInterval; private boolean inverse; private List<String> warnings; public ChartCreator(Plotable plotable) { super(new JFreeChart(new XYPlot())); zoomListeners = new ArrayList<>(); getPopupMenu().remove(10); getPopupMenu().remove(9); getPopupMenu().remove(8); getPopupMenu().remove(7); getPopupMenu().remove(6); getPopupMenu().remove(3); getPopupMenu().add(new DataAndModelChartSaveAsItem(), 3); plotables = new LinkedHashMap<>(); shortLegend = new LinkedHashMap<>(); longLegend = new LinkedHashMap<>(); colors = new LinkedHashMap<>(); shapes = new LinkedHashMap<>(); colorLists = new LinkedHashMap<>(); shapeLists = new LinkedHashMap<>(); plotables.put("", plotable); shortLegend.put("", ""); longLegend.put("", ""); } public ChartCreator(Map<String, Plotable> plotables, Map<String, String> shortLegend, Map<String, String> longLegend) { super(new JFreeChart(new XYPlot())); zoomListeners = new ArrayList<>(); getPopupMenu().remove(10); getPopupMenu().remove(9); getPopupMenu().remove(8); getPopupMenu().remove(7); getPopupMenu().remove(6); getPopupMenu().remove(3); getPopupMenu().add(new DataAndModelChartSaveAsItem(), 3); this.plotables = plotables; this.shortLegend = shortLegend; this.longLegend = longLegend; colors = new LinkedHashMap<>(); shapes = new LinkedHashMap<>(); colorLists = new LinkedHashMap<>(); shapeLists = new LinkedHashMap<>(); } public void addZoomListener(ZoomListener listener) { zoomListeners.add(listener); } public void removeZoomListener(ZoomListener listener) { zoomListeners.remove(listener); } @Override public void mouseReleased(MouseEvent e) { ValueAxis domainAxis = ((XYPlot) getChart().getPlot()).getDomainAxis(); ValueAxis rangeAxis = ((XYPlot) getChart().getPlot()).getRangeAxis(); Range xRange1 = domainAxis.getRange(); Range yRange1 = rangeAxis.getRange(); super.mouseReleased(e); Range xRange2 = domainAxis.getRange(); Range yRange2 = rangeAxis.getRange(); if (!xRange1.equals(xRange2) || !yRange1.equals(yRange2)) { minX = xRange2.getLowerBound(); maxX = xRange2.getUpperBound(); minY = yRange2.getLowerBound(); maxY = yRange2.getUpperBound(); fireZoomChanged(); } } public void createChart() { setChart(getChart(new ArrayList<>(plotables.keySet()))); } public void createChart(String idToPaint) { setChart(getChart(idToPaint)); } public void createChart(List<String> idsToPaint) { setChart(getChart(idsToPaint)); } public JFreeChart getChart(String idToPaint) { if (idToPaint != null) { return getChart(Arrays.asList(idToPaint)); } else { return getChart(new ArrayList<String>()); } } public JFreeChart getChart(List<String> idsToPaint) { if (paramX == null || paramY == null) { return new JFreeChart(null, JFreeChart.DEFAULT_TITLE_FONT, new XYPlot(), showLegend); } NumberAxis xAxis = new NumberAxis(AttributeUtilities.getNameWithUnit(paramX, unitX, transformX)); NumberAxis yAxis = new NumberAxis(AttributeUtilities.getNameWithUnit(paramY, unitY, transformY)); XYPlot plot = new XYPlot(null, xAxis, yAxis, null); double usedMinX = Double.POSITIVE_INFINITY; double usedMaxX = Double.NEGATIVE_INFINITY; int index = 0; ColorAndShapeCreator colorAndShapeCreator = new ColorAndShapeCreator(idsToPaint.size()); for (String id : idsToPaint) { Plotable plotable = plotables.get(id); try { if (plotable != null) { if (plotable.getType() == Plotable.BOTH || plotable.getType() == Plotable.BOTH_STRICT) { Double minArg = Plotable.transform( plotable.convertToUnit(paramX, plotable.getMinArguments().get(paramX), unitX), transformX); Double maxArg = Plotable.transform( plotable.convertToUnit(paramX, plotable.getMaxArguments().get(paramX), unitX), transformX); if (isValid(minArg)) { usedMinX = Math.min(usedMinX, minArg); } if (isValid(maxArg)) { usedMaxX = Math.max(usedMaxX, maxArg); } for (Map<String, Integer> choice : plotable.getAllChoices()) { double[][] points = plotable.getPoints(paramX, paramY, unitX, unitY, transformX, transformY, choice); if (points != null) { for (int i = 0; i < points[0].length; i++) { if (isValid(points[0][i])) { usedMinX = Math.min(usedMinX, points[0][i]); usedMaxX = Math.max(usedMaxX, points[0][i]); } } } } } else if (plotable.getType() == Plotable.DATASET || plotable.getType() == Plotable.DATASET_STRICT) { double[][] points = plotable.getPoints(paramX, paramY, unitX, unitY, transformX, transformY); if (points != null) { for (int i = 0; i < points[0].length; i++) { if (isValid(points[0][i])) { usedMinX = Math.min(usedMinX, points[0][i]); usedMaxX = Math.max(usedMaxX, points[0][i]); } } } } else if (plotable.getType() == Plotable.FUNCTION) { Double minArg = Plotable.transform( plotable.convertToUnit(paramX, plotable.getMinArguments().get(paramX), unitX), transformX); Double maxArg = Plotable.transform( plotable.convertToUnit(paramX, plotable.getMaxArguments().get(paramX), unitX), transformX); if (isValid(minArg)) { usedMinX = Math.min(usedMinX, minArg); } if (isValid(maxArg)) { usedMaxX = Math.max(usedMaxX, maxArg); } } else if (plotable.getType() == Plotable.FUNCTION_SAMPLE) { Double minArg = Plotable.transform( plotable.convertToUnit(paramX, plotable.getMinArguments().get(paramX), unitX), transformX); Double maxArg = Plotable.transform( plotable.convertToUnit(paramX, plotable.getMaxArguments().get(paramX), unitX), transformX); if (isValid(minArg)) { usedMinX = Math.min(usedMinX, minArg); } if (isValid(maxArg)) { usedMaxX = Math.max(usedMaxX, maxArg); } for (Double x : plotable.getSamples()) { Double xx = Plotable.transform(plotable.convertToUnit(paramX, x, unitX), transformX); if (isValid(xx)) { usedMinX = Math.min(usedMinX, xx); usedMaxX = Math.max(usedMaxX, xx); } } } } } catch (ConvertException e) { } } if (Double.isInfinite(usedMinX)) { usedMinX = 0.0; } if (Double.isInfinite(usedMaxX)) { usedMaxX = 100.0; } if (paramX.equals(AttributeUtilities.TIME) || paramX.equals(AttributeUtilities.CONCENTRATION)) { usedMinX = Math.min(usedMinX, 0.0); xAxis.setAutoRangeIncludesZero(true); } else { xAxis.setAutoRangeIncludesZero(false); } if (paramY.equals(AttributeUtilities.TIME) || paramY.equals(AttributeUtilities.CONCENTRATION)) { yAxis.setAutoRangeIncludesZero(true); } else { yAxis.setAutoRangeIncludesZero(false); } if (usedMinX == usedMaxX) { usedMinX -= 1.0; usedMaxX += 1.0; } if (useManualRange && minX < maxX && minY < maxY) { usedMinX = minX; usedMaxX = maxX; xAxis.setRange(new Range(minX, maxX)); yAxis.setRange(new Range(minY, maxY)); } Set<ConvertException> convertExceptions = new LinkedHashSet<>(); for (String id : idsToPaint) { Plotable plotable = plotables.get(id); if (plotable != null && plotable.getType() == Plotable.DATASET) { try { plotDataSet(plot, plotable, id, colorAndShapeCreator.getColorList().get(index), colorAndShapeCreator.getShapeList().get(index)); index++; } catch (ConvertException e) { convertExceptions.add(e); } } } for (String id : idsToPaint) { Plotable plotable = plotables.get(id); if (plotable != null && plotable.getType() == Plotable.DATASET_STRICT) { try { plotDataSetStrict(plot, plotable, id); index++; } catch (ConvertException e) { convertExceptions.add(e); } } } for (String id : idsToPaint) { Plotable plotable = plotables.get(id); if (plotable != null && plotable.getType() == Plotable.FUNCTION) { try { plotFunction(plot, plotable, id, colorAndShapeCreator.getColorList().get(index), colorAndShapeCreator.getShapeList().get(index), usedMinX, usedMaxX); index++; } catch (ConvertException e) { convertExceptions.add(e); } } } warnings = new ArrayList<>(); for (String id : idsToPaint) { Plotable plotable = plotables.get(id); if (plotable != null && plotable.getType() == Plotable.FUNCTION_SAMPLE) { try { plotFunctionSample(plot, plotable, id, colorAndShapeCreator.getColorList().get(index), colorAndShapeCreator.getShapeList().get(index), usedMinX, usedMaxX, warnings); index++; } catch (ConvertException e) { convertExceptions.add(e); } } } for (String id : idsToPaint) { Plotable plotable = plotables.get(id); if (plotable != null && plotable.getType() == Plotable.BOTH) { try { plotBoth(plot, plotable, id, colorAndShapeCreator.getColorList().get(index), colorAndShapeCreator.getShapeList().get(index), usedMinX, usedMaxX); index++; } catch (ConvertException e) { convertExceptions.add(e); } } } for (String id : idsToPaint) { Plotable plotable = plotables.get(id); if (plotable != null && plotable.getType() == Plotable.BOTH_STRICT) { try { plotBothStrict(plot, plotable, id, usedMinX, usedMaxX); index++; } catch (ConvertException e) { convertExceptions.add(e); } } } if (!convertExceptions.isEmpty()) { String warning = "Some datasets/functions cannot be converted to the desired unit\n"; warning += "Uncovertable units: "; for (ConvertException e : convertExceptions) { warning += e.getFromUnit() + "->" + e.getToUnit() + ", "; } warning = warning.substring(0, warning.length() - 2); JOptionPane.showMessageDialog(this, warning, "Warning", JOptionPane.WARNING_MESSAGE); } return new JFreeChart(null, JFreeChart.DEFAULT_TITLE_FONT, plot, showLegend); } public Map<String, Plotable> getPlotables() { return plotables; } public String getParamX() { return paramX; } public void setParamX(String paramX) { this.paramX = paramX; } public String getParamY() { return paramY; } public void setParamY(String paramY) { this.paramY = paramY; } public String getUnitX() { return unitX; } public void setUnitX(String unitX) { this.unitX = unitX; } public String getUnitY() { return unitY; } public void setUnitY(String unitY) { this.unitY = unitY; } public String getTransformX() { return transformX; } public void setTransformX(String transformX) { this.transformX = transformX; } public String getTransformY() { return transformY; } public void setTransformY(String transformY) { this.transformY = transformY; } public boolean isUseManualRange() { return useManualRange; } public void setUseManualRange(boolean useManualRange) { this.useManualRange = useManualRange; } public double getMinX() { return minX; } public void setMinX(double minX) { this.minX = minX; } public double getMinY() { return minY; } public void setMinY(double minY) { this.minY = minY; } public double getMaxX() { return maxX; } public void setMaxX(double maxX) { this.maxX = maxX; } public double getMaxY() { return maxY; } public void setMaxY(double maxY) { this.maxY = maxY; } public boolean isDrawLines() { return drawLines; } public void setDrawLines(boolean drawLines) { this.drawLines = drawLines; } public boolean isShowLegend() { return showLegend; } public void setShowLegend(boolean showLegend) { this.showLegend = showLegend; } public boolean isAddInfoInLegend() { return addInfoInLegend; } public void setAddInfoInLegend(boolean addInfoInLegend) { this.addInfoInLegend = addInfoInLegend; } public boolean isShowConfidenceInterval() { return showConfidenceInterval; } public void setShowConfidenceInterval(boolean showConfidenceInterval) { this.showConfidenceInterval = showConfidenceInterval; } public boolean isInverse() { return inverse; } public void setInverse(boolean inverse) { this.inverse = inverse; } public Map<String, Color> getColors() { return colors; } public void setColors(Map<String, Color> colors) { this.colors = colors; } public Map<String, Shape> getShapes() { return shapes; } public void setShapes(Map<String, Shape> shapes) { this.shapes = shapes; } public Map<String, List<Color>> getColorLists() { return colorLists; } public void setColorLists(Map<String, List<Color>> colorLists) { this.colorLists = colorLists; } public Map<String, List<Shape>> getShapeLists() { return shapeLists; } public void setShapeLists(Map<String, List<Shape>> shapeLists) { this.shapeLists = shapeLists; } public List<String> getWarnings() { return warnings; } private void fireZoomChanged() { for (ZoomListener listener : zoomListeners) { listener.zoomChanged(); } } private void plotDataSet(XYPlot plot, Plotable plotable, String id, Color defaultColor, Shape defaultShape) throws ConvertException { double[][] points = plotable.getPoints(paramX, paramY, unitX, unitY, transformX, transformY); String legend = shortLegend.get(id); Color color = colors.get(id); Shape shape = shapes.get(id); if (addInfoInLegend) { legend = longLegend.get(id); } if (color == null) { color = defaultColor; } if (shape == null) { shape = defaultShape; } if (points != null) { DefaultXYDataset dataset = new DefaultXYDataset(); XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(drawLines, true); dataset.addSeries(legend, points); renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); renderer.setSeriesPaint(0, color); renderer.setSeriesShape(0, shape); int i; if (plot.getDataset(0) == null) { i = 0; } else { i = plot.getDatasetCount(); } plot.setDataset(i, dataset); plot.setRenderer(i, renderer); } } private void plotDataSetStrict(XYPlot plot, Plotable plotable, String id) throws ConvertException { String legend = shortLegend.get(id); List<Color> colorList = colorLists.get(id); List<Shape> shapeList = shapeLists.get(id); ColorAndShapeCreator creator = new ColorAndShapeCreator(plotable.getNumberOfCombinations()); int index = 0; if (addInfoInLegend) { legend = longLegend.get(id); } if (colorList == null || colorList.isEmpty()) { colorList = creator.getColorList(); } if (shapeList == null || shapeList.isEmpty()) { shapeList = creator.getShapeList(); } for (Map<String, Integer> choiceMap : plotable.getAllChoices()) { double[][] dataPoints = plotable.getPoints(paramX, paramY, unitX, unitY, transformX, transformY, choiceMap); if (dataPoints != null) { DefaultXYDataset dataSet = new DefaultXYDataset(); XYLineAndShapeRenderer dataRenderer = new XYLineAndShapeRenderer(drawLines, true); String addLegend = ""; for (String arg : choiceMap.keySet()) { if (!arg.equals(paramX)) { addLegend += " (" + arg + "=" + plotable.getFunctionArguments().get(arg).get(choiceMap.get(arg)) + ")"; } } dataSet.addSeries(legend + addLegend, dataPoints); dataRenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); dataRenderer.setSeriesPaint(0, colorList.get(index)); dataRenderer.setSeriesShape(0, shapeList.get(index)); int i; if (plot.getDataset(0) == null) { i = 0; } else { i = plot.getDatasetCount(); } plot.setDataset(i, dataSet); plot.setRenderer(i, dataRenderer); } index++; } } private void plotFunction(XYPlot plot, Plotable plotable, String id, Color defaultColor, Shape defaultShape, double minX, double maxX) throws ConvertException { double[][] points = plotable.getFunctionPoints(paramX, paramY, unitX, unitY, transformX, transformY, minX, maxX, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); double[][] functionErrors = null; String legend = shortLegend.get(id); Color color = colors.get(id); Shape shape = shapes.get(id); if (showConfidenceInterval) { functionErrors = plotable.getFunctionErrors(paramX, paramY, unitX, unitY, transformX, transformY, minX, maxX, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); } if (addInfoInLegend) { legend = longLegend.get(id); } if (color == null) { color = defaultColor; } if (shape == null) { shape = defaultShape; } if (points != null) { int i; if (plot.getDataset(0) == null) { i = 0; } else { i = plot.getDatasetCount(); } if (functionErrors != null) { YIntervalSeriesCollection functionDataset = new YIntervalSeriesCollection(); DeviationRenderer functionRenderer = new DeviationRenderer(true, false); YIntervalSeries series = new YIntervalSeries(legend); for (int j = 0; j < points[0].length; j++) { double error = Double.isNaN(functionErrors[1][j]) ? 0.0 : functionErrors[1][j]; series.add(points[0][j], points[1][j], points[1][j] - error, points[1][j] + error); } functionDataset.addSeries(series); functionRenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); functionRenderer.setSeriesPaint(0, color); functionRenderer.setSeriesFillPaint(0, color); functionRenderer.setSeriesShape(0, shape); plot.setDataset(i, functionDataset); plot.setRenderer(i, functionRenderer); } else { DefaultXYDataset functionDataset = new DefaultXYDataset(); XYLineAndShapeRenderer functionRenderer = new XYLineAndShapeRenderer(true, false); functionDataset.addSeries(legend, points); functionRenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); functionRenderer.setSeriesPaint(0, color); functionRenderer.setSeriesShape(0, shape); plot.setDataset(i, functionDataset); plot.setRenderer(i, functionRenderer); } } } private void plotFunctionSample(XYPlot plot, Plotable plotable, String id, Color defaultColor, Shape defaultShape, double minX, double maxX, List<String> warnings) throws ConvertException { double[][] functionPoints = plotable.getFunctionPoints(paramX, paramY, unitX, unitY, transformX, transformY, minX, maxX, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); double[][] samplePoints; if (!inverse) { samplePoints = plotable.getFunctionSamplePoints(paramX, paramY, unitX, unitY, transformX, transformY, minX, maxX, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, warnings); } else { samplePoints = plotable.getInverseFunctionSamplePoints(paramX, paramY, unitX, unitY, transformX, transformY, minX, maxX, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, warnings); } double[][] functionErrors = null; String legend = shortLegend.get(id); Color color = colors.get(id); Shape shape = shapes.get(id); if (showConfidenceInterval) { functionErrors = plotable.getFunctionErrors(paramX, paramY, unitX, unitY, transformX, transformY, minX, maxX, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); } if (addInfoInLegend) { legend = longLegend.get(id); } if (color == null) { color = defaultColor; } if (shape == null) { shape = defaultShape; } if (functionPoints != null) { int i; if (plot.getDataset(0) == null) { i = 0; } else { i = plot.getDatasetCount(); } if (functionErrors != null) { YIntervalSeriesCollection functionDataset = new YIntervalSeriesCollection(); DeviationRenderer functionRenderer = new DeviationRenderer(true, false); YIntervalSeries series = new YIntervalSeries(legend); for (int j = 0; j < functionPoints[0].length; j++) { double error = Double.isNaN(functionErrors[1][j]) ? 0.0 : functionErrors[1][j]; series.add(functionPoints[0][j], functionPoints[1][j], functionPoints[1][j] - error, functionPoints[1][j] + error); } functionDataset.addSeries(series); functionRenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); functionRenderer.setSeriesPaint(0, color); functionRenderer.setSeriesFillPaint(0, color); functionRenderer.setSeriesShape(0, shape); if (samplePoints != null) { functionRenderer.setBaseSeriesVisibleInLegend(false); } plot.setDataset(i, functionDataset); plot.setRenderer(i, functionRenderer); } else { DefaultXYDataset functionDataset = new DefaultXYDataset(); XYLineAndShapeRenderer functionRenderer = new XYLineAndShapeRenderer(true, false); functionDataset.addSeries(legend, functionPoints); functionRenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); functionRenderer.setSeriesPaint(0, color); functionRenderer.setSeriesShape(0, shape); if (samplePoints != null) { functionRenderer.setBaseSeriesVisibleInLegend(false); } plot.setDataset(i, functionDataset); plot.setRenderer(i, functionRenderer); } if (samplePoints != null) { DefaultXYDataset sampleDataset = new DefaultXYDataset(); XYLineAndShapeRenderer sampleRenderer = new XYLineAndShapeRenderer(false, true); sampleDataset.addSeries(legend, samplePoints); sampleRenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); sampleRenderer.setSeriesPaint(0, color); sampleRenderer.setSeriesShape(0, shape); plot.setDataset(i + 1, sampleDataset); plot.setRenderer(i + 1, sampleRenderer); } } } private void plotBoth(XYPlot plot, Plotable plotable, String id, Color defaultColor, Shape defaultShape, double minX, double maxX) throws ConvertException { double[][] modelPoints = plotable.getFunctionPoints(paramX, paramY, unitX, unitY, transformX, transformY, minX, maxX, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); double[][] dataPoints = plotable.getPoints(paramX, paramY, unitX, unitY, transformX, transformY); double[][] functionErrors = null; String legend = shortLegend.get(id); Color color = colors.get(id); Shape shape = shapes.get(id); if (showConfidenceInterval) { functionErrors = plotable.getFunctionErrors(paramX, paramY, unitX, unitY, transformX, transformY, minX, maxX, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); } if (addInfoInLegend) { legend = longLegend.get(id); } if (color == null) { color = defaultColor; } if (shape == null) { shape = defaultShape; } if (modelPoints != null) { int i; if (plot.getDataset(0) == null) { i = 0; } else { i = plot.getDatasetCount(); } if (functionErrors != null) { YIntervalSeriesCollection functionDataset = new YIntervalSeriesCollection(); DeviationRenderer functionRenderer = new DeviationRenderer(true, false); YIntervalSeries series = new YIntervalSeries(legend); for (int j = 0; j < modelPoints[0].length; j++) { double error = Double.isNaN(functionErrors[1][j]) ? 0.0 : functionErrors[1][j]; series.add(modelPoints[0][j], modelPoints[1][j], modelPoints[1][j] - error, modelPoints[1][j] + error); } functionDataset.addSeries(series); functionRenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); functionRenderer.setSeriesPaint(0, color); functionRenderer.setSeriesFillPaint(0, color); functionRenderer.setSeriesShape(0, shape); if (dataPoints != null) { functionRenderer.setBaseSeriesVisibleInLegend(false); } plot.setDataset(i, functionDataset); plot.setRenderer(i, functionRenderer); } else { DefaultXYDataset functionDataset = new DefaultXYDataset(); XYLineAndShapeRenderer functionRenderer = new XYLineAndShapeRenderer(true, false); functionDataset.addSeries(legend, modelPoints); functionRenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); functionRenderer.setSeriesPaint(0, color); functionRenderer.setSeriesShape(0, shape); if (dataPoints != null) { functionRenderer.setBaseSeriesVisibleInLegend(false); } plot.setDataset(i, functionDataset); plot.setRenderer(i, functionRenderer); } } if (dataPoints != null) { DefaultXYDataset dataSet = new DefaultXYDataset(); XYLineAndShapeRenderer dataRenderer = new XYLineAndShapeRenderer(drawLines, true); dataSet.addSeries(legend, dataPoints); dataRenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); dataRenderer.setSeriesPaint(0, color); dataRenderer.setSeriesShape(0, shape); int i; if (plot.getDataset(0) == null) { i = 0; } else { i = plot.getDatasetCount(); } plot.setDataset(i, dataSet); plot.setRenderer(i, dataRenderer); } } private void plotBothStrict(XYPlot plot, Plotable plotable, String id, double minX, double maxX) throws ConvertException { String legend = shortLegend.get(id); List<Color> colorList = colorLists.get(id); List<Shape> shapeList = shapeLists.get(id); ColorAndShapeCreator creator = new ColorAndShapeCreator(plotable.getNumberOfCombinations()); int index = 0; if (addInfoInLegend) { legend = longLegend.get(id); } if (colorList == null || colorList.isEmpty()) { colorList = creator.getColorList(); } if (shapeList == null || shapeList.isEmpty()) { shapeList = creator.getShapeList(); } for (Map<String, Integer> choiceMap : plotable.getAllChoices()) { double[][] dataPoints = plotable.getPoints(paramX, paramY, unitX, unitY, transformX, transformY, choiceMap); if (dataPoints == null) { continue; } double[][] modelPoints = plotable.getFunctionPoints(paramX, paramY, unitX, unitY, transformX, transformY, minX, maxX, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, choiceMap); if (modelPoints == null) { continue; } double[][] modelErrors = null; if (showConfidenceInterval) { modelErrors = plotable.getFunctionErrors(paramX, paramY, unitX, unitY, transformX, transformY, minX, maxX, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, choiceMap); } int i; if (plot.getDataset(0) == null) { i = 0; } else { i = plot.getDatasetCount(); } String addLegend = ""; for (String arg : choiceMap.keySet()) { if (!arg.equals(paramX)) { addLegend += " (" + arg + "=" + plotable.getFunctionArguments().get(arg).get(choiceMap.get(arg)) + ")"; } } if (modelErrors != null) { YIntervalSeriesCollection modelSet = new YIntervalSeriesCollection(); DeviationRenderer modelRenderer = new DeviationRenderer(true, false); YIntervalSeries series = new YIntervalSeries(legend); for (int j = 0; j < modelPoints[0].length; j++) { double error = Double.isNaN(modelErrors[1][j]) ? 0.0 : modelErrors[1][j]; series.add(modelPoints[0][j], modelPoints[1][j], modelPoints[1][j] - error, modelPoints[1][j] + error); } modelSet.addSeries(series); modelRenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); modelRenderer.setSeriesPaint(0, colorList.get(index)); modelRenderer.setSeriesFillPaint(0, colorList.get(index)); modelRenderer.setSeriesShape(0, shapeList.get(index)); if (dataPoints != null) { modelRenderer.setBaseSeriesVisibleInLegend(false); } plot.setDataset(i, modelSet); plot.setRenderer(i, modelRenderer); } else { DefaultXYDataset modelSet = new DefaultXYDataset(); XYLineAndShapeRenderer modelRenderer = new XYLineAndShapeRenderer(true, false); modelSet.addSeries(legend + addLegend, modelPoints); modelRenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); modelRenderer.setBaseSeriesVisibleInLegend(false); modelRenderer.setSeriesPaint(0, colorList.get(index)); modelRenderer.setSeriesShape(0, shapeList.get(index)); plot.setDataset(i, modelSet); plot.setRenderer(i, modelRenderer); } DefaultXYDataset dataSet = new DefaultXYDataset(); XYLineAndShapeRenderer dataRenderer = new XYLineAndShapeRenderer(drawLines, true); dataSet.addSeries(legend + addLegend, dataPoints); dataRenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); dataRenderer.setSeriesPaint(0, colorList.get(index)); dataRenderer.setSeriesShape(0, shapeList.get(index)); plot.setDataset(i + 1, dataSet); plot.setRenderer(i + 1, dataRenderer); index++; } } private boolean isValid(Double value) { return value != null && !value.isInfinite() && !value.isNaN(); } private class DataAndModelChartSaveAsItem extends JMenuItem implements ActionListener { private static final long serialVersionUID = 1L; public DataAndModelChartSaveAsItem() { super("Save as..."); addActionListener(this); } private void fireSaveAsButtonClicked(String fileName) { ChartCreator chartPanel = ChartCreator.this; ChartUtilities.saveChartAs(chartPanel.getChart(), fileName, chartPanel.getWidth(), chartPanel.getHeight()); } @Override public void actionPerformed(ActionEvent e) { JFileChooser fileChooser = new JFileChooser(); FileFilter svgFilter = new FileFilter() { @Override public String getDescription() { return "SVG Vector Graphic (*.svg)"; } @Override public boolean accept(File f) { return f.isDirectory() || f.getName().toLowerCase().endsWith(".svg"); } }; FileFilter pngFilter = new FileFilter() { @Override public String getDescription() { return "Portable Network Graphics (*.png)"; } @Override public boolean accept(File f) { return f.isDirectory() || f.getName().toLowerCase().endsWith(".png"); } }; fileChooser.setAcceptAllFileFilterUsed(false); fileChooser.addChoosableFileFilter(pngFilter); fileChooser.addChoosableFileFilter(svgFilter); if (fileChooser.showSaveDialog(ChartCreator.this) == JFileChooser.APPROVE_OPTION) { String fileName = fileChooser.getSelectedFile().getName(); String path = fileChooser.getSelectedFile().getAbsolutePath(); if (fileChooser.getFileFilter() == svgFilter) { if (fileName.toLowerCase().endsWith(".svg")) { fireSaveAsButtonClicked(path); } else { fireSaveAsButtonClicked(path + ".svg"); } } else if (fileChooser.getFileFilter() == pngFilter) { if (fileName.toLowerCase().endsWith(".png")) { fireSaveAsButtonClicked(path); } else { fireSaveAsButtonClicked(path + ".png"); } } } } } public static interface ZoomListener { public void zoomChanged(); } }