123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- /*
- * ====================================================================
- * 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.examples.xssf.usermodel;
-
- import java.io.FileOutputStream;
-
- import org.apache.poi.ss.util.CellRangeAddress;
- import org.apache.poi.ss.util.CellReference;
- import org.apache.poi.xddf.usermodel.PresetColor;
- import org.apache.poi.xddf.usermodel.XDDFColor;
- import org.apache.poi.xddf.usermodel.XDDFFillProperties;
- import org.apache.poi.xddf.usermodel.XDDFLineProperties;
- import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
- import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;
- import org.apache.poi.xddf.usermodel.chart.AxisPosition;
- import org.apache.poi.xddf.usermodel.chart.AxisTickLabelPosition;
- import org.apache.poi.xddf.usermodel.chart.BarDirection;
- import org.apache.poi.xddf.usermodel.chart.ChartTypes;
- import org.apache.poi.xddf.usermodel.chart.LegendPosition;
- import org.apache.poi.xddf.usermodel.chart.XDDFBarChartData;
- import org.apache.poi.xddf.usermodel.chart.XDDFCategoryAxis;
- import org.apache.poi.xddf.usermodel.chart.XDDFCategoryDataSource;
- import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
- import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
- import org.apache.poi.xddf.usermodel.chart.XDDFLegendEntry;
- import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
- import org.apache.poi.xddf.usermodel.chart.XDDFScatterChartData;
- import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
- import org.apache.poi.xddf.usermodel.text.XDDFRunProperties;
- import org.apache.poi.xssf.usermodel.XSSFCell;
- import org.apache.poi.xssf.usermodel.XSSFChart;
- import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
- import org.apache.poi.xssf.usermodel.XSSFDrawing;
- import org.apache.poi.xssf.usermodel.XSSFRow;
- import org.apache.poi.xssf.usermodel.XSSFSheet;
- import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-
- /**
- * This example is based on original contributions by Axel Richter
- *
- * <em>Note from original author</em>:
- * This only works for Excel since OpenOffice or LibreOffice Calc is not able having series having literal numeric values set.
- */
- public final class ExcelChartWithTargetLine {
- private ExcelChartWithTargetLine() {}
-
- private static final int NUM_OF_ROWS = 6;
-
- private static void createChart(XSSFChart chart, XSSFSheet sheet, int[] chartedCols, double target) {
- // some colors
- XDDFFillProperties[] fills = new XDDFFillProperties[] {
- new XDDFSolidFillProperties(XDDFColor.from(PresetColor.TURQUOISE)),
- new XDDFSolidFillProperties(XDDFColor.from(PresetColor.CHARTREUSE)),
- new XDDFSolidFillProperties(XDDFColor.from(PresetColor.LAVENDER)),
- new XDDFSolidFillProperties(XDDFColor.from(PresetColor.CHOCOLATE)),
- new XDDFSolidFillProperties(XDDFColor.from(PresetColor.TOMATO)),
- new XDDFSolidFillProperties(XDDFColor.from(PresetColor.PLUM))
- };
- XDDFLineProperties solidTurquoise = new XDDFLineProperties(fills[0]);
- XDDFLineProperties solidTomato = new XDDFLineProperties(fills[4]);
- XDDFLineProperties solidPlum = new XDDFLineProperties(fills[5]);
- XDDFSolidFillProperties solidAlmond = new XDDFSolidFillProperties(XDDFColor.from(PresetColor.BLANCHED_ALMOND));
- XDDFSolidFillProperties solidGray = new XDDFSolidFillProperties(XDDFColor.from(PresetColor.DARK_SLATE_GRAY));
-
-
- // the bar chart
-
- XDDFCategoryAxis barCategories = chart.createCategoryAxis(AxisPosition.BOTTOM);
- XDDFValueAxis leftValues = chart.createValueAxis(AxisPosition.LEFT);
- leftValues.crossAxis(barCategories);
- barCategories.crossAxis(leftValues);
-
- // colored major grid lines
- leftValues.getOrAddMajorGridProperties().setLineProperties(solidTomato);
- //colored axis line
- leftValues.getOrAddShapeProperties().setLineProperties(solidPlum);
- // axis font
- XDDFRunProperties props = leftValues.getOrAddTextProperties();
- props.setFontSize(14.0);
- props.setFillProperties(fills[5]);
-
- XDDFBarChartData bar = (XDDFBarChartData) chart.createData(ChartTypes.BAR, barCategories, leftValues);
- bar.setVaryColors(true);
- bar.setBarDirection(chartedCols.length > 1 ? BarDirection.COL : BarDirection.BAR);
-
- for (int c : chartedCols) {
- // the data sources
- XDDFCategoryDataSource xs = XDDFDataSourcesFactory.fromStringCellRange(sheet,
- new CellRangeAddress(1, NUM_OF_ROWS, 0, 0));
- XDDFNumericalDataSource<Double> ys = XDDFDataSourcesFactory.fromNumericCellRange(sheet,
- new CellRangeAddress(1, NUM_OF_ROWS, c, c));
- XDDFBarChartData.Series series = (XDDFBarChartData.Series) bar.addSeries(xs, ys);
- series.setTitle(null, new CellReference(sheet.getSheetName(), 0, c, true, true));
- series.setFillProperties(fills[c]);
- series.setLineProperties(solidTurquoise); // bar border color different from fill
- }
- chart.plot(bar);
-
-
- // target line
- // line of a scatter chart from 0 (min) to 1 (max) having value of target
-
- XDDFValueAxis scatterX = chart.createValueAxis(AxisPosition.TOP);
- scatterX.setVisible(false);
- scatterX.setTickLabelPosition(AxisTickLabelPosition.NONE);
- XDDFValueAxis scatterY = chart.createValueAxis(AxisPosition.RIGHT);
- scatterY.setVisible(false);
- scatterY.setTickLabelPosition(AxisTickLabelPosition.NONE);
- scatterX.crossAxis(scatterY);
- scatterY.crossAxis(scatterX);
- if (chartedCols.length > 1) {
- scatterX.setMaximum(1.0);
- } else {
- scatterY.setMaximum(1.0);
- }
-
- XDDFScatterChartData scatter = (XDDFScatterChartData) chart.createData(ChartTypes.SCATTER, scatterX, scatterY);
- scatter.setVaryColors(false);
-
- // This only works for Excel since OpenOffice or LibreOffice Calc does not support literal numeric data series.
- XDDFNumericalDataSource<Double> targetDS = XDDFDataSourcesFactory.fromArray(new Double[] { target, target });
- XDDFNumericalDataSource<Double> zeroOneDS = XDDFDataSourcesFactory.fromArray(new Double[] { 0.0, 1.0 });
-
- if (chartedCols.length > 1) {
- // BarDirection.COL then X axis is from 0 to 1 and Y axis is target axis
- scatter.addSeries(zeroOneDS, targetDS).setLineProperties(solidTurquoise);
- } else {
- // BarDirection.BAR then X axis is target axis and Y axis is from 0 to 1
- scatter.addSeries(targetDS, zeroOneDS).setLineProperties(solidTurquoise);
- }
-
- chart.plot(scatter);
-
-
- // legend
- if (chartedCols.length > 1) {
- XDDFChartLegend legend = chart.getOrAddLegend();
- legend.setPosition(LegendPosition.LEFT);
- legend.setOverlay(false);
-
- // delete additional target line series legend entry
- XDDFLegendEntry entry = legend.addEntry();
- entry.setIndex(0);
- entry.setDelete(true);
- }
-
-
- // customize the chart
-
- // do not auto delete the title
- chart.setAutoTitleDeleted(false);
-
- // plot area background and border line
- XDDFShapeProperties chartProps = chart.getOrAddShapeProperties();
- chartProps.setFillProperties(solidAlmond);
- chartProps.setLineProperties(new XDDFLineProperties(solidGray));
-
- // line style of cat axis
- XDDFLineProperties categoriesProps = new XDDFLineProperties(solidGray);
- categoriesProps.setWidth(2.1);
- barCategories.getOrAddShapeProperties().setLineProperties(categoriesProps);
- }
-
- private static XSSFClientAnchor createAnchor(XSSFDrawing drawing, int[] chartedCols) {
- if (chartedCols.length > 1) {
- return drawing.createAnchor(0, 0, 0, 0, 0, 8, 10, 23);
- } else {
- return drawing.createAnchor(0, 0, 0, 0, 0, 8, 5, 23);
- }
- }
-
- public static void main(String[] args) throws Exception {
- try (XSSFWorkbook workbook = new XSSFWorkbook()) {
- XSSFSheet sheet = workbook.createSheet("targetline");
- final int NUM_OF_COLUMNS = 4;
-
- // create some data
- XSSFRow row;
- XSSFCell cell;
- String[] headings = new String[] { "Year", "Male", "Female", "Other" };
- int rowIndex = 0;
- row = sheet.createRow(rowIndex);
- for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
- cell = row.createCell(colIndex);
- cell.setCellValue(headings[colIndex]);
- }
- double[][] values = new double[][] { new double[] { 1980, 56.0, 44.1, 12.2 },
- new double[] { 1985, 34.5, 41.0, 4 }, new double[] { 1990, 65.0, 68.5, 9.1 },
- new double[] { 1995, 34.7, 47.6, 4.9 }, new double[] { 2000, 23.0, 64.5, 11.1 },
- new double[] { 2005, 56.3, 69.8, 9.5 } };
- for (; rowIndex < NUM_OF_ROWS; rowIndex++) {
- row = sheet.createRow(rowIndex + 1);
- for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
- cell = row.createCell(colIndex);
- cell.setCellValue(values[rowIndex][colIndex]);
- }
- }
-
- int[] chartedCols = new int[] { 1, 2 , 3 };
-
- XSSFDrawing drawing = sheet.createDrawingPatriarch();
- XSSFClientAnchor anchor = createAnchor(drawing, chartedCols);
- XSSFChart chart = drawing.createChart(anchor);
- createChart(chart, sheet, chartedCols, 42.0);
-
- try (FileOutputStream fos = new FileOutputStream("ExcelChartWithTargetLine.xlsx")) {
- workbook.write(fos);
- }
- }
- }
- }
|