package com.vaadin.addon.spreadsheet.charts.converter.xssfreader;
/*
* #%L
* Vaadin Spreadsheet Charts Integration
* %%
* Copyright (C) 2016 Vaadin Ltd
* %%
* This program is available under Commercial Vaadin Add-On License 3.0
* (CVALv3).
*
* See the file license.html distributed with this software for more
* information about licensing.
*
* You should have received a copy of the CVALv3 along with this program.
* If not, see <http://vaadin.com/license/cval-3>.
* #L%
*/
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.xssf.usermodel.XSSFChart;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAreaChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTBar3DChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTBubbleChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTDoughnutChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTLineChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPie3DChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTRadarChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTUnsignedInt;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTView3D;
import org.openxmlformats.schemas.drawingml.x2006.chart.STDispBlanksAs;
import org.openxmlformats.schemas.drawingml.x2006.chart.STLegendPos;
import com.vaadin.addon.spreadsheet.Spreadsheet;
import com.vaadin.addon.spreadsheet.charts.converter.Utils;
import com.vaadin.addon.spreadsheet.charts.converter.chartdata.AbstractSeriesData;
import com.vaadin.addon.spreadsheet.charts.converter.chartdata.ChartData;
import com.vaadin.addon.spreadsheet.charts.converter.chartdata.ChartData.AxisProperties;
import com.vaadin.addon.spreadsheet.charts.converter.chartdata.ChartData.LegendPosition;
import com.vaadin.addon.spreadsheet.charts.converter.chartdata.ChartData.LegendProperties;
@SuppressWarnings("serial")
public class XSSFChartReader {
private final XSSFChart xssfChart;
private final Spreadsheet spreadsheet;
private final ChartStylesReader stylesReader;
private LinkedHashMap<Long, AxisProperties> yAxes;
public XSSFChartReader(Spreadsheet spreadsheet, XSSFChart xssfChart) {
this.spreadsheet = spreadsheet;
this.xssfChart = xssfChart;
stylesReader = new ChartStylesReader(spreadsheet, xssfChart);
}
public ChartData readXSSFChart() {
ChartData chartData = new ChartData();
final CTPlotArea plotArea = xssfChart.getCTChart().getPlotArea();
yAxes = stylesReader.getYAxisProperties();
chartData.plotData = readPlotData(plotArea);
chartData.title = getTitle(xssfChart, chartData.plotData);
// read these parameters to
final CTView3D view3d = xssfChart.getCTChart().getView3D();
if (view3d != null) {
chartData.view3dData = new ChartData.View3dData();
if (view3d.getRotX() != null) {
chartData.view3dData.rotation3dAngleA = view3d.getRotX()
.getVal();
}
if (view3d.getRotY() != null) {
chartData.view3dData.rotation3dAngleB = view3d.getRotY()
.getVal();
}
}
chartData.legendProperties = getLegendProperties();
chartData.borderStyle = stylesReader.getBorderStyle();
chartData.background = stylesReader.getBackgroundProperties();
chartData.titleStyle = stylesReader.getTitleProperties();
chartData.xAxisProperties = stylesReader.getXAxisProperties();
// values() of LinkedHashMap guarantees the order of items
chartData.yAxesProperties = new ArrayList<AxisProperties>(
yAxes.values());
chartData.blanksAsZeros = getDisplayBlanksAs();
return chartData;
}
private boolean getDisplayBlanksAs() {
try {
STDispBlanksAs.Enum blanksAs = xssfChart.getCTChart()
.getDispBlanksAs().getVal();
return blanksAs == STDispBlanksAs.ZERO;
} catch (NullPointerException e) {
return false;
}
}
private LegendProperties getLegendProperties() {
LegendProperties result = new LegendProperties();
result.position = getLegendPosition();
result.textProperties = stylesReader.getLegendTextProperties();
return result;
}
private LegendPosition getLegendPosition() {
Map<STLegendPos.Enum, LegendPosition> translationMap = new HashMap<STLegendPos.Enum, LegendPosition>() {
{
put(STLegendPos.B, LegendPosition.BOTTOM);
put(STLegendPos.L, LegendPosition.LEFT);
put(STLegendPos.T, LegendPosition.TOP);
put(STLegendPos.TR, LegendPosition.TOP_RIGHT);
put(STLegendPos.R, LegendPosition.RIGHT);
}
};
try {
STLegendPos.Enum legendPos = xssfChart.getCTChart().getLegend()
.getLegendPos().getVal();
return translationMap.get(legendPos);
} catch (NullPointerException e) {
return LegendPosition.NONE;
}
}
private List<AbstractSeriesData> readPlotData(CTPlotArea plotArea) {
boolean showDataInHiddenCells = getShowDataInHiddenCells();
ArrayList<AbstractSeriesData> list = new ArrayList<AbstractSeriesData>();
for (CTBarChart ctChart : plotArea.getBarChartList()) {
list.addAll(addYAxis(new BarSeriesReader(ctChart, spreadsheet,
showDataInHiddenCells).getSeries(), getAxIdList(ctChart)));
}
for (CTBar3DChart ctChart : plotArea.getBar3DChartList()) {
list.addAll(addYAxis(new BarSeriesReader(ctChart, spreadsheet,
showDataInHiddenCells).getSeries(), getAxIdList(ctChart)));
}
for (CTPieChart ctChart : plotArea.getPieChartList()) {
list.addAll(new PieSeriesReader(ctChart, spreadsheet,
showDataInHiddenCells).getSeries());
}
for (CTPie3DChart ctChart : plotArea.getPie3DChartList()) {
list.addAll(new PieSeriesReader(ctChart, spreadsheet,
showDataInHiddenCells).getSeries());
}
for (CTAreaChart ctChart : plotArea.getAreaChartList()) {
list.addAll(addYAxis(new AreaSeriesReader(ctChart, spreadsheet,
showDataInHiddenCells).getSeries(), getAxIdList(ctChart)));
}
for (CTBubbleChart ctChart : plotArea.getBubbleChartList()) {
list.addAll(addYAxis(new BubbleSeriesReader(ctChart, spreadsheet,
showDataInHiddenCells).getSeries(), getAxIdList(ctChart)));
}
for (CTLineChart ctChart : plotArea.getLineChartList()) {
list.addAll(addYAxis(new LineSeriesReader(ctChart, spreadsheet,
showDataInHiddenCells).getSeries(), getAxIdList(ctChart)));
}
for (CTRadarChart ctChart : plotArea.getRadarChartList()) {
list.addAll(addYAxis(new RadarSeriesReader(ctChart, spreadsheet,
showDataInHiddenCells).getSeries(), getAxIdList(ctChart)));
}
for (CTScatterChart ctChart : plotArea.getScatterChartList()) {
list.addAll(addYAxis(new ScatterSeriesReader(ctChart, spreadsheet,
showDataInHiddenCells).getSeries(), getAxIdList(ctChart)));
}
for (CTDoughnutChart ctChart : plotArea.getDoughnutChartList()) {
list.addAll(new PieSeriesReader(ctChart, spreadsheet,
showDataInHiddenCells).getSeries());
}
return list;
}
private boolean getShowDataInHiddenCells() {
try {
return !xssfChart.getCTChart().getPlotVisOnly().getVal();
} catch (NullPointerException e) {
return false;
}
}
private Collection<? extends AbstractSeriesData> addYAxis(
Collection<? extends AbstractSeriesData> seriesList,
List<CTUnsignedInt> axIdList) {
// keySet() of LinkedHashMap guarantees the order of items
final List<Long> axisIds = new ArrayList<Long>(yAxes.keySet());
for (Long axisId : axisIds) {
for (CTUnsignedInt id : axIdList) {
if (id.getVal() == axisId) {
for (AbstractSeriesData series : seriesList) {
series.yAxis = axisIds.indexOf(axisId);
}
break;
}
}
}
return seriesList;
}
@SuppressWarnings("unchecked")
private List<CTUnsignedInt> getAxIdList(XmlObject ctChart) {
return (List<CTUnsignedInt>) Utils.callMethodUsingReflection(ctChart,
"getAxIdList");
}
private String getTitle(XSSFChart chart, List<AbstractSeriesData> plotData) {
String title = "";
final CTChart ctChart = chart.getCTChart();
if (ctChart.isSetTitle()) {
title = "" + chart.getTitle();
// default title
if (title.isEmpty() && plotData.size() > 0
&& plotData.get(0).name != null) {
title = plotData.get(0).name;
}
}
return title;
}
}