19 package org.sleuthkit.autopsy.report.modules.datasourcesummaryexport;
 
   21 import java.lang.reflect.Constructor;
 
   22 import java.lang.reflect.InvocationTargetException;
 
   23 import java.util.Arrays;
 
   24 import java.util.List;
 
   25 import org.apache.poi.ss.usermodel.Sheet;
 
   26 import org.apache.poi.ss.util.CellRangeAddress;
 
   27 import org.apache.poi.xddf.usermodel.chart.ChartTypes;
 
   28 import org.apache.poi.xddf.usermodel.chart.LegendPosition;
 
   29 import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
 
   30 import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
 
   31 import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
 
   32 import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
 
   33 import org.apache.poi.xddf.usermodel.chart.XDDFPieChartData;
 
   34 import org.apache.poi.xssf.usermodel.XSSFChart;
 
   35 import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
 
   36 import org.apache.poi.xssf.usermodel.XSSFDrawing;
 
   37 import org.apache.poi.xssf.usermodel.XSSFSheet;
 
   38 import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieChart;
 
   49 class PieChartExport 
implements ExcelItemExportable, ExcelSheetExport {
 
   51     private static final int DEFAULT_ROW_SIZE = 20;
 
   52     private static final int DEFAULT_COL_SIZE = 10;
 
   53     private static final int DEFAULT_ROW_PADDING = 1;
 
   54     private static final int DEFAULT_COL_OFFSET = 1;
 
   56     private final ExcelTableExport<PieChartItem, ? extends CellModel> tableExport;
 
   57     private final int colOffset;
 
   58     private final int rowPadding;
 
   59     private final int colSize;
 
   60     private final int rowSize;
 
   61     private final String chartTitle;
 
   62     private final String sheetName;
 
   74     PieChartExport(String keyColumnHeader,
 
   75             String valueColumnHeader, String valueFormatString,
 
   77             List<PieChartItem> slices) {
 
   78         this(keyColumnHeader, valueColumnHeader, valueFormatString, chartTitle, chartTitle, slices,
 
   79                 DEFAULT_COL_OFFSET, DEFAULT_ROW_PADDING, DEFAULT_COL_SIZE, DEFAULT_ROW_SIZE);
 
   98     PieChartExport(String keyColumnHeader,
 
   99             String valueColumnHeader, String valueFormatString,
 
  100             String chartTitle, String sheetName,
 
  101             List<PieChartItem> slices,
 
  102             int colOffset, 
int rowPadding, 
int colSize, 
int rowSize) {
 
  104         this.tableExport = 
new ExcelTableExport<>(chartTitle,
 
  106                         new ColumnModel<>(keyColumnHeader, (slice) -> 
new DefaultCellModel<>(slice.getLabel())),
 
  107                         new ColumnModel<>(valueColumnHeader, (slice) -> 
new DefaultCellModel<>(slice.getValue(), null, valueFormatString))
 
  110         this.colOffset = colOffset;
 
  111         this.rowPadding = rowPadding;
 
  112         this.colSize = colSize;
 
  113         this.rowSize = rowSize;
 
  114         this.chartTitle = chartTitle;
 
  115         this.sheetName = sheetName;
 
  119     public String getSheetName() {
 
  124     public void renderSheet(Sheet sheet, ExcelExport.WorksheetEnv env) throws ExcelExport.ExcelExportException {
 
  125         write(sheet, 0, 0, env);
 
  129     public ItemDimensions write(Sheet sheet, 
int rowStart, 
int colStart, ExcelExport.WorksheetEnv env) throws ExcelExportException {
 
  130         if (!(sheet instanceof XSSFSheet)) {
 
  131             throw new ExcelExportException(
"Sheet must be an XSSFSheet in order to write.");
 
  134         XSSFSheet xssfSheet = (XSSFSheet) sheet;
 
  137         ItemDimensions tableDimensions = tableExport.write(xssfSheet, rowStart + rowPadding, colStart, env);
 
  139         XSSFDrawing drawing = xssfSheet.createDrawingPatriarch();
 
  141         int chartColStart = colStart + 2 + colOffset;
 
  144         XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, chartColStart, rowStart + rowPadding, chartColStart + colSize + 1, rowStart + rowSize + 1);
 
  146         XSSFChart chart = drawing.createChart(anchor);
 
  147         chart.setTitleText(chartTitle);
 
  148         chart.setTitleOverlay(
false);
 
  149         XDDFChartLegend legend = chart.getOrAddLegend();
 
  150         legend.setPosition(LegendPosition.RIGHT);
 
  153         XDDFDataSource<String> cat = XDDFDataSourcesFactory.fromStringCellRange(xssfSheet,
 
  154                 new CellRangeAddress(tableDimensions.getRowStart() + 1, tableDimensions.getRowEnd(),
 
  155                         tableDimensions.getColStart(), tableDimensions.getColStart()));
 
  157         XDDFNumericalDataSource<Double> val = XDDFDataSourcesFactory.fromNumericCellRange(xssfSheet,
 
  158                 new CellRangeAddress(tableDimensions.getRowStart() + 1, tableDimensions.getRowEnd(),
 
  159                         tableDimensions.getColStart() + 1, tableDimensions.getColStart() + 1));
 
  161         XDDFPieChartData data = (XDDFPieChartData) chart.createData(ChartTypes.PIE, null, null);
 
  162         data.setVaryColors(
true);
 
  163         data.addSeries(cat, val);
 
  166         if (!chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).isSetDLbls()) {
 
  167             chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).addNewDLbls();
 
  170         chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().addNewShowVal().setVal(
true);
 
  171         chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().addNewShowSerName().setVal(
false);
 
  172         chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().addNewShowCatName().setVal(
true);
 
  173         chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().addNewShowPercent().setVal(
true);
 
  174         chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().addNewShowLegendKey().setVal(
false);
 
  178         return new ItemDimensions(rowStart, colStart, Math.max(tableDimensions.getRowEnd(), rowStart + rowSize) + rowPadding, chartColStart + colSize);