Apache POI scatter chart creation - java

Currently generating a scatterplot using POI, however the chart comes out weird:
The topleft one is generated using my code, the other one is made manually in Excel.
They are both of the type "scatter with straight lines and markers", the generated chart however shows curved lines for some reason. Another issue is that each of the data-points is listed separately in the legend as well as given another colour.
public void GenerateChart(XSSFSheet sheet) {
XSSFDrawing drawing = sheet.createDrawingPatriarch();
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15);
XSSFChart chart = drawing.createChart(anchor);
XSSFChartLegend legend = chart.getOrCreateLegend();
legend.setPosition(LegendPosition.TOP_RIGHT);
XSSFValueAxis bottomAxis = chart.createValueAxis(AxisPosition.BOTTOM);
XSSFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
CellRangeAddress crXData = new CellRangeAddress(1, sheet.getLastRowNum(), 0, 0);
CellRangeAddress crYData = new CellRangeAddress(1, sheet.getLastRowNum(), 1, 1);
CellReference crTitle = new CellReference(0,1);
Cell cell = sheet.getRow(crTitle.getRow()).getCell(crTitle.getCol());
ChartDataSource<Number> dsXData = DataSources.fromNumericCellRange(sheet, crXData);
ChartDataSource<Number> dsYData = DataSources.fromNumericCellRange(sheet, crYData);
XSSFScatterChartData data = chart.getChartDataFactory().createScatterChartData();
ScatterChartSeries seriesTitler = data.addSerie(dsXData, dsYData);
seriesTitler.setTitle(cell.getStringCellValue());
chart.plot(data, bottomAxis, leftAxis);
}
Using Apache POI 3.17
Documentation here shows that XSSFScatterChartData and others are deprecated, and that I should be using XDDFScatterChartData instead. However I cannot figure out where to get the .jar to use this. I'm assuming it's in beta?
What I want to do is to generate something like the chart on the right of the image, the manually created one. Since POI allowing chart creation seems to be a relatively new thing, I haven't been able to find any clues. Anyone know the trick?

The problems are changed defaults for Excel charts in newer Excel versions.
There is a setting for smooth the line in scatter charts. Apache poi does not set this. But now in newer Excelversions this option defaults to true if it is not set.
Also there is a setting for vary the colors of each data point. Also apache poi does not set this. But now in newer Excelversions this option defaults to true if not set.
So we need setting both of those options to false as wanted:
...
chart.plot(data, bottomAxis, leftAxis);
//set properties of first scatter chart data series to not smooth the line:
((XSSFChart)chart).getCTChart().getPlotArea().getScatterChartArray(0).getSerArray(0)
.addNewSmooth().setVal(false);
//set properties of first scatter chart to not vary the colors:
((XSSFChart)chart).getCTChart().getPlotArea().getScatterChartArray(0)
.addNewVaryColors().setVal(false);
...
Unfortunately the https://poi.apache.org/apidocs/ is not the POI API Documentation for the latest stable release but for the current "Nightly Build". So for using the XDDF instead of XSSF one needs using the nightly builds which of course are not stable releases which should be used in productive code.

Related

Aspose slides 'Area chart' series value not shown in the tooltip

I am using aspose-slides-17.3-jdk16.jar for java. I have created the Area Chart using IChartDataWorkbook and I'm able to get the series values in the tool tip for all the charts except Area chart.
Following is the code I have done so far.
public class AreaChartSlide {
public static void main(String[] args) {
Presentation pres = new Presentation();
ISlide slide = pres.getSlides().get_Item(0);
// Creating the default chart
IChart chart = slide.getShapes().addChart(ChartType.Area, 0, 0, 500, 400);
// Getting the default chart data worksheet index
int defaultWorksheetIndex = 0;
// Getting the chart data worksheet
IChartDataWorkbook fact = chart.getChartData().getChartDataWorkbook();
// Delete demo series
chart.getChartData().getSeries().clear();
// Add new series
chart.getChartData().getSeries().add(fact.getCell(defaultWorksheetIndex, 0, 1, "Series 1"), chart.getType());
chart.getChartData().getSeries().add(fact.getCell(defaultWorksheetIndex, 0, 2, "Series 2"), chart.getType());
// Adding new categories
chart.getChartData().getCategories().add(fact.getCell(defaultWorksheetIndex, 1, 0, "Cat 1"));
chart.getChartData().getCategories().add(fact.getCell(defaultWorksheetIndex, 2, 0, "Cat 2"));
// Take first chart series
IChartSeries series = chart.getChartData().getSeries().get_Item(0);
// Now populating series data
series.getDataPoints().addDataPointForAreaSeries(fact.getCell(defaultWorksheetIndex, 1, 1, 20));
series.getDataPoints().addDataPointForAreaSeries(fact.getCell(defaultWorksheetIndex, 2, 2, 50));
// Setting fill color for series
series.getFormat().getFill().setFillType(FillType.Solid);
series.getFormat().getFill().getSolidFillColor().setColor(Color.RED);
// Take second chart series
series = chart.getChartData().getSeries().get_Item(1);
// Now populating series data
series.getDataPoints().addDataPointForAreaSeries(fact.getCell(defaultWorksheetIndex, 2, 1, 30));
series.getDataPoints().addDataPointForAreaSeries(fact.getCell(defaultWorksheetIndex, 2, 2, 10));
series.getFormat().getFill().setFillType(FillType.Solid);
series.getFormat().getFill().getSolidFillColor().setColor(Color.GREEN);
pres.save("E:/PPT/Aspose.pptx", SaveFormat.Pptx);
System.out.println("done");
}
Below is the chart output i got
Any help would be greatly appreciated.
I have worked with shared sample code using Aspose.Slides for Java 17.5 on my end and have generated a presentation with Area chart having two series and two categories. I have opened the generated presentation in PowerPoint and able to observe the tool-tip text for both chart series. Please observe Series 1 and Series 2 tool-tip text display for your kind reference. I hope the shared information will be helpful. Please share, if I may help you further in this regard.
I am working as Support developer/ Evangelist at Aspose.
We are sorry for your inconvenience.
I have observed your comments and comparison image of tool-tip text display for Bar chart and Area chart. I like to add here that this is not some issue in Aspose.Slides charting engine but its a PowerPoint implementation. If you add an Area chart using PowerPoint, that too will display the point and series name in tool-tip text. Please observe the tool-tip text for slides 2 and 3 in this presentation. You can observe in this snapshot as well that tool-tip text for PowerPoint generated chart is also displaying series and point as it is being shown for similar chart type generated using Aspose.Slides. I hope the shared information will be helpful.
I am working as Support developer/ Evangelist at Aspose.
Many Thanks.

How to create shapes on a JFreeChart line chart?

I would like to have shapes (small squares) that mark data points in the line chart that I am creating with ChartFactory.createLineChart().
It should look something like this (this image was not created with JFreeChart):
I have followed the description here, however, they don't appear for me. This is what the output from my JFreeChart software looks like:
My code is:
JFreeChart lineChart = ChartFactory.createLineChart(...);
CategoryPlot plot = (CategoryPlot) lineChart.getPlot();
plot.getRenderer().setBaseShape(
new Rectangle2D.Double(-20.0, -20.0, 40.0, 40.0));
I also tried using setSeriesShape instead of setBaseShape for all the series I'm plotting, it didn't make any difference either.
What am I doing wrong?
Given a reference to the renderer,
LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer();
Invoke setBaseShapesVisible() to enable the shapes provided by your chosen DrawingSupplier.
renderer.setBaseShapesVisible(true);
To change the appearance, pass a custom Shape to setSeriesShape() for the desired series.
renderer.setSeriesShape(0, new Ellipse2D.Double(-3d, -3d, 6d, 6d));
From JFreechart 1.5.0
LineAndShapeRenderer renderer = (LineAndShapeRenderer) lineChart.getCategoryPlot().getRenderer();
renderer.setDefaultShapesVisible(true);

JFreeChart Smudging of lines in Candlestick Chart

This has reference to JFreeChart rendering of candlestick charts. Below is the code fragment that generates a candle stick chart with JFreeChart.
This code has been tested and has been working for a long time. However, the version of JFreeChart was changed from 1.0.17 to 1.0.19 and the candlestick chart generated with 1.0.19 is showing smudging of the candle objects/lines. When I changed the library back to 1.0.17, the candlestick objects/lines once again becomes clear.
The images with both the libraries are provided below.
I have tried to find the cause of this and have been unsuccessful as yet. Now, the question is, since the code is tested and possibly does not have any error (at least what I can figure or am I missing something?), is the issue with the library? Have anyone faced this problem and has an work around
I shall be rather grateful, if someone has found the reason/solution to this and shared the same.
Please use MS Paint to view the images.
try{
chart=ChartFactory.createCandlestickChart("Candlestick Chart", "Date", "EOD Closing Price", (OHLCDataset)dataset, true);
plot=(XYPlot)chart.getPlot();
CandlestickRenderer renderer=new Chart_CandlestickRenderer();//(CandlestickRenderer)plot.getRenderer();
renderer.setSeriesPaint(0, Color.BLACK);
renderer.setUpPaint(Color.WHITE);
renderer.setDownPaint(Color.BLACK);
//HighLowItemLabelGenerator candleTooltipGenerator=new HighLowItemLabelGenerator(new SimpleDateFormat("dd-MMM-yyyy"), new DecimalFormat());
XYToolTipGenerator candleTooltipGenerator=Chart_TooltipProvider.getOHLCTooltipGenerator();
renderer.setBaseToolTipGenerator(candleTooltipGenerator);
plot.setRenderer(0,renderer);
//Organize the data to draw Fibbonacci retracements with highs and lows
DefaultOHLCDataset ohlcDataset=(DefaultOHLCDataset)dataset;
int dataCount=ohlcDataset.getItemCount(0);
data=new double[dataCount*2];//for each data item we shall get 2 values, high and low
for(int i=0;i<dataCount;i++){
//for each i 2 data values need to be put into the array and adjust the index accordingly
data[i*2]=ohlcDataset.getHighValue(0, i);
data[i*2+1]=ohlcDataset.getLowValue(0, i);
}//for closing
//If there is only the candlestick to be drawn, return, as the job has been done, draw the Fibonnaci and return
if(indicators.length==1){
this.drawFibonnaciRetracement(data, plot);
retVal=true;
return retVal;
}//if closing
}catch(Exception e){e.printStackTrace();return retVal;}
Try setting setAntiAlias of the JFreeChart to false.
JFreeChart chart = ChartFactory.createCandlestickChart(...);
chart.setAntiAlias(false);

Generating PDF report : jFreeChart and DynamicReports

I need to generate a report as shown below:
I have designed a GUI using swing in NetBeans to enter the details:
The Plot I have generated using jFreeChart:
JFreeChart chart = ChartFactory.createXYLineChart(
"Hysteresis Plot", // chart title
"Pounds(lb)", // domain axis label
"Movement(inch)", // range axis label
dataset, // data
PlotOrientation.VERTICAL, // orientation
false, // include legend
true, // tooltips
false // urls
);
OutPut:
I was searching the internet and read that I can use iText or JasperReports or DynamicReports (Based on Jasper Report)
http://www.dynamicreports.org/getting_started.html#step9
I found using Dynamic Reports easier. My question is- can i use DynamicReports for my purpose (I suppose- yes looking at the sample reports) and if yes then how do I export my jFreeChart to the report.
Please help as I do not have much time left to complete this project.
Thanks
You can create the chart directly in DynamicReports instead of JFreeChart. Use the DynamicReports XYLineChartReport component to do this. See the example code at http://www.dynamicreports.org/examples/xylinechartreport.html.
If you want to use the JFreeChart output, export the chart to an image and then include that image in the report using cmp.image():
// Create the chart.
JFreeChart chart = ChartFactory.createXYLineChart(
"Hysteresis Plot", // chart title
"Pounds(lb)", // domain axis label
"Movement(inch)", // range axis label
dataset, // data
PlotOrientation.VERTICAL, // orientation
false, // include legend
true, // tooltips
false // urls
);
// Export the chart to an image.
BufferedImage image = chart.createBufferedImage( 300, 300);
report()
.title(cmp.text("XYZ HOSPITAL"))
.columns(fieldNameColumn, fieldValueColumn)
.summary(
cmp.verticalList()
.add(cmp.text("HYSTERISIS PLOT"))
.add(cmp.text("A brief description of what this plot signifies"))
.add(cmp.image(image)) // Add the exported chart image to the report.
.add(cmp.text("REMARKS"))
)
.setDataSource(createDataSource())
.toPDF(outputStream);

How to customize series fill in area chart via BIRT chart API?

I am trying to create a gradient fill for a series in an area chart that I am building through the BIRT chart API, but the book "Integrating and Extending BIRT" and the Interwebs seem curiously silent about how to get it to work. It seems no matter what I do, I always get a flat color from the default palette. I've tried using SeriesDefinition.getSeriesPalette().update(Gradient) and even creating my own Palette with the gradient fill in it and setting that on the SeriesDefinition, but to no avail. I've also noticed that if I do not perform a shift() on the Palette, even if it's shift(0), which the Javadocs claim will do nothing, I get NullPointerException when I try to generate the chart:
Caused by: java.lang.NullPointerException
at org.eclipse.birt.chart.render.Area.renderDataPoints(Area.java:521)
at org.eclipse.birt.chart.render.Line.renderSeries(Line.java:570)
at org.eclipse.birt.chart.render.AxesRenderer.renderPlot(AxesRenderer.java:2181)
at org.eclipse.birt.chart.render.AxesRenderer.render(AxesRenderer.java:314)
at org.eclipse.birt.chart.factory.Generator.render(Generator.java:1368)
... 108 more
Here's the latest (non-working) code that I've tried:
Gradient gradient = FillUtil.createDefaultGradient(BirtReportBuilder.COLOR_WHITE);
gradient.setStartColor(ColorDefinitionImpl.WHITE());
gradient.setEndColor(ColorDefinitionImpl.create(76, 116, 131));
gradient.setDirection(90);
SeriesDefinition sdY = SeriesDefinitionImpl.create();
sdY.getQuery().setDefinition("\"Quantity\"");
Palette pal = PaletteImpl.create(gradient);
pal.shift(0);
sdY.setSeriesPalette(pal);
sdY.getSeries().add(as1);
yAxisPrimary.getSeriesDefinitions().add(sdY);
So what's the magic incantation to get the BIRT charting API to use my Gradient as the area fill?
This code works for me, I get a ugly coloured serie...
sdY.getSeriesPalette().update(GradientImpl.create(ColorDefinitionImpl.create(255,255,255), ColorDefinitionImpl.create(200,0,0,150), 90, false));
Hope it will help you ;p

Categories