/* * ==================================================================== * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ==================================================================== */ package org.apache.poi.xslf.usermodel; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; import java.util.List; import org.apache.poi.ooxml.POIXMLDocumentPart; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xddf.usermodel.chart.AxisCrossBetween; import org.apache.poi.xddf.usermodel.chart.AxisCrosses; import org.apache.poi.xddf.usermodel.chart.AxisOrientation; import org.apache.poi.xddf.usermodel.chart.AxisPosition; import org.apache.poi.xddf.usermodel.chart.AxisTickMark; import org.apache.poi.xddf.usermodel.chart.BarDirection; import org.apache.poi.xddf.usermodel.chart.BarGrouping; import org.apache.poi.xddf.usermodel.chart.Grouping; import org.apache.poi.xddf.usermodel.chart.LayoutMode; import org.apache.poi.xddf.usermodel.chart.LayoutTarget; import org.apache.poi.xddf.usermodel.chart.LegendPosition; import org.apache.poi.xddf.usermodel.chart.RadarStyle; import org.apache.poi.xddf.usermodel.chart.ScatterStyle; import org.apache.poi.xddf.usermodel.chart.XDDFBarChartData; import org.apache.poi.xddf.usermodel.chart.XDDFChartData; import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend; import org.apache.poi.xddf.usermodel.chart.XDDFDataSource; import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory; import org.apache.poi.xddf.usermodel.chart.XDDFLineChartData; import org.apache.poi.xddf.usermodel.chart.XDDFManualLayout; import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource; import org.apache.poi.xddf.usermodel.chart.XDDFPieChartData; import org.apache.poi.xddf.usermodel.chart.XDDFRadarChartData; import org.apache.poi.xddf.usermodel.chart.XDDFScatterChartData; import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis; import org.apache.poi.xslf.XSLFTestDataSamples; import org.junit.jupiter.api.Test; /** * a modified version from POI-examples */ class TestXSLFChart { @Test void testFillPieChartTemplate() throws IOException { XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument("pie-chart.pptx"); XSLFChart chart = findChart(pptx.getSlides().get(0)); List data = findChartData(chart); XDDFPieChartData pie = (XDDFPieChartData) data.get(0); XDDFPieChartData.Series firstSeries = (XDDFPieChartData.Series) pie.getSeries(0); firstSeries.setExplosion(25L); assertEquals(Long.valueOf(25), firstSeries.getExplosion()); fillChartData(chart, pie); pptx.close(); } @Test void testFillBarChartTemplate() throws IOException { XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument("bar-chart.pptx"); XSLFSlide slide = pptx.getSlides().get(0); // duplicate slide and chart before applying "destructive" tests to it XSLFChart chart2 = findChart(pptx.createSlide().importContent(slide)); XSLFChart chart = findChart(slide); List data = findChartData(chart); XDDFBarChartData bar = (XDDFBarChartData) data.get(0); assertEquals(BarDirection.BAR, bar.getBarDirection()); assertEquals(BarGrouping.CLUSTERED, bar.getBarGrouping()); assertEquals(Integer.valueOf(100), bar.getGapWidth()); fillChartData(chart, bar); XDDFBarChartData column = (XDDFBarChartData) findChartData(chart2).get(0); column.setBarDirection(BarDirection.COL); assertEquals(BarDirection.COL, column.getBarDirection()); column.getCategoryAxis().setOrientation(AxisOrientation.MIN_MAX); column.getValueAxes().get(0).setPosition(AxisPosition.BOTTOM); fillChartData(chart2, column); pptx.close(); } @Test void testFillLineChartTemplate() throws IOException { XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument("line-chart.pptx"); XSLFChart chart = findChart(pptx.getSlides().get(0)); List data = findChartData(chart); XDDFLineChartData line = (XDDFLineChartData) data.get(0); assertEquals(Grouping.STANDARD, line.getGrouping()); line.setGrouping(Grouping.PERCENT_STACKED); assertEquals(Grouping.PERCENT_STACKED, line.getGrouping()); fillChartData(chart, line); pptx.close(); } @Test void testFillRadarChartTemplate() throws IOException { XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument("radar-chart.pptx"); XSLFChart chart = findChart(pptx.getSlides().get(0)); List data = findChartData(chart); XDDFRadarChartData radar = (XDDFRadarChartData) data.get(0); assertEquals(RadarStyle.MARKER, radar.getStyle()); radar.setStyle(RadarStyle.FILLED); assertEquals(RadarStyle.FILLED, radar.getStyle()); fillChartData(chart, radar); pptx.close(); } @Test void testFillScatterChartTemplate() throws IOException { XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument("scatter-chart.pptx"); XSLFChart chart = findChart(pptx.getSlides().get(0)); List data = findChartData(chart); XDDFScatterChartData scatter = (XDDFScatterChartData) data.get(0); assertEquals(ScatterStyle.LINE_MARKER, scatter.getStyle()); scatter.setStyle(ScatterStyle.SMOOTH); assertEquals(ScatterStyle.SMOOTH, scatter.getStyle()); fillChartData(chart, scatter); pptx.close(); } private void fillChartData(XSLFChart chart, XDDFChartData data) { final int numOfPoints = 3; final String[] categories = {"First", "Second", "Third"}; final Integer[] values = {1, 3, 4}; final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0)); final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 1, 1)); final XDDFChartData.Series series = data.getSeries(0); final XDDFDataSource categoryData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange); final XDDFNumericalDataSource valuesData = XDDFDataSourcesFactory.fromArray(values, valuesDataRange); series.replaceData(categoryData, valuesData); final String title = "Apache POI"; series.setTitle(title, chart.setSheetTitle(title, 0)); chart.plot(data); } private XSLFChart findChart(XSLFSlide slide) { // find chart in the slide XSLFChart chart = null; for(POIXMLDocumentPart part : slide.getRelations()){ if(part instanceof XSLFChart){ chart = (XSLFChart) part; break; } } if(chart == null) { throw new IllegalStateException("chart not found in the template"); } checkLegendOperations(chart); return chart; } private List findChartData(XSLFChart chart) { List data = chart.getChartSeries(); assertNotNull(data); assertEquals(1, data.size()); XDDFChartData firstSeries = data.get(0); assertNotNull(firstSeries); if (firstSeries instanceof XDDFScatterChartData) { assertNull(firstSeries.getCategoryAxis()); assertEquals(2, firstSeries.getValueAxes().size()); checkAxisOperations(firstSeries.getValueAxes().get(0)); checkAxisOperations(firstSeries.getValueAxes().get(1)); } else if (!(firstSeries instanceof XDDFPieChartData)) { assertNotNull(firstSeries.getCategoryAxis()); assertEquals(1, firstSeries.getValueAxes().size()); checkAxisOperations(firstSeries.getValueAxes().get(0)); } return data; } private void checkLegendOperations(XSLFChart chart) { XDDFChartLegend legend = chart.getOrAddLegend(); assertFalse(legend.isOverlay()); legend.setOverlay(true); assertTrue(legend.isOverlay()); legend.setPosition(LegendPosition.TOP_RIGHT); assertEquals(LegendPosition.TOP_RIGHT, legend.getPosition()); XDDFManualLayout layout = legend.getOrAddManualLayout(); assertNotNull(layout.getTarget()); assertNotNull(layout.getXMode()); assertNotNull(layout.getYMode()); assertNotNull(layout.getHeightMode()); assertNotNull(layout.getWidthMode()); /* * According to interface, 0.0 should be returned for * uninitialized double properties. */ assertEquals(0.0, layout.getX(), 0.0); assertEquals(0.0, layout.getY(), 0.0); assertEquals(0.0, layout.getWidthRatio(), 0.0); assertEquals(0.0, layout.getHeightRatio(), 0.0); final double newRatio = 1.1; final double newCoordinate = 0.3; final LayoutMode nonDefaultMode = LayoutMode.FACTOR; final LayoutTarget nonDefaultTarget = LayoutTarget.OUTER; layout.setWidthRatio(newRatio); assertEquals(layout.getWidthRatio(), newRatio, 0.0); layout.setHeightRatio(newRatio); assertEquals(layout.getHeightRatio(), newRatio, 0.0); layout.setX(newCoordinate); assertEquals(layout.getX(), newCoordinate, 0.0); layout.setY(newCoordinate); assertEquals(layout.getY(), newCoordinate, 0.0); layout.setXMode(nonDefaultMode); assertSame(layout.getXMode(), nonDefaultMode); layout.setYMode(nonDefaultMode); assertSame(layout.getYMode(), nonDefaultMode); layout.setWidthMode(nonDefaultMode); assertSame(layout.getWidthMode(), nonDefaultMode); layout.setHeightMode(nonDefaultMode); assertSame(layout.getHeightMode(), nonDefaultMode); layout.setTarget(nonDefaultTarget); assertSame(layout.getTarget(), nonDefaultTarget); } private void checkAxisOperations(XDDFValueAxis axis) { axis.setCrossBetween(AxisCrossBetween.MIDPOINT_CATEGORY); assertEquals(AxisCrossBetween.MIDPOINT_CATEGORY, axis.getCrossBetween()); axis.setCrosses(AxisCrosses.AUTO_ZERO); assertEquals(AxisCrosses.AUTO_ZERO, axis.getCrosses()); final String numberFormat = "General"; axis.setNumberFormat(numberFormat); assertEquals(numberFormat, axis.getNumberFormat()); axis.setPosition(AxisPosition.BOTTOM); assertEquals(AxisPosition.BOTTOM, axis.getPosition()); axis.setMajorTickMark(AxisTickMark.NONE); assertEquals(AxisTickMark.NONE, axis.getMajorTickMark()); axis.setMajorTickMark(AxisTickMark.IN); assertEquals(AxisTickMark.IN, axis.getMajorTickMark()); axis.setMajorTickMark(AxisTickMark.OUT); assertEquals(AxisTickMark.OUT, axis.getMajorTickMark()); axis.setMajorTickMark(AxisTickMark.CROSS); assertEquals(AxisTickMark.CROSS, axis.getMajorTickMark()); axis.setMinorTickMark(AxisTickMark.NONE); assertEquals(AxisTickMark.NONE, axis.getMinorTickMark()); axis.setMinorTickMark(AxisTickMark.IN); assertEquals(AxisTickMark.IN, axis.getMinorTickMark()); axis.setMinorTickMark(AxisTickMark.OUT); assertEquals(AxisTickMark.OUT, axis.getMinorTickMark()); axis.setMinorTickMark(AxisTickMark.CROSS); assertEquals(AxisTickMark.CROSS, axis.getMinorTickMark()); axis.setVisible(true); assertTrue(axis.isVisible()); axis.setVisible(false); assertFalse(axis.isVisible()); final double EPSILON = 1E-7; axis.setLogBase(Math.E); assertTrue(Math.abs(axis.getLogBase() - Math.E) < EPSILON); final double newValue = 10.0; axis.setMinimum(newValue); assertTrue(Math.abs(axis.getMinimum() - newValue) < EPSILON); axis.setMaximum(newValue); assertTrue(Math.abs(axis.getMaximum() - newValue) < EPSILON); IllegalArgumentException iae = null; try { axis.setLogBase(0.0); } catch (IllegalArgumentException e) { iae = e; } assertNotNull(iae); iae = null; try { axis.setLogBase(30000.0); } catch (IllegalArgumentException e) { iae = e; } assertNotNull(iae); } }