package charts.graphics;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.Rectangle2D;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.DefaultDrawingSupplier;
import org.jfree.chart.plot.DrawingSupplier;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.TextAnchor;
import charts.ChartType;
import charts.Drawable;
import charts.Region;
import charts.builder.spreadsheet.JFreeContext;
import charts.graphics.BeerCoaster.Condition;
import charts.jfree.ADCDataset;
import charts.jfree.Attribute;
public class MarineTrends {
private static class MarineTrendsRenderer extends LineAndShapeRenderer {
private boolean drawBreak;
public void setDrawBreak(boolean drawBreak) {
this.drawBreak = drawBreak;
}
@Override
public void drawBackground(Graphics2D g2, CategoryPlot plot,
Rectangle2D dataArea) {
super.drawBackground(g2, plot, dataArea);
NumberAxis raxis = (NumberAxis)plot.getRangeAxis();
int value = 100;
for(Condition c : BeerCoaster.Condition.values()) {
if(c == Condition.NOT_EVALUATED) {
continue;
}
drawCondition(g2, c.getLabel(),
raxis.valueToJava2D(value-20, dataArea, RectangleEdge.LEFT),
raxis.valueToJava2D(value, dataArea, RectangleEdge.LEFT),
c.getColor(), dataArea);
value-=20;
}
if(drawBreak) {
Double x0 = getXOfCol("2012/13", dataArea);
Double x1 = getXOfCol("2013/14", dataArea);
if((x0 != null) && (x1 != null)) {
double xc = x0 + ((x1 - x0) / 2);
g2.setStroke(new BasicStroke(1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f,
new float[] {5.0f, 5.0f}, 0.0f));
g2.setPaint(Color.lightGray);
g2.draw(new java.awt.geom.Line2D.Double(xc, dataArea.getMinY(), xc, dataArea.getMaxY()));
}
}
}
private Double getXOfCol(String s, Rectangle2D dataArea) {
try {
CategoryAxis axis = this.getPlot().getDomainAxis();
return axis.getCategoryMiddle(s, getPlot().getDataset().getColumnKeys(), dataArea,
getPlot().getDomainAxisEdge());
} catch(Exception e) {
return null;
}
}
private void drawCondition(Graphics2D g2, String text,
double y0, double y1, Color background, Rectangle2D dataArea) {
double width = 20;
double height = Math.abs(y1-y0);
double yCenter = y1+height/2;
double xCenter = dataArea.getMinX()+width/2;
g2.setColor(background);
g2.fill(new Rectangle2D.Double(dataArea.getMinX(), Math.min(y0, y1), width, height));
g2.setColor(Color.black);
TextUtilities.drawRotatedString(text, g2, (float)xCenter, (float)yCenter,
TextAnchor.CENTER, -Math.PI/2, (float)xCenter, (float)yCenter);
}
}
public static Drawable createChart(final ADCDataset dataset,
Dimension dimension, JFreeContext ctx) {
final JFreeChart chart = ChartFactory.createLineChart(
dataset.get(Attribute.TITLE),
dataset.get(Attribute.X_AXIS_LABEL),
dataset.get(Attribute.Y_AXIS_LABEL),
dataset,
PlotOrientation.VERTICAL,
true, false, false);
final CategoryPlot plot = chart.getCategoryPlot();
plot.setDrawingSupplier(drawingSupplier());
plot.setBackgroundPaint(Color.white);
plot.setDomainGridlinesVisible(false);
plot.setRangeGridlinePaint(Color.gray);
plot.setRangeGridlineStroke(new BasicStroke(1));
NumberAxis raxis = (NumberAxis)plot.getRangeAxis();
raxis.setRange(0, 100.0);
raxis.setTickUnit(new NumberTickUnit(20));
MarineTrendsRenderer renderer = new MarineTrendsRenderer();
if(ChartType.MARINE_ST.equals(ctx.type()) && Region.CAPE_YORK.equals(ctx.region())) {
renderer.setDrawBreak(true);
}
plot.setRenderer(renderer);
for(int i=0;i<dataset.get(Attribute.SERIES_COLORS).length;i++) {
renderer.setSeriesPaint(i, dataset.get(Attribute.SERIES_COLORS)[i]);
}
renderer.setUseOutlinePaint(false);
renderer.setBaseShapesVisible(true);
final CategoryAxis domainAxis = plot.getDomainAxis();
domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
return new JFreeChartDrawable(chart, dimension);
}
private static DrawingSupplier drawingSupplier() {
Stroke[] strokes = new Stroke[] { stroke(), stroke(5,5),
stroke(20,5,5,5), stroke(10,10), stroke(20,5,5,5,5,5)};
return new DefaultDrawingSupplier(
DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE,
DefaultDrawingSupplier.DEFAULT_FILL_PAINT_SEQUENCE,
DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE,
strokes,
DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE,
DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE);
}
private static Stroke stroke(float... dash) {
return new BasicStroke(1.0f, BasicStroke.CAP_SQUARE,BasicStroke.JOIN_BEVEL,
1f, dash.length > 0?dash:null, 0f);
}
}