java - 如何将条形图放置在刻度线之间?

标签 java apache-poi bar-chart

我在下面的图片中添加了我想要的示例。

这就是我得到的。 What I get

这就是我想要的。 What I want

我一直在图书馆中搜索,试图找到一些东西来进行此更改,但我似乎找不到它。

或者,有没有办法在顶部或底部添加填充?主要问题是我不希望条形图接触图表的顶部或底部边框。

这是一个XDDFChart,这里是相关代码。

  XDDFCategoryAxis leftAxis = chart.createCategoryAxis(AxisPosition.LEFT);
  leftAxis.setTitle("Name");


  XDDFValueAxis bottomAxis = chart.createValueAxis(AxisPosition.BOTTOM);
  bottomAxis.setTitle("Volume");

最佳答案

在条形图中,值轴应设置为 crossBetween val="between" ,因此值轴与类别之间的类别轴交叉。否则,第一个和最后一个类别恰好位于交叉点上,并且条形图仅一半可见。

此外,左轴永远不会是类别轴,底轴永远不会是值轴,即使对于显示 BarDirection.BAR 的条形图也是如此。而不是BarDirection.COL 。只有XDDFBarChartData的酒吧方向不同。轴保持不变。

所以对于XDDFChart一般来说,酒吧chrat有BarDirection.BAR应该是这样的:

...
// create axis
XDDFCategoryAxis categoryAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
categoryAxis.setTickLabelPosition(AxisTickLabelPosition.NONE);
XDDFValueAxis valueAxis = chart.createValueAxis(AxisPosition.LEFT);
valueAxis.setCrosses(AxisCrosses.AUTO_ZERO);
// Set AxisCrossBetween, so the left 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.
valueAxis.setCrossBetween(AxisCrossBetween.BETWEEN);

// create chart data
XDDFBarChartData data = (XDDFBarChartData)chart.createData(ChartTypes.BAR, categoryAxis, valueAxis);
data.setBarDirection(BarDirection.BAR);
 ...

创建 XWPFChart 的完整示例在 Word文档:

import java.io.*;

import org.apache.poi.xwpf.usermodel.*;

import org.apache.poi.ss.util.*;
import org.apache.poi.util.Units;

import org.apache.poi.xddf.usermodel.*;
import org.apache.poi.xddf.usermodel.chart.*;

import org.apache.poi.xssf.usermodel.*;

public class CreateWordXDDFChart {

 // methode to set title in the data sheet without creating a Table but using the sheet data only
 // creating a Table is not really necessary
 static CellReference setTitleInDataSheet(XDDFChart chart, String title, int column) throws Exception {
  XSSFWorkbook workbook = chart.getWorkbook();
  XSSFSheet sheet = workbook.getSheetAt(0);
  XSSFRow row = sheet.getRow(0); if (row == null) row = sheet.createRow(0);
  XSSFCell cell = row.getCell(column); if (cell == null) cell = row.createCell(column);
  cell.setCellValue(title);
  return new CellReference(sheet.getSheetName(), 0, column, true, true);
 }

 // methode to fill a series data into the underlying sheet
 static void fillSheet(XDDFChart chart, XDDFDataSource<?> categoryData, XDDFNumericalDataSource<?> valuesData) throws Exception {
  XSSFWorkbook workbook = chart.getWorkbook();
  XSSFSheet sheet = workbook.getSheetAt(0);
  int numOfPoints = categoryData.getPointCount();
  for (int i = 0; i < numOfPoints; i++) {
   XSSFRow row = sheet.getRow(i + 1); if (row == null) row = sheet.createRow(i + 1); // first row is for title
   XSSFCell cell = row.getCell(categoryData.getColIndex()); if (cell == null) cell = row.createCell(categoryData.getColIndex());
   cell.setCellValue(categoryData.getPointAt(i).toString());
   cell = row.getCell(valuesData.getColIndex()); if (cell == null) cell = row.createCell(valuesData.getColIndex());
   cell.setCellValue(valuesData.getPointAt(i).doubleValue());
  }
 }

 public static void main(String[] args) throws Exception {
  try (XWPFDocument document = new XWPFDocument()) {

   // create the data
   String[] categories = new String[]{"C1", "C2", "C3"};
   Double[] valuesA = new Double[]{300d, 20d, 10d};

   // create the chart
   XWPFChart chart = document.createChart(15*Units.EMU_PER_CENTIMETER, 10*Units.EMU_PER_CENTIMETER);

   // create data sources
   int numOfPoints = categories.length;
   String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
   String valuesDataRangeA = chart.formatRange(new CellRangeAddress(1, numOfPoints, 1, 1));
   XDDFDataSource<String> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);
   XDDFNumericalDataSource<Double> valuesDataA = XDDFDataSourcesFactory.fromArray(valuesA, valuesDataRangeA, 1);

   // create axis
   XDDFCategoryAxis categoryAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
   categoryAxis.setTickLabelPosition(AxisTickLabelPosition.NONE);
   XDDFValueAxis valueAxis = chart.createValueAxis(AxisPosition.LEFT);
   valueAxis.setCrosses(AxisCrosses.AUTO_ZERO);
   // Set AxisCrossBetween, so the left 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.
   valueAxis.setCrossBetween(AxisCrossBetween.BETWEEN);

   // create chart data
   XDDFBarChartData data = (XDDFBarChartData)chart.createData(ChartTypes.BAR, categoryAxis, valueAxis);
   data.setBarDirection(BarDirection.BAR);

   // create series
   data.setVaryColors(true);
   XDDFBarChartData.Series series = (XDDFBarChartData.Series)data.addSeries(categoriesData, valuesDataA);
   // XDDFChart.setSheetTitle is buggy. It creates a Table but only half way and incomplete.
   // Excel cannot opening the workbook after creating that incomplete Table.
   // So updating the chart data in Word is not possible.
   //series.setTitle("Ser1", chart.setSheetTitle("Ser1", 1));
   series.setTitle("Ser1", setTitleInDataSheet(chart, "Ser1", 1));
   // since apache oi 4.1.1 XDDFChart does not fill the series in the sheet while plot. Apache poi 4.1.0 had done this: https://svn.apache.org/viewvc/poi/tags/REL_4_1_0/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChart.java?view=markup#l363
   // so we need doing this for each series now
   fillSheet(chart, categoriesData, valuesDataA);

   // plot chart data
   chart.plot(data);

   // Write the output to a file
   try (FileOutputStream fileOut = new FileOutputStream("CreateWordXDDFChart.docx")) {
    document.write(fileOut);
   }
  }
 }
}

关于java - 如何将条形图放置在刻度线之间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59637419/

相关文章:

javascript - 如何在谷歌条形图中显示百分比?

javascript - D3 条形图中第一个条之前不需要的空格

java - m2eclipse 依赖版本不是最新的

java - 设计模式-单个对象只能存在于单个事件中

java - 将 Apache POI 与 GraalVM native 镜像结合使用 - 来自 XMLBeans 的 ClassCastException

java - Apache poi 无法打开 Word 文档 : NoSuchMethodError using ooxml-shemas-1. 0.jar,但无法使用 poi-ooxmlshemas-3.8.jar

r - 如何在 ggplot2 中绘制组合条形图和折线图

java - 使用网络资源进行货币转换器

java - Fragments 中的 Android FATAL 异常

java - 使用 POI 从 .xls 升级到 .xlsx