package charts.builder.spreadsheet;
import java.awt.Color;
import java.awt.Dimension;
import java.io.IOException;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.jfree.data.category.CategoryDataset;
import org.supercsv.io.CsvListWriter;
import play.Logger;
import charts.ChartType;
import charts.Drawable;
import charts.builder.DataSource.MissingDataException;
import charts.builder.Value;
import charts.builder.csv.Csv;
import charts.builder.csv.CsvWriter;
import charts.graphics.AnnualRainfall;
import charts.jfree.ADCDataset;
import charts.jfree.Attribute;
import charts.jfree.AttributeMap;
import com.google.common.collect.ImmutableSet;
public class AnnualRainfallBuilder extends JFreeBuilder {
private static final SubstitutionKey START_YEAR = new SubstitutionKey("startYear",
"first year of annual rainfall data in the spreadsheet",
new SubstitutionKey.Val() {
@Override
public String value(Context ctx) {
CategoryDataset dataset = (CategoryDataset)((JFreeContext)ctx).dataset();
if(!dataset.getColumnKeys().isEmpty()) {
return dataset.getColumnKeys().get(0).toString();
} else {
return "";
}
}
});
private static final SubstitutionKey END_YEAR = new SubstitutionKey("endYear",
"last year of annual rainfall data in the spreadsheet",
new SubstitutionKey.Val() {
@Override
public String value(Context ctx) {
CategoryDataset dataset = (CategoryDataset)((JFreeContext)ctx).dataset();
if(!dataset.getColumnKeys().isEmpty()) {
return dataset.getColumnKeys().get(dataset.getColumnKeys().size()-1).toString();
} else {
return "";
}
}
});
private static final SubstitutionKey MAR_REGION = new SubstitutionKey("marRegion",
"mean annual rainfall region copied from spreadsheet A2-A7",
new SubstitutionKey.Val() {
@Override
public String value(Context ctx) {
try {
return ctx.datasource().select(regionRow(ctx), 0).asString();
} catch (MissingDataException e) {
return ctx.region().getProperName();
}
}
});
public AnnualRainfallBuilder() {
super(ChartType.ANNUAL_RAINFALL);
}
@Override
protected ADCDataset createDataset(Context ctx) {
Integer row = regionRow(ctx);
if(row == null) {
return null;
}
final String series = "rainfall";
ADCDataset dataset = new ADCDataset();
try {
for (int i = 1; true; i++) {
String year = ctx.datasource().select(0, i).asString();
if (StringUtils.equalsIgnoreCase("Annual Average", year)) {
break;
}
String rainfall = ctx.datasource().select(row, i).asString();
if (StringUtils.isBlank(year) || StringUtils.isBlank(rainfall)) {
break;
}
double val = Double.parseDouble(rainfall);
dataset.addValue(val, series, Integer.toString(parseYear(year)));
}
} catch (Exception e) {
Logger.debug("while building dataset for the annual rainfall chart", e);
}
return dataset;
}
private int parseYear(String y) {
y = StringUtils.strip(y);
if (y.contains(".")) {
y = StringUtils.substringBefore(y, ".");
}
return Integer.parseInt(y);
}
@Override
public boolean canHandle(SpreadsheetDataSource datasource) {
try {
if(datasource.getColumnCount(0) != null) {
for(int column = 1; column<datasource.getColumnCount(0);column++) {
Value v = datasource.select(0, column);
if(v.asInteger() == null) {
return StringUtils.equalsIgnoreCase(
"Annual Average", StringUtils.strip(v.asString()));
}
}
}
} catch (MissingDataException e) {}
return false;
}
@Override
public AttributeMap defaults(ChartType type) {
return new AttributeMap.Builder().
put(Attribute.TITLE, "Mean annual rainfall for ${startYear}-${endYear} - ${marRegion}").
put(Attribute.X_AXIS_LABEL, "Year").
put(Attribute.Y_AXIS_LABEL, "Rainfall (mm)").
put(Attribute.SERIES_COLOR, Color.blue).
build();
}
@Override
protected Drawable getDrawable(JFreeContext ctx) {
return new AnnualRainfall().createChart((ADCDataset)ctx.dataset(), new Dimension(750, 500));
}
@Override
protected String getCsv(JFreeContext ctx) {
final CategoryDataset dataset = (CategoryDataset)ctx.dataset();
return Csv.write(new CsvWriter() {
@Override
public void write(CsvListWriter csv) throws IOException {
csv.write("Year", "Rainfall (mm)");
for (int i = 0; i < dataset.getColumnCount(); i++) {
csv.write(dataset.getColumnKey(i), dataset.getValue(0, i));
}
}});
}
@Override
public Set<SubstitutionKey> substitutionKeys() {
return ImmutableSet.<SubstitutionKey>builder().
addAll(super.substitutionKeys()).add(START_YEAR).add(END_YEAR).add(MAR_REGION).build();
}
private static Integer regionRow(Context ctx) {
int row = 1;
for(Value v : ctx.datasource().rangeRowSelect(0, 1, 6)) {
if(StringUtils.containsIgnoreCase(v.asString(), ctx.region().getProperName()) ||
StringUtils.containsIgnoreCase(
v.asString(), StringUtils.split(ctx.region().getProperName())[0])) {
return row;
}
row++;
}
return null;
}
}