package charts.builder.spreadsheet; import static charts.ChartType.PSII_TRENDS; 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.isBlank; import static org.apache.commons.lang.StringUtils.isNotBlank; import java.awt.Color; import java.awt.Dimension; import java.io.IOException; import java.util.List; import java.util.Map; 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.PSIITrends; import charts.jfree.ADCDataset; import charts.jfree.Attribute; import charts.jfree.AttributeMap; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.Maps; public class PSIITrendsBuilder extends JFreeBuilder { private static final String TITLE = "Maximum concentration of individual PSII herbicides"; private static final Pattern YEAR_PATTERN = Pattern.compile(".*?(\\d+-\\d+).*?"); public PSIITrendsBuilder() { super(PSII_TRENDS); } @Override public boolean canHandle(SpreadsheetDataSource datasource) { try { return StringUtils.startsWithIgnoreCase(datasource.select("A2").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 boolean eof(SpreadsheetDataSource ds, int row) throws MissingDataException { for(int i=0;i<3;i++) { if(isNotBlank(ds.select(row+i, 1).asString())) { return false; } } return true; } @Override protected ADCDataset createDataset(Context ctx) { if(ctx.region() != Region.GBR) { return null; } final SpreadsheetDataSource ds = ctx.datasource(); try { ADCDataset dataset = new ADCDataset(); String cRegion = null; String year = null; List<String> pesticides = Lists.newArrayList(); Map<String, Color> seriesColors = Maps.newHashMap(); for(int row = 1;!eof(ds, row);row++) { String col1 = ds.select(row, 0).asString(); if(StringUtils.startsWithIgnoreCase(col1, TITLE)) { year = getYear(col1); continue; } else if(StringUtils.equalsIgnoreCase("region", col1)) { pesticides = Lists.newArrayList(); for(int col=2;col<13;col++) { String p = ds.select(row, col).asString(); if(isBlank(p)) { break; } else { pesticides.add(p); Color c = ds.select(row,col).asColor(); if(c!= null && !Color.white.equals(c)) { seriesColors.put(p, c); } } } continue; } if(isNotBlank(col1)) { cRegion = col1; } String site = ds.select(row, 1).asString(); if(isBlank(site)) { continue; } for(int i=0;i<pesticides.size();i++) { String p = pesticides.get(i); Double val = ds.select(row, i+2).asDouble(); double v = val!=null?val:0.0; String key = StringUtils.join( Lists.newArrayList(cRegion, site, year), PSIITrends.SEPARATOR); dataset.addValue(v, p, 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, "Concentration in water (ng/L)"). put(Attribute.SERIES_COLORS, PSIITrends.SERIES_PAINT). build(); } @Override protected Drawable getDrawable(JFreeContext ctx) { return PSIITrends.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<String> 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") .addAll(rowKeys) .build(); csv.write(heading); for (String col : columnKeys) { List<String> line = newLinkedList(); line.add(""); line.addAll(asList(col.split("\\_\\|\\|\\_"))); for (String row : rowKeys) { line.add(format("%.1f", dataset.getValue(row, col).doubleValue())); } csv.write(line); } }}); } }