///////////////////////////////////////////////////////////////////////////// // // Project ProjectForge Community Edition // www.projectforge.org // // Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de) // // ProjectForge is dual-licensed. // // This community edition 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; version 3 of the License. // // This community edition 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/. // ///////////////////////////////////////////////////////////////////////////// package org.projectforge.charting; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.Ellipse2D; import java.util.Date; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.DateAxis; import org.jfree.chart.axis.DateTickMarkPosition; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.data.general.Series; import org.jfree.data.time.DateRange; import org.jfree.data.xy.XYDataset; import org.projectforge.user.PFUserContext; /** * Builder class for building JFree charts. * @author Kai Reinhard (k.reinhard@micromata.de) * */ public class XYChartBuilder { private final XYPlot plot; private final JFreeChart chart; private final Shape circleShape = new Ellipse2D.Float(-2, -2, 4, 4); private final Shape strongCircleShape = new Ellipse2D.Float(-3, -3, 6, 6); private final Stroke strongStroke = new BasicStroke(3.0f); private final Stroke stroke = new BasicStroke(1.0f); private ValueAxis xAxis; private final Stroke dashedStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 3.0f, new float[] { 3.0f, 3.0f}, 1.0f); public XYChartBuilder(final String title, final String xAxisLabel, final String yAxisLabel, final XYDataset dataset, final boolean legend) { this(ChartFactory.createXYLineChart(title, xAxisLabel, yAxisLabel, dataset, PlotOrientation.VERTICAL, legend, true, false)); } public XYChartBuilder(final JFreeChart chart) { this.chart = chart; plot = chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.lightGray); plot.setRangeGridlinePaint(Color.lightGray); plot.setOutlineVisible(false); } public XYChartBuilder setDateXAxis(final boolean showAxisValues) { xAxis = new DateAxis(); ((DateAxis) xAxis).setTickMarkPosition(DateTickMarkPosition.MIDDLE); xAxis.setLowerMargin(0.0); xAxis.setUpperMargin(0.0); xAxis.setVisible(showAxisValues); plot.setDomainAxis(xAxis); return this; } public XYChartBuilder setDateXAxisRange(final Date lower, final Date upper) { if (xAxis == null) { throw new IllegalArgumentException("Call set*XAxis first. No xAxis given yet."); } xAxis.setRange(new DateRange(lower, upper)); return this; } public XYChartBuilder setYAxis(final boolean showAxisValues, final String valueAxisUnitKey) { final NumberAxis yAxis; if (showAxisValues == true && valueAxisUnitKey != null) { yAxis = new NumberAxis(PFUserContext.getLocalizedString(valueAxisUnitKey)); } else { yAxis = new NumberAxis(); } yAxis.setVisible(showAxisValues); plot.setRangeAxis(yAxis); return this; } public XYChartBuilder setDataset(final int index, final XYDataset dataset) { plot.setDataset(index, dataset); return this; } /** * Applies {@link #strongCircleShape} and {@link #strongStroke} if set to all series entries. * @param renderer * @param visibleInLegend * @param series * @return */ public XYChartBuilder setStrongStyle(final XYItemRenderer renderer, final boolean visibleInLegend, final Series... series) { if (series == null || series.length == 0) { return this; } for (int i = 0; i < series.length; i++) { renderer.setSeriesShape(i, strongCircleShape); } for (int i = 0; i < series.length; i++) { renderer.setSeriesStroke(i, strongStroke); renderer.setSeriesVisibleInLegend(i, visibleInLegend); } return this; } /** * Applies {@link #strongCircleShape} and {@link #strongStroke} if set to all series entries. * @param renderer * @param visibleInLegend * @param series * @return */ public XYChartBuilder setNormalStyle(final XYItemRenderer renderer, final boolean visibleInLegend, final Series... series) { if (series == null || series.length == 0) { return this; } for (int i = 0; i < series.length; i++) { renderer.setSeriesShape(i, circleShape); } for (int i = 0; i < series.length; i++) { renderer.setSeriesStroke(i, stroke); renderer.setSeriesVisibleInLegend(i, visibleInLegend); } return this; } /** * @return the chart */ public JFreeChart getChart() { return chart; } public XYChartBuilder setRenderer(final int index, final XYItemRenderer renderer) { plot.setRenderer(index, renderer); return this; } /** * @return the dashedStroke */ public Stroke getDashedStroke() { return dashedStroke; } /** * @return the stroke */ public Stroke getStroke() { return stroke; } public Color getRedFill() { return new Color(238, 176, 176); } public Color getGreenFill() { return new Color(135, 206, 112); } public Color getRedMarker() { return new Color(222, 23, 33); } public Color getGreenMarker() { return new Color(64, 169, 59); } public Color getGrayMarker() { return new Color(55, 55, 55); } }