I've generated a line chart using Apache POI. I need to change the default colors I got in the chart. Can I use RGB codes to define specific colors to each line?
My code is as follows.
Drawing drawing = sheet4.createDrawingPatriarch();
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 17, 22);
Chart chart = drawing.createChart(anchor);
ChartLegend legend = chart.getOrCreateLegend();
legend.setPosition(LegendPosition.RIGHT);
LineChartData data = chart.getChartDataFactory().createLineChartData();
ChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM);
ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
ChartDataSource<Number> xs = DataSources.fromNumericCellRange(sheet1, new CellRangeAddress(1, 380, 0, 0));
ChartDataSource<Number> ys1 = DataSources.fromNumericCellRange(sheet1, new CellRangeAddress(1, 380, 1, 1));
ChartDataSource<Number> ys2 = DataSources.fromNumericCellRange(sheet1, new CellRangeAddress(1, 380, 3, 3));
ChartDataSource<Number> ys3 = DataSources.fromNumericCellRange(sheet1, new CellRangeAddress(1, 380, 4, 4));
ChartDataSource<Number> ys4 = DataSources.fromNumericCellRange(sheet1, new CellRangeAddress(1, 380, 8, 8));
LineChartSeries series1 = data.addSeries(xs, ys1);
series1.setTitle("Value 1");
LineChartSeries series2 = data.addSeries(xs, ys2);
series2.setTitle("Value 2");
LineChartSeries series3 = data.addSeries(xs, ys3);
series3.setTitle("Value 3");
LineChartSeries series4 = data.addSeries(xs, ys4);
series4.setTitle("Value 4");
chart.plot(data, bottomAxis, leftAxis);
XSSFChart xssfChart = (XSSFChart) chart;
CTPlotArea plotArea = xssfChart.getCTChart().getPlotArea();
plotArea.getLineChartArray()[0].getSmooth();
CTBoolean ctBool = CTBoolean.Factory.newInstance();
ctBool.setVal(false);
plotArea.getLineChartArray()[0].setSmooth(ctBool);
for (CTLineSer ser : plotArea.getLineChartArray()[0].getSerArray()) {
ser.setSmooth(ctBool);
}
I am always a friend of complete examples. Then others can reproducing this and don't need guess how the Excel sheet might look like.
The following complete example does creating a new Excel workbook in Office Open XML format (*.xlsx) having a sheet containing some example data and the line chart.
First code part creates a line chart how apache poi version 3.17 creates it per default.
Then in second code part, I do customizing the chart. The code parts are commented to show what they shall do. After that customizing the chart also is OpenOffice / Libreoffice Calc compatible. The apache poi default charts are not OpenOffice / Libreoffice Calc compatible. At least up to version 3.17.
For customizing one needs knowledge about the internal low level objects apache poi uses as basic objects. Those are contained in ooxml-schemas-1.3.jar . Unfortunately there is not more a API doc public available. So one must download ooxml-schemas-1.3-sources.jar and then do javadoc one's own to get a documentation.
Also one should know that files in Office Open XML format (*.xlsx) simply are ZIP archives. So one can unzip them and have a look at /xl/charts/chart1.xml. When one does this after apache poi has created the chart and do comparing that XML with the XML after re-saving after done the wanted changings in Excel, then one will see the needed XML changings.
Example:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.charts.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.Units;
public class CreateExcelLineChartAndCustomize {
public static void main(String[] args) throws Exception {
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet("linechart");
final int NUM_OF_ROWS = 100;
final int NUM_OF_COLUMNS = 5;
// create some data
Row row;
Cell cell;
String[] headings = new String []{"x", "sin(x)", "cos(x)", "random", "random/x"};
for (int rowIndex = 0; rowIndex < 1; rowIndex++) {
row = sheet.createRow(rowIndex);
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
cell = row.createCell(colIndex);
cell.setCellValue(headings[colIndex]);
}
}
for (int rowIndex = 1; rowIndex < NUM_OF_ROWS; rowIndex++) {
row = sheet.createRow(rowIndex);
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
cell = row.createCell(colIndex);
switch (colIndex) {
case 0:
cell.setCellValue(rowIndex/10d);
break;
case 1:
cell.setCellFormula("SIN(A" + (rowIndex+1) + ")");
break;
case 2:
cell.setCellFormula("COS(A" + (rowIndex+1) + ")");
break;
case 3:
cell.setCellFormula("RAND()");
break;
case 4:
cell.setCellFormula("-D"+(rowIndex+1));
break;
default:
}
}
}
// create default chart
Drawing<?> drawing = sheet.createDrawingPatriarch();
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 6, 1, 15, 21);
Chart chart = drawing.createChart(anchor);
ChartLegend legend = chart.getOrCreateLegend();
legend.setPosition(LegendPosition.RIGHT);
if (chart instanceof XSSFChart) ((XSSFChart)chart).setTitleText("Some lines");
LineChartData data = chart.getChartDataFactory().createLineChartData();
ChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM);
ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
ChartDataSource<Number> xs = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(1, 99, 0, 0));
ChartDataSource<Number> ys1 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(1, 99, 1, 1));
ChartDataSource<Number> ys2 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(1, 99, 2, 2));
ChartDataSource<Number> ys3 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(1, 99, 3, 3));
ChartDataSource<Number> ys4 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(1, 99, 4, 4));
LineChartSeries series1 = data.addSeries(xs, ys1);
series1.setTitle("Value 1");
LineChartSeries series2 = data.addSeries(xs, ys2);
series2.setTitle("Value 2");
LineChartSeries series3 = data.addSeries(xs, ys3);
series3.setTitle("Value 3");
LineChartSeries series4 = data.addSeries(xs, ys4);
series4.setTitle("Value 4");
chart.plot(data, bottomAxis, leftAxis);
// customize the chart, this also makes it OpenOffice/Libreoffice Calc compatible
if (chart instanceof XSSFChart) {
XSSFChart xssfChart = (XSSFChart)chart;
// do not auto delete the title
if (xssfChart.getCTChart().getAutoTitleDeleted() == null) xssfChart.getCTChart().addNewAutoTitleDeleted();
xssfChart.getCTChart().getAutoTitleDeleted().setVal(false);
// plot area background and border line
if (xssfChart.getCTChartSpace().getSpPr() == null) xssfChart.getCTChartSpace().addNewSpPr();
if (xssfChart.getCTChartSpace().getSpPr().getSolidFill() == null)
xssfChart.getCTChartSpace().getSpPr().addNewSolidFill();
if (xssfChart.getCTChartSpace().getSpPr().getSolidFill().getSrgbClr() == null)
xssfChart.getCTChartSpace().getSpPr().getSolidFill().addNewSrgbClr();
xssfChart.getCTChartSpace().getSpPr().getSolidFill().getSrgbClr().setVal(new byte[]{(byte)255,(byte)255,(byte)255});
if (xssfChart.getCTChartSpace().getSpPr().getLn() == null) xssfChart.getCTChartSpace().getSpPr().addNewLn();
xssfChart.getCTChartSpace().getSpPr().getLn().setW(Units.pixelToEMU(1));
if (xssfChart.getCTChartSpace().getSpPr().getLn().getSolidFill() == null)
xssfChart.getCTChartSpace().getSpPr().getLn().addNewSolidFill();
if (xssfChart.getCTChartSpace().getSpPr().getLn().getSolidFill().getSrgbClr() == null)
xssfChart.getCTChartSpace().getSpPr().getLn().getSolidFill().addNewSrgbClr();
xssfChart.getCTChartSpace().getSpPr().getLn().getSolidFill().getSrgbClr().setVal(new byte[]{(byte)0,(byte)0,(byte)0});
// line style of cat axis
if (xssfChart.getCTChart().getPlotArea().getCatAxArray(0).getSpPr() == null)
xssfChart.getCTChart().getPlotArea().getCatAxArray(0).addNewSpPr();
if (xssfChart.getCTChart().getPlotArea().getCatAxArray(0).getSpPr().getLn() == null)
xssfChart.getCTChart().getPlotArea().getCatAxArray(0).getSpPr().addNewLn();
xssfChart.getCTChart().getPlotArea().getCatAxArray(0).getSpPr().getLn().setW(Units.pixelToEMU(1));
if (xssfChart.getCTChart().getPlotArea().getCatAxArray(0).getSpPr().getLn().getSolidFill() == null)
xssfChart.getCTChart().getPlotArea().getCatAxArray(0).getSpPr().getLn().addNewSolidFill();
if (xssfChart.getCTChart().getPlotArea().getCatAxArray(0).getSpPr().getLn().getSolidFill().getSrgbClr() == null)
xssfChart.getCTChart().getPlotArea().getCatAxArray(0).getSpPr().getLn().getSolidFill().addNewSrgbClr();
xssfChart.getCTChart().getPlotArea().getCatAxArray(0).getSpPr().getLn().getSolidFill().getSrgbClr()
.setVal(new byte[]{(byte)0,(byte)0,(byte)0});
//line style of val axis
if (xssfChart.getCTChart().getPlotArea().getValAxArray(0).getSpPr() == null)
xssfChart.getCTChart().getPlotArea().getValAxArray(0).addNewSpPr();
if (xssfChart.getCTChart().getPlotArea().getValAxArray(0).getSpPr().getLn() == null)
xssfChart.getCTChart().getPlotArea().getValAxArray(0).getSpPr().addNewLn();
xssfChart.getCTChart().getPlotArea().getValAxArray(0).getSpPr().getLn().setW(Units.pixelToEMU(1));
if (xssfChart.getCTChart().getPlotArea().getValAxArray(0).getSpPr().getLn().getSolidFill() == null)
xssfChart.getCTChart().getPlotArea().getValAxArray(0).getSpPr().getLn().addNewSolidFill();
if (xssfChart.getCTChart().getPlotArea().getValAxArray(0).getSpPr().getLn().getSolidFill().getSrgbClr() == null)
xssfChart.getCTChart().getPlotArea().getValAxArray(0).getSpPr().getLn().getSolidFill().addNewSrgbClr();
xssfChart.getCTChart().getPlotArea().getValAxArray(0).getSpPr().getLn().getSolidFill().getSrgbClr()
.setVal(new byte[]{(byte)0,(byte)0,(byte)0});
// line style of the series
for (int i = 0; i < 4; i++) {
if (xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i).getSpPr() == null)
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i).addNewSpPr();
if (xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i).getSpPr().getLn() == null)
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i).getSpPr().addNewLn();
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i)
.getSpPr().getLn().setW(Units.pixelToEMU(3));
if (xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i).getSpPr().getLn().getSolidFill() == null)
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i).getSpPr().getLn().addNewSolidFill();
if (xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i).getSpPr().getLn().getSolidFill().getSrgbClr() == null)
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i).getSpPr().getLn().getSolidFill().addNewSrgbClr();
}
// first series red
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0)
.getSpPr().getLn().getSolidFill().getSrgbClr().setVal(new byte[]{(byte)255,(byte)0,(byte)0});
// second series green
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(1)
.getSpPr().getLn().getSolidFill().getSrgbClr().setVal(new byte[]{(byte)0,(byte)255,(byte)0});
// third series blue
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(2)
.getSpPr().getLn().getSolidFill().getSrgbClr().setVal(new byte[]{(byte)0,(byte)0,(byte)255});
// fourth series yellow
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(3)
.getSpPr().getLn().getSolidFill().getSrgbClr().setVal(new byte[]{(byte)255,(byte)255,(byte)0});
// set line data series to not smooth the line
for (int i = 0; i < 4; i++) {
if (xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i).getSmooth() == null)
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i).addNewSmooth();
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i).getSmooth().setVal(false);
}
// set or unset tick marks
for (int i = 0; i < 4; i++) {
if (xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i).getMarker() == null)
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i).addNewMarker();
if (xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i).getMarker().getSymbol() == null)
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(i).getMarker().addNewSymbol();
}
// no tick marks
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getMarker().getSymbol().setVal(
org.openxmlformats.schemas.drawingml.x2006.chart.STMarkerStyle.NONE);
// diamond tick marks
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(1).getMarker().getSymbol().setVal(
org.openxmlformats.schemas.drawingml.x2006.chart.STMarkerStyle.DIAMOND);
// auto tick marks = marker set but no symbol given
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(2).getMarker().unsetSymbol();
// no tick marks
xssfChart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(3).getMarker().getSymbol().setVal(
org.openxmlformats.schemas.drawingml.x2006.chart.STMarkerStyle.NONE);
}
wb.write(new FileOutputStream("CreateExcelLineChartAndCustomize.xlsx"));
wb.close();
}
}
Result:
Apache POI 4
private void lineSeriesColor(XDDFChartData.Series series, XDDFColor color) {
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(color);
XDDFLineProperties line = new XDDFLineProperties();
line.setFillProperties(fill);
XDDFShapeProperties properties = series.getShapeProperties();
if (properties == null) {
properties = new XDDFShapeProperties();
}
properties.setLineProperties(line);
series.setShapeProperties(properties);
}
private byte[] hex2Rgb(String colorStr) {
int r = Integer.valueOf(colorStr.substring(1, 3), 16);
int g = Integer.valueOf(colorStr.substring(3, 5), 16);
int b = Integer.valueOf(colorStr.substring(5, 7), 16);
return new byte[]{(byte) r, (byte) g, (byte) b};
}
then
String color = "#0C1111";
lineSeriesColor(series, XDDFColor.from(hex2Rgb(color)));
Related
I have excel generation using org.apache.poi library. Here i need to generate a bar chart which should show like below:
And my excel look like:
Code:
//CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol)
XDDFDataSource<String> department = XDDFDataSourcesFactory.fromStringCellRange(sheet,
new CellRangeAddress(7, 17, 1, 1));
If i set CellRangeAddress firstCol - 0 and lastCol - 1 its not working?
Is any option to enable this in java:
Multi-level category labels are not possible using the XDDF stuff of apache poi. The XDDF always uses StrRef as references for chart data sources. To create multi-level category labels MultiLvlStrRef would must be used. So the task only is solvable using the low level org.openxmlformats.schemas.drawingml.x2006.chart.* classes directly.
That's why following code needs the full jar of all of the ooxml-schemas, which is ooxml-schemas-1.4.jar for current apache poi 4.1.2, in class path. The poi-ooxml-schemas-4.1.2.jar does not contain org.openxmlformats.schemas.drawingml.x2006.chart.CTMultiLvlStrRef.
And because of the crude logic of Microsoft, which uses a setting NoMultiLvlLbl-true as the default for category axes, one now must tell the category axis that it not has no multi level labels. So, if the axis shall have multi-level category labels, NoMultiLvlLbl must be set false. Well, seems that Microsoft wants to check whether programmers have learned their logic lessons well ;-).
Complete example:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
import org.apache.poi.xddf.usermodel.chart.LegendPosition;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.chart.*;
public class BarChartMultiLevelCategories {
public static void main(String[] args) throws Exception {
String[] series = new String[]{"January","February","March"};
String[] charges = new String[]{"Charges not Tally","Deposit","High Charges", "Quotation"};
String[] treatment = new String[]{"Diagnosis","Explanation","Procedure"};
String[] behaviour = new String[]{"Miscommunication","Not Attentive","Not Friendly", "Rude"};
Double[][] values = new Double[][]{
new Double[]{1d, 2d, 3d},
new Double[]{1d, 3d, 2d},
new Double[]{2d, 1d, 3d},
new Double[]{2d, 3d, 1d},
new Double[]{3d, 1d, 2d},
new Double[]{3d, 2d, 1d},
new Double[]{1d, 2d, 3d},
new Double[]{1d, 3d, 2d},
new Double[]{2d, 1d, 3d},
new Double[]{2d, 3d, 1d},
new Double[]{3d, 1d, 2d},
};
try (XSSFWorkbook wb = new XSSFWorkbook()) {
//the sheet for the chart
XSSFSheet chartSheet = wb.createSheet("barchart");
//the sheet for the data
XSSFSheet dataSheet = wb.createSheet("data");
Row row;
Cell cell;
row = dataSheet.createRow(0);
for (int i = 0; i < series.length; i++) {
cell = row.createCell(i+2); cell.setCellValue(series[i]);
}
for (int i = 0; i < charges.length; i++) {
row = dataSheet.createRow(i+1);
if (i == 0) { cell = row.createCell(0); cell.setCellValue("Charges"); }
cell = row.createCell(1); cell.setCellValue(charges[i]);
}
dataSheet.addMergedRegion(new CellRangeAddress(1, charges.length, 0, 0));
for (int i = 0; i < treatment.length; i++) {
row = dataSheet.createRow(i+1+charges.length);
if (i == 0) { cell = row.createCell(0); cell.setCellValue("Treatment"); }
cell = row.createCell(1); cell.setCellValue(treatment[i]);
}
dataSheet.addMergedRegion(new CellRangeAddress(1+charges.length, charges.length+treatment.length, 0, 0));
for (int i = 0; i < behaviour.length; i++) {
row = dataSheet.createRow(i+1+charges.length+treatment.length);
if (i == 0) { cell = row.createCell(0); cell.setCellValue("Behaviour"); }
cell = row.createCell(1); cell.setCellValue(behaviour[i]);
}
dataSheet.addMergedRegion(
new CellRangeAddress(1+charges.length+treatment.length, charges.length+treatment.length+behaviour.length, 0, 0));
for (int i = 0; i < values.length; i++) {
Double[] valuesRow = values[i];
row = dataSheet.getRow(i+1);
for (int j = 0; j < valuesRow.length; j++) {
cell = row.createCell(j+2); cell.setCellValue(valuesRow[j]);
}
}
XSSFDrawing drawing = chartSheet.createDrawingPatriarch();
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 0, 10, 20);
XSSFChart chart = drawing.createChart(anchor);
chart.setTitleText("Chart title");
chart.setTitleOverlay(false);
//do not auto delete the title; is necessary for showing title in Calc
if (chart.getCTChart().getAutoTitleDeleted() == null) chart.getCTChart().addNewAutoTitleDeleted();
chart.getCTChart().getAutoTitleDeleted().setVal(false);
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.RIGHT);
CTChart ctChart = chart.getCTChart();
CTPlotArea ctPlotArea = ctChart.getPlotArea();
CTBarChart ctBarChart = ctPlotArea.addNewBarChart();
CTBoolean ctBoolean = ctBarChart.addNewVaryColors();
ctBoolean.setVal(true);
ctBarChart.addNewBarDir().setVal(STBarDir.COL);
//telling the BarChart that it has axes and giving them Ids
ctBarChart.addNewAxId().setVal(123456);
ctBarChart.addNewAxId().setVal(123457);
//cat axis
CTCatAx ctCatAx = ctPlotArea.addNewCatAx();
ctCatAx.addNewAxId().setVal(123456); //id of the cat axis
CTScaling ctScaling = ctCatAx.addNewScaling();
ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
ctCatAx.addNewDelete().setVal(false);
ctCatAx.addNewAxPos().setVal(STAxPos.B);
ctCatAx.addNewCrossAx().setVal(123457); //id of the val axis
ctCatAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
//telling the category axis that it not has no multi level labels ;-)
ctCatAx.addNewNoMultiLvlLbl().setVal(false);
//val axis
CTValAx ctValAx = ctPlotArea.addNewValAx();
ctValAx.addNewAxId().setVal(123457); //id of the val axis
ctScaling = ctValAx.addNewScaling();
ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
ctValAx.addNewDelete().setVal(false);
ctValAx.addNewAxPos().setVal(STAxPos.L);
ctValAx.addNewCrossAx().setVal(123456); //id of the cat axis
ctValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
//series
byte[][] seriesColors = new byte[][] {
new byte[]{(byte)255, 0, 0}, //red
new byte[]{0, (byte)255, 0}, //green
new byte[]{0, 0, (byte)255} //blue
};
for (int i = 0; i < series.length; i++) {
CTBarSer ctBarSer = ctBarChart.addNewSer();
CTSerTx ctSerTx = ctBarSer.addNewTx();
CTStrRef ctStrRef = ctSerTx.addNewStrRef();
ctStrRef.setF(
new CellRangeAddress(0, 0, i+2, i+2)
.formatAsString(dataSheet.getSheetName(), true)); //data!R1C(i+2)
ctBarSer.addNewIdx().setVal(i);
CTAxDataSource cttAxDataSource = ctBarSer.addNewCat();
//do using MultiLvlStrRef instead of StrRef
CTMultiLvlStrRef ctMultiLvlStrRef = cttAxDataSource.addNewMultiLvlStrRef();
ctMultiLvlStrRef.setF(
new CellRangeAddress(1, charges.length+treatment.length+behaviour.length, 0, 1)
.formatAsString(dataSheet.getSheetName(), true)); //data!$A$2:$B$12
CTNumDataSource ctNumDataSource = ctBarSer.addNewVal();
CTNumRef ctNumRef = ctNumDataSource.addNewNumRef();
ctNumRef.setF(
new CellRangeAddress(1, charges.length+treatment.length+behaviour.length, i+2, i+2)
.formatAsString(dataSheet.getSheetName(), true)); //data!R2C(i+2):R12C(i+2)
ctBarSer.addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(seriesColors[i]);
}
try (FileOutputStream fileOut = new FileOutputStream("ooxml-bar-chart.xlsx")) {
wb.write(fileOut);
}
}
}
}
I use poi version is 4.1.1.
Now I want to make first column doesn't display on y-axis, means I want to add some space between y-axis and the first column.
I notice there is an option "Axis position" on x-axis, when it set to "Between tick marks", it will work as I want.
But I don't know how to make it using apache-poi. Is it possible to make it?
here is the "Asis position in excel"
now the line chart looks like
what I want
Thanks everyone!!!
Here is the code example from Apache website:
public class LineChart {
public static void main(String[] args) throws IOException {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
XSSFSheet sheet = wb.createSheet("linechart");
final int NUM_OF_ROWS = 3;
final int NUM_OF_COLUMNS = 10;
// Create a row and put some cells in it. Rows are 0 based.
Row row;
Cell cell;
for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++) {
row = sheet.createRow((short) rowIndex);
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
cell = row.createCell((short) colIndex);
cell.setCellValue(colIndex * (rowIndex + 1.0));
}
}
XSSFDrawing drawing = sheet.createDrawingPatriarch();
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15);
XSSFChart chart = drawing.createChart(anchor);
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.BOTTOM);
// Use a category axis for the bottom axis.
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
//bottomAxis.setTitle("x"); // https://stackoverflow.com/questions/32010765
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
//leftAxis.setTitle("f(x)");
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
XDDFDataSource<Double> xs = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
XDDFNumericalDataSource<Double> ys1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1));
XDDFNumericalDataSource<Double> ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1));
XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(xs, ys1);
series1.setTitle("a", null); // https://stackoverflow.com/questions/21855842
//series1.setSmooth(false); // https://stackoverflow.com/questions/29014848
series1.setMarkerStyle(MarkerStyle.NONE); // https://stackoverflow.com/questions/39636138
XDDFLineChartData.Series series2 = (XDDFLineChartData.Series) data.addSeries(xs, ys2);
series2.setTitle("b", null);
//series2.setSmooth(true);
//series2.setMarkerSize((short) 6);
series2.setMarkerStyle(MarkerStyle.NONE); // https://stackoverflow.com/questions/39636138
CTBoolean ctBoolean = CTBoolean.Factory.newInstance();
ctBoolean.setVal(false);
CTPlotArea plotArea = chart.getCTChart().getPlotArea();
chart.getCTChartSpace().setRoundedCorners(ctBoolean);
for (CTLineSer ser : plotArea.getLineChartArray()[0].getSerArray()) {
CTDLbls ctdLbls = ser.addNewDLbls();
ctdLbls.setShowSerName(ctBoolean);
ctdLbls.setShowLegendKey(ctBoolean);
ctdLbls.setShowLeaderLines(ctBoolean);
ctdLbls.setShowCatName(ctBoolean);
CTDLblPos ctdLblPos = CTDLblPos.Factory.newInstance();
ctdLblPos.setVal(STDLblPos.CTR);
CTDLblPos.Factory.newInstance();
ctdLbls.setDLblPos(ctdLblPos);
}
chart.plot(data);
// if your series have missing values like https://stackoverflow.com/questions/29014848
// chart.displayBlanksAs(DisplayBlanks.GAP);
// https://stackoverflow.com/questions/24676460
solidLineSeries(data, 0, PresetColor.LIGHT_GREEN);
solidLineSeries(data, 1, PresetColor.DARK_RED);
// Write the output to a file
try (FileOutputStream fileOut = new FileOutputStream("ooxml-line-chart.xlsx")) {
wb.write(fileOut);
}
}
}
//CTPresetLineDashProperties
private static void solidLineSeries(XDDFChartData data, int index, PresetColor color) {
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
XDDFLineProperties line = new XDDFLineProperties();
if (index == 0) {
line.setPresetDash(new XDDFPresetLineDash(PresetLineDash.DOT));
}
line.setFillProperties(fill);
XDDFChartData.Series series = data.getSeries().get(index);
XDDFShapeProperties properties = series.getShapeProperties();
if (properties == null) {
properties = new XDDFShapeProperties();
}
properties.setLineProperties(line);
series.setShapeProperties(properties);
}
}
Per default the value axis and the category axis crosses exactly on category point. So if value axis crosses category axis at point 0, then it looks like your result now.
But if x axis is a category axis, then there is a setting XDDFValueAxis.setCrossBetween. If that is set to AxisCrossBetween.BETWEEN then the value axis crosses the category axis between the category points. This looks as you want.
So in your case:
...
// Use a category axis for the bottom axis.
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
//bottomAxis.setTitle("x"); // https://stackoverflow.com/questions/32010765
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
//leftAxis.setTitle("f(x)");
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
...
Btw.: You should get rid of deprecated methods.
For example the get...Array() methods of ooxml-schemas are deprecated. Either you get a concrete item from the array using get...Array(item) or you get a List using get...List().
In your case:
...
//for (CTLineSer ser : plotArea.getLineChartArray()[0].getSerArray()) {
for (CTLineSer ser : plotArea.getLineChartArray(0).getSerList()) {
...
And also XDDFChartData.getSeries() is deprecated. If you need one series do using XDDFChartData.getSeries(index)
In your case:
...
//XDDFChartData.Series series = data.getSeries().get(index);
XDDFChartData.Series series = data.getSeries(index);
...
The scatter chart example included with Apache POI shows how to set the color of a line (that connects markers in a series), but I cannot figure out how to set the color of a marker for a series. I see that I can change the marker icon (with setMarkerStyle (javadoc), but that does not appear to have editable color properties).
From a previous SO question I suspect that it will be necessary to disable the vary colors configuration, but I still do not know how to set the colors after that step (if the following line is even necessary).
((XSSFChart)chart).getCTChart().getPlotArea().getScatterChartArray(0)
.addNewVaryColors().setVal(false);
How can I specify the marker icon colors in the example below?
public class ScatterChart {
public static void main(String[] args) throws IOException {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
XSSFSheet sheet = wb.createSheet("Sheet 1");
final int NUM_OF_ROWS = 3;
final int NUM_OF_COLUMNS = 10;
// Create a row and put some cells in it. Rows are 0 based.
Row row;
Cell cell;
for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++) {
row = sheet.createRow((short) rowIndex);
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
cell = row.createCell((short) colIndex);
cell.setCellValue(colIndex * (rowIndex + 1.0));
}
}
XSSFDrawing drawing = sheet.createDrawingPatriarch();
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15);
XSSFChart chart = drawing.createChart(anchor);
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.TOP_RIGHT);
XDDFValueAxis bottomAxis = chart.createValueAxis(AxisPosition.BOTTOM);
bottomAxis.setTitle("x"); // https://stackoverflow.com/questions/32010765
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.setTitle("f(x)");
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
XDDFDataSource<Double> xs = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
XDDFNumericalDataSource<Double> ys1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1));
XDDFNumericalDataSource<Double> ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1));
XDDFScatterChartData data = (XDDFScatterChartData) chart.createData(ChartTypes.SCATTER, bottomAxis, leftAxis);
XDDFScatterChartData.Series series1 = (XDDFScatterChartData.Series) data.addSeries(xs, ys1);
series1.setTitle("2x", null); // https://stackoverflow.com/questions/21855842
series1.setSmooth(false); // https://stackoverflow.com/questions/39636138
XDDFScatterChartData.Series series2 = (XDDFScatterChartData.Series) data.addSeries(xs, ys2);
series2.setTitle("3x", null);
chart.plot(data);
solidLineSeries(data, 0, PresetColor.CHARTREUSE);
solidLineSeries(data, 1, PresetColor.TURQUOISE);
// Write the output to a file
try (FileOutputStream fileOut = new FileOutputStream("ooxml-scatter-chart.xlsx")) {
wb.write(fileOut);
}
}
}
private static void solidLineSeries(XDDFChartData data, int index, PresetColor color) {
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
XDDFLineProperties line = new XDDFLineProperties();
line.setFillProperties(fill);
XDDFChartData.Series series = data.getSeries().get(index);
XDDFShapeProperties properties = series.getShapeProperties();
if (properties == null) {
properties = new XDDFShapeProperties();
}
properties.setLineProperties(line);
series.setShapeProperties(properties);
}
}
The previous question you linked is from May 2018 and is about the pure XSSFChart stuff from apache poi upto version 3.17. This is outdated since apache poi 4.0.0 introduced the new XDDF stuff.
Nevertheless setting the marker color is not supported until now using only the high level XDDF classes. The marker has shape properties having fill properties of the same kind as the series itself. So we can use XDDFSolidFillProperties and XDDFShapeProperties as for the line settings. But to get the marker, we need using the low level underlying ooxml-schemas-1.4 beans.
Example:
...
series2.setMarkerStyle(MarkerStyle.DIAMOND);
series2.setMarkerSize((short)15);
XDDFSolidFillProperties fillMarker = new XDDFSolidFillProperties(XDDFColor.from(new byte[]{(byte)0xFF, (byte)0xFF, 0x00}));
XDDFShapeProperties propertiesMarker = new XDDFShapeProperties();
propertiesMarker.setFillProperties(fillMarker);
chart.getCTChart().getPlotArea().getScatterChartArray(0).getSerArray(1).getMarker()
.addNewSpPr().set(propertiesMarker.getXmlObject());
...
After building a XSSFScatterChartData and I filling it using the method XSSFChart.plot(ChartData data, ChartAxis... chartAxis), the plot contains markers but linked by a line..
I think the problem comes from the method XSSFScatterChartData.addStyle which sets a STScatterStyle.LINE_MARKER by default.
Here is a copy of the method I use to generate the chart:
private void setTrainingTimeGraph(Sheet trainingTimeSheet, Sheet resultsSheet) {
Drawing drawing = trainingTimeSheet.createDrawingPatriarch();
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 5, 5, 20, 30);
XSSFChart chart = (XSSFChart) drawing.createChart(anchor);
ChartLegend legend = chart.getOrCreateLegend();
legend.setPosition(LegendPosition.TOP_RIGHT);
chart.setTitleText("Training time over Fscore");
XSSFScatterChartData data = chart.getChartDataFactory().createScatterChartData();
ValueAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
setValueAxisTitle((XSSFChart) chart,0,"Fscore");
setValueAxisTitle((XSSFChart) chart,1, "Training Time");
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
bottomAxis.setCrosses(AxisCrosses.AUTO_ZERO);
ChartDataSource<Number> xs = DataSources.fromNumericCellRange(resultsSheet, new CellRangeAddress(16, 29, 10, 10));
ChartDataSource<Number> ys = DataSources.fromNumericCellRange(resultsSheet, new CellRangeAddress(16, 29, 18, 18));
data.addSerie(xs, ys);
chart.plot(data,bottomAxis, leftAxis);
}
UPDATE
So adding #AxelRichter code to set to no fill in my scatter chart data serie:
...
data.addSerie(xs, ys);
chart.plot(data,bottomAxis, leftAxis);
//set line properties of first scatter chart data serie to no fill:
((XSSFChart)chart).getCTChart().getPlotArea().getScatterChartArray(0).getSerArray(0)
.addNewSpPr().addNewLn().addNewNoFill();
I manged to get rid of the lines linking the Markers.. Finally!
But the second part wasn't what I was looking for. Let me explain it a little bit better:
When I pass hover each point in my scatterPlot there is some text which pops up ("label/x_value", x_value,y_value). The value in the legend is the same as its "label/x_value". I would like to set for each data point and for each value in legend its "label/x_value".
Thanks in advance!
Excel scatter charts will always have line between the markers too. If you don't wants to see this line it's fill color must be set to no fill.
References:
CTScatterSer -> CTShapeProperties -> CTLineProperties -> CTLineProperties.addNewNoFill
And for having data labels the series needs a CTDLbl setting.
Complete example:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.charts.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFChart;
import org.apache.poi.ss.util.CellRangeAddress;
public class CreateExcelScatterChart {
public static void main(String[] args) throws Exception {
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet("chart");
final int NUM_OF_ROWS = 2;
final int NUM_OF_COLUMNS = 20;
Row row;
Cell cell;
for (int rowIndex = 0; rowIndex < 1; rowIndex++) {
row = sheet.createRow((short) rowIndex);
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
cell = row.createCell((short) colIndex);
cell.setCellValue(4*colIndex * (rowIndex + 1));
}
}
for (int rowIndex = 1; rowIndex < NUM_OF_ROWS; rowIndex++) {
row = sheet.createRow((short) rowIndex);
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
cell = row.createCell((short) colIndex);
cell.setCellValue(Math.sin(Math.PI*colIndex/10*2));
}
}
Drawing<?> drawing = sheet.createDrawingPatriarch();
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 3, 13, 20);
Chart chart = drawing.createChart(anchor);
ChartLegend legend = chart.getOrCreateLegend();
legend.setPosition(LegendPosition.TOP_RIGHT);
ScatterChartData data = chart.getChartDataFactory().createScatterChartData();
ValueAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
bottomAxis.setCrosses(AxisCrosses.AUTO_ZERO);
ChartDataSource<Number> xs = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
ChartDataSource<Number> ys1 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1));
ScatterChartSeries chartSerie = data.addSerie(xs, ys1);
chartSerie.setTitle("My Title");
chart.plot(data, bottomAxis, leftAxis);
//set line properties of first scatter chart data serie to no fill:
((XSSFChart)chart).getCTChart().getPlotArea().getScatterChartArray(0).getSerArray(0)
.addNewSpPr().addNewLn().addNewNoFill();
//set data labels for first scatter chart data serie
((XSSFChart)chart).getCTChart().getPlotArea().getScatterChartArray(0).getSerArray(0)
.addNewDLbls()
.addNewNumFmt().setFormatCode("0.0");
((XSSFChart)chart).getCTChart().getPlotArea().getScatterChartArray(0).getSerArray(0)
.getDLbls().getNumFmt()
.setSourceLinked(false);
((XSSFChart)chart).getCTChart().getPlotArea().getScatterChartArray(0).getSerArray(0)
.getDLbls()
.addNewShowLegendKey().setVal(false);
((XSSFChart)chart).getCTChart().getPlotArea().getScatterChartArray(0).getSerArray(0)
.getDLbls()
.addNewShowCatName().setVal(false);
((XSSFChart)chart).getCTChart().getPlotArea().getScatterChartArray(0).getSerArray(0)
.getDLbls()
.addNewShowSerName().setVal(false);
((XSSFChart)chart).getCTChart().getPlotArea().getScatterChartArray(0).getSerArray(0)
.getDLbls()
.addNewShowPercent().setVal(false);
((XSSFChart)chart).getCTChart().getPlotArea().getScatterChartArray(0).getSerArray(0)
.getDLbls()
.addNewShowBubbleSize().setVal(false);
((XSSFChart)chart).getCTChart().getPlotArea().getScatterChartArray(0).getSerArray(0)
.getDLbls()
.addNewShowVal().setVal(true);
wb.write(new FileOutputStream("CreateExcelScatterChart.xlsx"));
wb.close();
}
}
This code needs the full jar of all of the schemas ooxml-schemas-1.3.jar as mentioned in FAQ-N10025.
This code works using the current last stable release apache poi version 3.17. Note: The Chart code of apache poi is highly in development now. So the code may not work in further releases.
So basing myself on the anwser of #Axel Richter.
Here is the to code used as basis:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.charts.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFChart;
import org.apache.poi.ss.util.CellRangeAddress;
public class CreateExcelScatterChart {
public static void main(String[] args) throws Exception {
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet("chart");
final int NUM_OF_ROWS = 2;
final int NUM_OF_COLUMNS = 20;
Row row;
Cell cell;
//x values
for (int rowIndex = 0; rowIndex < 1; rowIndex++) {
row = sheet.createRow((short) rowIndex);
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
cell = row.createCell((short) colIndex);
cell.setCellValue(4*colIndex * (rowIndex + 1));
}
}
// y values
for (int rowIndex = 1; rowIndex < NUM_OF_ROWS; rowIndex++) {
row = sheet.createRow((short) rowIndex);
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
cell = row.createCell((short) colIndex);
cell.setCellValue(Math.sin(Math.PI*colIndex/10*2));
}
}
Drawing<?> drawing = sheet.createDrawingPatriarch();
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 3, 13, 20);
Chart chart = drawing.createChart(anchor);
ChartLegend legend = chart.getOrCreateLegend();
legend.setPosition(LegendPosition.TOP_RIGHT);
ScatterChartData data = chart.getChartDataFactory().createScatterChartData();
ValueAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
bottomAxis.setCrosses(AxisCrosses.AUTO_ZERO);
for (int i = 0; i < NUM_OF_COLUMNS; i++) {
ChartDataSource<Number> xs = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, i, i));
ChartDataSource<Number> ys = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, i, i));
ScatterChartSeries chartSerie = data.addSerie(xs, ys);
chartSerie.setTitle("My Title " + i);
}
chart.plot(data, bottomAxis, leftAxis);
//set line properties of first scatter chart data serie to no fill:
CTScatterSer[] scatterChartSeries = ((XSSFChart) chart).getCTChart().getPlotArea().getScatterChartArray(0).getSerArray();
for (int i = 0; i < scatterChartSeries.length; i++) {
scatterChartSeries[i].addNewSpPr().addNewLn().addNewNoFill();
}
wb.write(new FileOutputStream("CreateExcelScatterChart.xlsx"));
wb.close();
}
}
It will generate 20 series each one with a title when passing hover and the same title in the legend. There will be as no lines between each marker. So basically it does what I was looking for.
Thank you for your answers.
Ps: In case that you want to use some labels on each marker follow the //set data labels for first scatter chart data serie on #Richet answer
I am creating an Excel file with line chart. I've created chart and filled it with data but I cannot create points on my chart. Does anyone know, is there a way I could generate these points(triangles, squares, circles etc.) in a chart using apache poi?
This is my code for generating current char:
public static void main(String[] args) throws Exception {
Workbook wb = new XSSFWorkbook();
Sheet dataSheet = wb.createSheet("linechart");
final int NUM_OF_ROWS = 10;
final int NUM_OF_COLUMNS = 4;
Row row;
Cell cell;
for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++) {
row = dataSheet.createRow((short) rowIndex);
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
cell = row.createCell((short) colIndex);
cell.setCellValue(rowIndex * ((colIndex + 1) + ((int) (Math.random() * 10))));
}
}
Drawing drawing = dataSheet.createDrawingPatriarch();
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, NUM_OF_COLUMNS + 2, 3, NUM_OF_COLUMNS + 15, 20);
Chart chart = drawing.createChart(anchor);
ChartLegend legend = chart.getOrCreateLegend();
legend.setPosition(LegendPosition.RIGHT);
LineChartData data = chart.getChartDataFactory().createLineChartData();
ChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM);
ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
ChartDataSource<Number> xs = DataSources.fromNumericCellRange(dataSheet, new CellRangeAddress(0, NUM_OF_ROWS - 1, 0, 0));
ChartDataSource<Number> ys1 = DataSources.fromNumericCellRange(dataSheet, new CellRangeAddress(0, NUM_OF_ROWS - 1, 1, 1));
ChartDataSource<Number> ys2 = DataSources.fromNumericCellRange(dataSheet, new CellRangeAddress(0, NUM_OF_ROWS - 1, 2, 2));
ChartDataSource<Number> ys3 = DataSources.fromNumericCellRange(dataSheet, new CellRangeAddress(0, NUM_OF_ROWS - 1, 3, 3));
LineChartSeries series1 = data.addSeries(xs, ys1);
series1.setTitle("one");
LineChartSeries series2 = data.addSeries(xs, ys2);
series2.setTitle("two");
LineChartSeries series3 = data.addSeries(xs, ys3);
series3.setTitle("three");
chart.plot(data, bottomAxis, leftAxis);
XSSFChart xssfChart = (XSSFChart) chart;
CTPlotArea plotArea = xssfChart.getCTChart().getPlotArea();
plotArea.getLineChartArray()[0].getSmooth();
CTBoolean ctBool = CTBoolean.Factory.newInstance();
ctBool.setVal(false);
plotArea.getLineChartArray()[0].setSmooth(ctBool);
for (CTLineSer ser : plotArea.getLineChartArray()[0].getSerArray()) {
ser.setSmooth(ctBool);
}
FileOutputStream fileOut = new FileOutputStream("chart.xlsx");
wb.write(fileOut);
fileOut.close();
}
Solution:
CTPlotArea plotArea = xssfChart.getCTChart().getPlotArea();
CTMarker ctMarker = CTMarker.Factory.newInstance();
ctMarker.setSymbol(CTMarkerStyle.Factory.newInstance());
for (CTLineSer ser : plotArea.getLineChartArray()[0].getSerArray()) {
ser.setMarker(ctMarker);
}
Following code will give you what exactly you are looking for
CTPlotArea plotArea = xssfChart.getCTChart().getPlotArea();
plotArea.getLineChartArray()[0].getSmooth();
CTMarker ctMarker = CTMarker.Factory.newInstance();
ctMarker.setSymbol(CTMarkerStyle.Factory.newInstance());
CTBoolean ctBool = CTBoolean.Factory.newInstance();
ctBool.setVal(false);
plotArea.getLineChartArray()[0].setSmooth(ctBool);
for (CTLineSer ser : plotArea.getLineChartArray()[0].getSerArray()) {
ser.setSmooth(ctBool);
ser.setMarker(ctMarker);
}