Similar to savechartasimage-generate-infinite-loop-process-t10740.html, but with PIE !
When I use saveChartAsImage(), the generation (cf file as an attachment) is falling into infinite process.
It seems that this function is REALLY INSTABLE, depending data used...
Here code used to create Chart
- Code: Select all
public BufferedImage createChart(Workbook workbook, ChartData data, Double width, Double height) throws Exception {
if (workbook == null) {
workbook = new Workbook();
}
final Worksheet sheet = workbook.createEmptySheet();
this.addChartToWorksheet(sheet, data, width, height);
workbook.saveToFile(UUID.randomUUID() + "_" + data.getType().name() + ".xlsx");
return workbook.saveChartAsImage(sheet, 0);
}
protected void addChartToWorksheet(Worksheet sheet, ChartData data, Double width, Double height) throws Exception {
final Chart chart = sheet.getCharts().add(formatExcelChartType(data.getType()));
final DataTable dataTable = createChartDataTable(data);
sheet.insertDataTable(dataTable, true, 1, 1);
chart.getPlotArea().getFill().setVisible(false);
final CellRange cellDataRange =
sheet.getCellRange(1, 1, dataTable.getRows().size() + 1, dataTable.getColumns().size());
chart.getPrimaryCategoryAxis().setCategoryLabels(
sheet.getCellRange(1, data.getLegends() != null ? 2 : 1, 1, dataTable.getColumns().size()));
//Set region of chart data
chart.setDataRange(cellDataRange);
chart.setSeriesDataFromRange(true);
//Set position of chart
chart.setLeft(1);
chart.setTopRow(6);
chart.setWidth((int) Math.round(width == null ? data.getW() : width));
chart.setHeight((int) Math.round(height == null ? data.getH() : height));
//Chart title
chart.setChartTitle(data.getTitle());
chart.getChartTitleArea().isBold(true);
chart.getChartTitleArea().setSize(10);
chart.setWallsAndGridlines2D(true);
// Text gray
final Color textColor = new Color(89, 89, 89);
chart.getPrimaryValueAxis().getBorder().setCustomLineWeight(0);
chart.getPrimaryValueAxis().getBorder().setColor(Color.WHITE);
chart.getPrimaryValueAxis().getFont().setColor(textColor);
//chart.getPrimaryValueAxis().setAutoTickLabelSpacing(true);
//chart.getPrimaryValueAxis().setAutoTickMarkSpacing(true);
chart.getPrimaryValueAxis().getMajorGridLines().getBorder().setColor(new Color(217, 217, 217));
chart.getPrimaryCategoryAxis().getFont().setColor(textColor);
chart.getPrimaryCategoryAxis().getBorder().setCustomLineWeight(0);
chart.getPrimaryCategoryAxis().getBorder().setColor(Color.WHITE);
// Border
chart.getChartArea().getBorder().setCustomLineWeight(0);
chart.getChartArea().getBorder().setColor(new Color(255, 255, 255));
if (data.getType() != ChartTypeEnum.PIE) {
chart.hasLegend(data.getLegends() != null);
chart.getLegend().setPosition(LegendPositionType.Bottom);
} else {
chart.hasLegend(true);
chart.getLegend().setPosition(LegendPositionType.Right);
}
//Draw chart with data
final AtomicInteger iSerie = new AtomicInteger();
chart.getSeries().forEach(cs -> {
final ChartSerie s = (ChartSerie) cs;
final fr.exceliances.easy.service.generation.model.ChartSerie sourceSerie =
data.getSeries().get(iSerie.getAndIncrement());
final Color color = sourceSerie.getColor();
s.getDataPoints().getDefaultDataPoint().getDataLabels().hasValue(sourceSerie.isShowDataLabels());
s.getFormat().getFormat3D().setBevelTopType(XLSXChartBevelType.SoftRound);
s.getFormat().getFormat3D().setBevelTopWidth(12);
s.getFormat().getFormat3D().setBevelTopHeight(4);
if (sourceSerie.getNumberFormat() != null) {
s.getValues().setNumberFormat(sourceSerie.getNumberFormat());
} else {
s.getValues().setNumberFormat("# ##0;-# ##0");
}
if (sourceSerie.getType() != null) {
s.setSerieType(sourceSerie.getType());
}
if (sourceSerie.isSecondaryAxis()) {
s.setUsePrimaryAxis(false);
}
if (data.getType() != ChartTypeEnum.PIE) {
s.getFormat().setForeGroundColor(color == null ? CHART_COLORS[iSerie.get() - 1] : color);
s.getFormat().getOptions().setOverlap(-10);
}
if (data.getType() == ChartTypeEnum.BAR_TREND || data.getType() == ChartTypeEnum.BAR) {
s.getDataLabels().setTextRotationAngle(-45);
}
if (data.getType() == ChartTypeEnum.BAR_TREND) {
final IChartTrendLine chartTrendLine = s.getTrendLines().add(TrendLineType.Linear);
chartTrendLine.getBorder().setWeight(ChartLineWeightType.Narrow);
chartTrendLine.getBorder().setColor(new Color(110, 100, 112));
}
for (int i = 0; i < s.getPointNumber(); i++) {
final ChartDataPoint dp = chart.getSeries().get(0).getDataPoints().get(i++);
dp.getDataLabels().setPosition(DataLabelPositionType.Automatic);
}
});
if (chart.getSeries().size() == 1) {
final ChartSerie chartSerie = chart.getSeries().get(0);
final fr.exceliances.easy.service.generation.model.ChartSerie sourceSerie = data.getSeries().get(0);
for (int i = 0; i < chartSerie.getPointNumber(); i++) {
final ChartDataPoint dp = chartSerie.getDataPoints().get(i);
final ChartValue<?> chartValue = sourceSerie.getValues().get(i);
dp.getDataLabels().getFormat().setBackGroundColor(new Color(40, 40, 40));
dp.getDataLabels().setColor(Color.DARK_GRAY);
dp.getDataFormat().getFormat3D().setBevelTopType(XLSXChartBevelType.SoftRound);
dp.getDataFormat().getFormat3D().setBevelTopWidth(12);
dp.getDataFormat().getFormat3D().setBevelTopHeight(4);
dp.getDataFormat()
.setForeGroundColor(chartValue.getColor() == null ? CHART_COLORS[i] : chartValue.getColor());
}
}
}
protected DataTable createChartDataTable(ChartData chartData) throws Exception {
final DataTable dataTable = new DataTable();
final DataRowCollection rows = new DataRowCollection(dataTable);
if (chartData.getLegends() != null) {
final DataColumn col = new DataColumn();
col.setColumnName("");
dataTable.getColumns().add(new DataColumn());
}
chartData.getLabels().forEach(l -> {
final DataColumn col = new DataColumn();
col.setColumnName(l);
dataTable.getColumns().add(col);
});
final AtomicInteger iSerie = new AtomicInteger();
for (fr.exceliances.easy.service.generation.model.ChartSerie cs : chartData.getSeries()) {
final DataRow rowValue = dataTable.newRow();
final AtomicInteger cellIndx = new AtomicInteger(0);
if (chartData.getLegends() != null) {
rowValue.setObject(cellIndx.getAndIncrement(), chartData.getLegends().get(iSerie.getAndIncrement()));
}
cs.getValues().forEach(cv -> {
rowValue.setObject(cellIndx.getAndIncrement(), cv.getValue());
});
rows.add(rowValue);
}
dataTable.setRows(rows);
return dataTable;
}
protected ExcelChartType formatExcelChartType(ChartTypeEnum type) {
switch (type) {
case PIE:
return ExcelChartType.PieExploded;
case LINE:
return ExcelChartType.LineMarkers;
case BAR:
case BAR_TREND:
return ExcelChartType.ColumnClustered;
default:
return ExcelChartType.Bar100PercentStacked;
}
}
And implementation to ChartData
- Code: Select all
final ChartData data = new ChartData(200, 250, 450, 250);
final List<String> labels = new ArrayList<>();
labels.add("SCI IR");
labels.add("SCI IS");
data.setLabels(labels);
final List<String> legends = new ArrayList<>();
legends.add("Flux de trésorerie nets sur la période (associé)");
legends.add("VAN");
data.setLegends(legends);
final List<ChartSerie> series = new ArrayList<>();
ChartSerie serie = new ChartSerie(Arrays.asList(new ChartValue<>(0.5264056893501265), new ChartValue<>(0.47359431064987345)));
serie.setNumberFormat("0.00%");
series.add(serie);
data.setSeries(series);
data.setType(ChartTypeEnum.PIE);
return data;
Please notice that the same code with other values like 0.6704920032171723 and 0.32950799678282766 is working well...
P.S : Custom classes are in attachment.