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);
Related
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.
We are using the jfreechart with Jasper reports and we are struggling to put the benchmark line on the bar chart.
How can this be achieved using jasper reports?
To customize your bar chart in jasper report create a customizer class (ChartCustomizer) extending the JRChartCustomizer.
public void customize(JFreeChart chart, ChartComponent chartComponent)
{
//get the ploy
CategoryPlot plot = (CategoryPlot) chart.getPlot();
//Now add your markers
ValueMarker vm = new ValueMarker(200); //200 is the position you like it to be
vm.setPaint(Color.RED);
vm.setStroke(new BasicStroke(1));
vm.setLabel("BeanchMark value"); //The label
vm.setLabelAnchor(RectangleAnchor.TOP);
vm.setLabelTextAnchor(TextAnchor.BOTTOM_RIGHT);
plot.addRangeMarker(vm);
}
add the class to classpath and in jrxml set the customizerClass attribute
<barChart>
<chart customizerClass="my.package.ChartCustomizer">
....
</chart>
...
</barChart>
We have resolved it by using the following code in customise class
ValueMarker marker = new ValueMarker(30);
marker.setLabel("Average 30%");
marker.setPaint(Color.black);
plot.addRangeMarker(marker);
However we need to change the label position, currently it is showing at the start of the line.
For one single horizontal line you can use provided chart customizer:
Go to Chart -> Properties -> Chart (tab) -> Chart customizers
There you can add a Range Interval Marker and configure it with start and end values with the desired value (35 in your example).
This way an horizontal line will be drawn in the 35 vertical value as you wanted.
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);
my bar chart is always drawn with a gradient color by default. I just want a simple color without any styled effects.
Can anyone help ?
Code:
final JFreeChart chart = ChartFactory.createBarChart(
"", // chart title
xLabel, // domain axis label
yLabel, // range axis label
dataset, // data
PlotOrientation.VERTICAL, // orientation
true, // include legend
false, // tooltips?
false // URLs?
);
final CategoryPlot plot = chart.getCategoryPlot();
// SOMETHING HAS TO BE DONE HERE
showChart(chart); // Simply shows the chart in a new window
Thanks
The problem lies in the BarPainter you are using. The JFreeChart version 1.0.13 default is to use GradientBarPainter which adds a metallic-ish look to the bar. If you want the "old" look the solution is to use the StandardBarPainter.
final CategoryPlot plot = chart.getCategoryPlot();
((BarRenderer) plot.getRenderer()).setBarPainter(new StandardBarPainter());
That should do it.
Alternatively, if you want use JFreeChart's BarRenderer, you could force it to use the StandardBarPainter by calling the static method setDefaultBarPainter() before initializing your renderer.
final CategoryPlot plot = chart.getCategoryPlot();
BarRenderer.setDefaultBarPainter(new StandardBarPainter());
((BarRenderer) plot.getRenderer()).setBarPainter(new BarPainter());
If you want more control of the chart you can always build it from the ground up instead of using ChartFactory, but that does require a lot extra code.
Before you create the chart from ChartFactory you can set the chart theme:
ChartFactory.setChartTheme(StandardChartTheme.createLegacyTheme());
The default is the JFreeTheme which adds the gradient. The following themes are available:
ChartFactory.setChartTheme(StandardChartTheme.createJFreeTheme());
ChartFactory.setChartTheme(StandardChartTheme.createDarknessTheme());
The source code for an older version of org.jfree.chart.demo.BarChartDemo1 shows how to set the series colors. Just specify plain colors instead of gradients.
renderer.setSeriesPaint(0, Color.red);
renderer.setSeriesPaint(1, Color.green);
renderer.setSeriesPaint(2, Color.blue);
Correction: The key to #Jes's helpful answer may be found in the initialization of defaultBarPainter in BarRenderer.
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