package charts.builder.spreadsheet; import static charts.ChartType.PSII_MAX_HEQ; import static charts.graphics.PSIIMaxHeq.SEPARATOR; import static com.google.common.collect.Lists.newLinkedList; import static java.lang.String.format; import static java.util.Arrays.asList; import static org.apache.commons.lang.StringUtils.equalsIgnoreCase; import static org.apache.commons.lang.StringUtils.isBlank; import java.awt.Dimension; import java.io.IOException; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import org.jfree.data.category.CategoryDataset; import org.supercsv.io.CsvListWriter; import charts.ChartType; import charts.Drawable; import charts.Region; import charts.builder.DataSource.MissingDataException; import charts.builder.csv.Csv; import charts.builder.csv.CsvWriter; import charts.graphics.PSIIMaxHeq; import charts.graphics.PSIIMaxHeq.Condition; import charts.jfree.ADCDataset; import charts.jfree.Attribute; import charts.jfree.AttributeMap; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; public class PSIIMaxHeqBuilder extends JFreeBuilder { private static final String TITLE = "Maximum PSII Herbicide Equivalent Concentrations"; private static final Pattern YEAR_PATTERN = Pattern.compile(".*?(\\d+-\\d+).*?"); public PSIIMaxHeqBuilder() { super(PSII_MAX_HEQ); } @Override public boolean canHandle(SpreadsheetDataSource datasource) { try { return StringUtils.startsWithIgnoreCase(datasource.select("A1").asString(), TITLE); } catch(MissingDataException e) { throw new RuntimeException(e); } } private String getYear(String s) { Matcher m = YEAR_PATTERN.matcher(s); if(m.matches()) { String year = m.group(1); String[] y = StringUtils.split(year, '-'); if(y.length == 2 && y[0].length() == 4 && y[1].length() == 4) { return y[0].substring(2)+"-"+y[1].substring(2); } else { return year; } } else { throw new RuntimeException("trouble extracting year from "+s); } } private Condition getCondition(String s) { if(isBlank(s)) { return Condition.NOT_EVALUATED; } else if(equalsIgnoreCase("red", s)) { return Condition.VERY_POOR; } else if(equalsIgnoreCase("orange", s)) { return Condition.POOR; } else if(equalsIgnoreCase("yellow", s)) { return Condition.MODERATE; } else if(equalsIgnoreCase("light green", s)) { return Condition.GOOD; } else if(equalsIgnoreCase("dark green", s)) { return Condition.VERY_GOOD; } else { throw new RuntimeException(String.format("trouble mapping color %s to condition", s)); } } @Override protected ADCDataset createDataset(Context ctx) { if(ctx.region() != Region.GBR) { return null; } SpreadsheetDataSource ds = ctx.datasource(); try { ADCDataset dataset = new ADCDataset(); String year = ""; String region = ""; for(int row = 0;true;row++) { String col1 = ds.select(row, 0).asString(); if(StringUtils.equalsIgnoreCase("region", col1)) { continue; } if(StringUtils.startsWithIgnoreCase(col1, TITLE)) { year = getYear(col1); continue; } if(StringUtils.isNotBlank(col1)) { region = col1; } String site = ds.select(row, 1).asString(); if(StringUtils.isBlank(site)) { if(StringUtils.isBlank(ds.select(row+1, 0).asString())) { break; } else { continue; } } Double val = ds.select(row, 2).asDouble(); double v = val!=null?val:0.0; String condition = ds.select(row, 3).asString(); String key = StringUtils.join(Lists.newArrayList(region, site, year), SEPARATOR); dataset.addValue(v, getCondition(condition), key); } return dataset; } catch(MissingDataException e) { throw new RuntimeException(e); } } @Override public AttributeMap defaults(ChartType type) { return new AttributeMap.Builder(). put(Attribute.TITLE, TITLE). put(Attribute.X_AXIS_LABEL, ""). put(Attribute.Y_AXIS_LABEL, "Max PSII Heq ng/L"). build(); } @Override protected Drawable getDrawable(JFreeContext ctx) { return PSIIMaxHeq.createChart((ADCDataset)ctx.dataset(),new Dimension(1250, 500)); } @Override protected String getCsv(final JFreeContext ctx) { final CategoryDataset dataset = (CategoryDataset)ctx.dataset(); return Csv.write(new CsvWriter() { @Override public void write(CsvListWriter csv) throws IOException { @SuppressWarnings("unchecked") List<String> columnKeys = dataset.getColumnKeys(); @SuppressWarnings("unchecked") List<Condition> rowKeys = dataset.getRowKeys(); final List<String> heading = ImmutableList.<String>builder() .add(format("%s %s", ctx.region(), ctx.type().getLabel())) .add("Region") .add("Subregion") .add("Period") .add("ng/L") .add("Rating") .build(); csv.write(heading); for (String col : columnKeys) { List<String> line = newLinkedList(); line.add(""); line.addAll(asList(col.split("\\_\\|\\|\\_"))); for (Condition row : rowKeys) { final Number n = dataset.getValue(row, col); if (n == null) continue; line.add(format("%.1f", n.doubleValue())); line.add(row.getLabel()); } csv.write(line); } }}); } }