package charts.builder.spreadsheet; import java.awt.Color; import java.awt.Dimension; import java.io.IOException; import java.text.DecimalFormat; import java.util.List; import java.util.Set; import org.apache.commons.lang3.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.Value; import charts.builder.csv.Csv; import charts.builder.csv.CsvWriter; import charts.graphics.Colors; import charts.graphics.WetlandLoss; import charts.jfree.ADCDataset; import charts.jfree.Attribute; import charts.jfree.AttributeMap; import com.google.common.collect.ImmutableSet; public class WetlandsLossBuilder extends JFreeBuilder { private static final String SWAMPS = "Vegetated freshwater swamps loss"; private static final String FLATS = "Mangroves/salt flats loss"; private static final String WETLANDS_LOSS = "Wetlands loss (%)"; private static final String TITLE = "Wetlands (vegetated freshwater swamps and" + " mangroves/salt flats) loss"; public WetlandsLossBuilder() { super(ChartType.WETLANDS_LOSS); } @Override public boolean canHandle(SpreadsheetDataSource ds) { try { int fc = findFirstColumn(ds); return (startsWith(ds.select(0, fc), "Region") || startsWith(ds.select(0, fc), "Catchment")) && startsWith(ds.select(0, fc+1), SWAMPS) && startsWith(ds.select(0, fc+2), FLATS) && startsWith(ds.select(0, fc+3), SWAMPS) && startsWith(ds.select(0, fc+4), FLATS); } catch(MissingDataException e) {} return false; } private int findFirstColumn(SpreadsheetDataSource datasource) { Integer cc = datasource.getColumnCount(0); if(cc == null) { return 0; } else { try { for(int c = 0;c<cc;c++) { if(StringUtils.isNotBlank(datasource.select(0, c).asString())) { return c; } } } catch(MissingDataException e) { throw new RuntimeException(e); } return 0; } } private boolean startsWith(Value v, String prefix) { return StringUtils.startsWithIgnoreCase(StringUtils.strip(v.asString()), prefix); } private boolean matchesRegion(SpreadsheetDataSource ds, Region region) { try { String cmp = region.getProperName() + (region == Region.GBR?" total":" region"); int fc = findFirstColumn(ds); List<Value> col0 = ds.selectColumn(fc, 20); for(Value v : col0) { if(StringUtils.equalsIgnoreCase( StringUtils.strip(v.asString()), cmp)) { return true; } } return false; } catch(MissingDataException e) { throw new RuntimeException(e); } } @Override protected ADCDataset createDataset(Context ctx) { SpreadsheetDataSource ds = ctx.datasource(); if(canHandle(ds) && matchesRegion(ds, ctx.region())) { try { ADCDataset d = new ADCDataset(); int fc = findFirstColumn(ds); for(int col=1;col<5;col++) { String series = ds.select(0, fc+col).asString(); for(int row = 1;StringUtils.isNotBlank(ds.select(row, fc).asString());row++) { String region = ds.select(row, fc).asString(); Double val = ds.select(row, fc+col).asDouble(); d.addValue(val, series, region); } } return d; } catch(MissingDataException e) { throw new RuntimeException(e); } } else { return null; } } @Override protected Drawable getDrawable(JFreeContext ctx) { return WetlandLoss.createChart((ADCDataset)ctx.dataset(), new Dimension(750, 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 { csv.writeHeader((ctx.region() == Region.GBR?"Region":"Catchment"), (String)dataset.getRowKey(0), (String)dataset.getRowKey(1), (String)dataset.getRowKey(2), (String)dataset.getRowKey(3)); DecimalFormat f = new DecimalFormat(".##"); for(int cat=0;cat<dataset.getColumnCount();cat++) { csv.write(dataset.getColumnKey(cat), f.format(dataset.getValue(0, cat)), f.format(dataset.getValue(1, cat)), f.format(dataset.getValue(2, cat)), f.format(dataset.getValue(3, cat))); } }}); } @Override public AttributeMap defaults(ChartType type) { return new AttributeMap.Builder(). put(Attribute.TITLE, TITLE+"\n${region}"). put(Attribute.X_AXIS_LABEL, "${catchment}"). put(Attribute.Y_AXIS_LABEL, WETLANDS_LOSS). put(Attribute.SERIES_COLORS, new Color[] {Colors.RED, Colors.LIGHT_RED, Colors.BLUE, Colors.LIGHT_BLUE}). build(); } @Override public Set<SubstitutionKey> substitutionKeys() { return ImmutableSet.<SubstitutionKey>builder(). addAll(super.substitutionKeys()).add(SubstitutionKeys.CATCHMENT).build(); } }