Home > Mobile >  Manipulate bars from a chart
Manipulate bars from a chart

Time:07-27

I need to change the first and the last bars. As you can see, both bars are halfed due the limits of the chart.
Which class from Apache POI librar should I use to change that?enter image description here

This is the code which is drawing the chart

private ByteArrayInputStream generateFileDetails(List<ClientDataRequest> clientDataRequest, String metricName){

        ByteArrayOutputStream file = new ByteArrayOutputStream();

        try{
            try(XSSFWorkbook workbook = new XSSFWorkbook()){
                XSSFSheet sheet = workbook.createSheet(metricName);
                Font headerFont = workbook.createFont();
                headerFont.setBold(true);
                headerFont.setUnderline(Font.U_SINGLE);
                CellStyle headerCellStyle = workbook.createCellStyle();
                headerCellStyle.setFillBackgroundColor(IndexedColors.GREY_40_PERCENT.getIndex());
                headerCellStyle.setFont(headerFont);

                XSSFDrawing drawing = sheet.createDrawingPatriarch();
                XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 5, 1, 14, 10  clientDataRequest.size());

                Row headerRow = sheet.createRow(anchor.getRow2() 1);
                headerRow.createCell(0).setCellValue("Client Name");
                headerRow.createCell(1).setCellValue("Value");

                for (int i = 0; i < headerRow.getLastCellNum(); i  ) {
                    headerRow.getCell(i).setCellStyle(headerCellStyle);
                }

                for (int i = 0; i < clientDataRequest.size(); i  ) {
                    Row row = sheet.createRow(anchor.getRow2() 2 i);
                    row.createCell(0).setCellValue(clientDataRequest.get(i).getClientName());
                    sheet.autoSizeColumn(0);
                    row.createCell(1).setCellValue(clientDataRequest.get(i).getValue());
                    sheet.autoSizeColumn(1);
                }

                XSSFChart chart = drawing.createChart(anchor);
                chart.setTitleText(metricName);
                chart.setTitleOverlay(false);

                //XDDFChartLegend legend = chart.getOrAddLegend();
                //legend.setPosition(LegendPosition.TOP_RIGHT);

                XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
                bottomAxis.setTitle("Client Name");
                XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
                leftAxis.setTitle("Value");
                leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);

                XDDFDataSource<String> clientNames = XDDFDataSourcesFactory.fromStringCellRange(sheet,
                        new CellRangeAddress(anchor.getRow2() 2, anchor.getRow2() 1 clientDataRequest.size(), 0, 0));

                XDDFNumericalDataSource<Double> values = XDDFDataSourcesFactory.fromNumericCellRange(sheet,
                        new CellRangeAddress(anchor.getRow2() 2, anchor.getRow2() 1 clientDataRequest.size(), 1, 1));

                XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
                XDDFChartData.Series series = data.addSeries(clientNames, values);
                XDDFLineProperties line = new XDDFLineProperties();
                series.setTitle(null, null);
                data.setVaryColors(false);
                chart.plot(data);

                XDDFBarChartData bar = (XDDFBarChartData) data;
                bar.setBarDirection(BarDirection.BAR);

                workbook.write(file);
            }
        } catch (Exception e){

        }

        return new ByteArrayInputStream(file.toByteArray());

    }

It does not have many documentation and samples about the Apache POI.

CodePudding user response:

For a bar chart you additional need set AxisCrossBetween for the value axis, so the value axis crosses the category axis between the categories. Else first and last category is exactly on cross points and the bars are only half visible.

In your case:

...
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.setTitle("Value");
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);

leftAxis.setCrossBetween(org.apache.poi.xddf.usermodel.chart.AxisCrossBetween.BETWEEN);
...
  • Related