JFreeChart border line for areas? - java

I have a dynamic XYAreaChart and I want line borders to be clear because the area is all filled with a gradient color but I want the line borders to be in different color, for example my area is filled with gradient green and red color and I want the line borders to be in black color. How to do this?
Here's my code:
final XYSeries series = new XYSeries("Data");
XYSeriesCollection dataset = new XYSeriesCollection(series);
// Creation du area chart
JFreeChart chart = ChartFactory.createXYAreaChart("Fun Meter", "", "",
dataset, PlotOrientation.VERTICAL, false, false, false);
// jframe=new ChartFrame("Fun Meter", chart);
ChartPanel CP = new ChartPanel(chart);
XYPlot xyPlot = (XYPlot) chart.getPlot();
GradientPaint gp0 = new GradientPaint(0.0f, 100.0f, new Color(50, 205,
50), 0.0f, 100.0f, Color.red);
xyPlot.getRenderer().setSeriesPaint(0, gp0);
xyPlot.setForegroundAlpha(0.75f);

You should use the setSeriesOutlinePaint(int, Paint) method on the renderer.
Assuming you use a XYAreaRenderer
So something like:
XYAreaRenderer renderer = (XYAreaRenderer) xyPlot.getRenderer();
renderer.setSeriesOutlinePaint(0, Color.black);
renderer.setSeriesOutlineStroke(0, new BasicStroke(0.5f));
renderer.setOutline(true);

Related

Issues creating a jfreechart score bar/chart

I am trying to create a score/percent/status bar using jfreechart.
The image show what it's suppose to look like.Good ScoreChart
It looks like one bar from a stack chart, so I try to adjust from there. (Do let me know if there is a better way to do this other than the stack chart)
I am seeing multiple issues doing the bar this way. I can't make the start line and end line longer. I can't put text on top of both start/end line.(I think they get chopped off) I cannot put center text in the middle of the bar either...
Here is what I got now. Bad ScoreChart
Here is the code for the bad Chart.
public JFreeChart createChart(final CategoryDataset dataset) {
final JFreeChart chart = ChartFactory.createStackedBarChart(null, null, null, dataset,
PlotOrientation.HORIZONTAL, false, false, false);
chart.setBackgroundPaint(Color.WHITE);
CategoryPlot plot = chart.getCategoryPlot();
((BarRenderer) plot.getRenderer()).setBarPainter(new StandardBarPainter());
plot.getRenderer().setSeriesPaint(0, DONUT_CHART_ORANGE);
plot.getRenderer().setSeriesPaint(1, DONUT_CHART_BLUE);
ValueAxis rangeAxis = plot.getRangeAxis();
rangeAxis.setVisible(false);
CategoryAxis domainAxis = plot.getDomainAxis();
domainAxis.setVisible(false);
plot.setRangeGridlinesVisible(false);
plot.setBackgroundPaint(Color.WHITE);
plot.setOutlineVisible(false);
CategoryItemRenderer renderer = ((CategoryPlot) chart.getPlot()).getRenderer();
//renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setBaseItemLabelGenerator(new CustomItemLabelGenerator());
renderer.setBaseItemLabelsVisible(true);
ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.CENTER, TextAnchor.CENTER);
renderer.setBasePositiveItemLabelPosition(position);
Marker startMarker = new ValueMarker(0);
startMarker.setPaint(Color.black);
startMarker.setLabel("000000000");
startMarker.setStroke(new BasicStroke(1.0f));
startMarker.setLabelOffset( new RectangleInsets(UnitType.ABSOLUTE, 10,0,0,0));
startMarker.setLabelAnchor(RectangleAnchor.TOP_RIGHT) ;
startMarker.setLabelTextAnchor(TextAnchor.BASELINE_CENTER);
plot.addRangeMarker(startMarker);
Marker endMarker = new ValueMarker(1000);
endMarker.setPaint(Color.black);
endMarker.setLabel("1000");
endMarker.setStroke(new BasicStroke(1.0f));
endMarker.setLabelAnchor(RectangleAnchor.TOP);
endMarker.setLabelTextAnchor(TextAnchor.TOP_RIGHT);
plot.addRangeMarker(endMarker);
RectangleInsets chartRectangle = new RectangleInsets(35, 0, 35, 0);
chart.setPadding(chartRectangle);
return chart;
}
public CategoryDataset createDataset() {
double inValue = 775;
double[][] data = new double[][] {
{ inValue },
{ 1000- inValue },
};
return DatasetUtilities.createCategoryDataset("A", "B", data);
}
Any Idea how to move the text so they show up on top of the lines and at the center of the bar?
Can we adjust the line width at the beginning and the end?
Thanks for any idea/info.

How to customize legend of a BoxAndWhisker plot

I've created a BoxAndWhiskerRenderer plot using JFreeChart and it seems that it is automatically creating a sort of legend (see attached picutre).
Is there a way to remove the outside border of this legend and customize the font of the labels in the legend items?
Here is an example of my code:
//Get the desired BoxAndWhiskerCategoryDataset from a LinkedHashMap
BoxAndWhiskerCategoryDataset dataset = values.get(b);
//Create X axis
CategoryAxis xAxis = new CategoryAxis();
xAxis.setAxisLineVisible(false);
//Create Y axis
NumberAxis yAxis = new NumberAxis(b.getLabel());
yAxis.setAxisLineVisible(false);
yAxis.setTickLabelFont(FDFont.getFont(12f));
yAxis.setLabelFont(FDFont.getFont());
yAxis.setLabelPaint(FDPalette.secondaryText);
yAxis.setTickLabelPaint(FDPalette.secondaryText);
yAxis.setAutoRangeIncludesZero(false);
//Create renderer
BoxAndWhiskerRenderer renderer = new BoxAndWhiskerRenderer();
int count = 0;
for(Map.Entry<Integer,Color> map : clusterColor.entrySet()){
//Set color for the series (I have a previously created map which links colors and series)
renderer.setSeriesPaint(count,map.getValue());
count++;
}
renderer.setFillBox(true);
renderer.setToolTipGenerator(new BoxAndWhiskerToolTipGenerator());
CategoryPlot plot = new CategoryPlot(dataset, xAxis, yAxis, renderer);
JFreeChart chart = new JFreeChart(plot);
chart.setBackgroundPaint(white);
chart.setBorderVisible(false);
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new java.awt.Dimension(300, 270));
As shown here, the simplest JFreeChart constructor adds a legend by default. The code for doing so is seen here; simply substitute your desired frame, color and position.
Starting from this example, the following changes produce the chart shown below:
private void createChartPanel() {
…
JFreeChart chart = new JFreeChart("BoxAndWhiskerDemo", plot);
LegendTitle legend = chart.getLegend();
legend.setFrame(new LineBorder(Color.white, new BasicStroke(1.0f),
new RectangleInsets(1.0, 1.0, 1.0, 1.0)));
legend.setItemFont(legend.getItemFont().deriveFont(16f));
chartPanel = new ChartPanel(chart);
}
Compare to this default legend:

Jfreechart.draw() throws a Nullpointerexception

Issue: chart.draw((Graphics2D) emffile.create(), new Rectangle(1500, 600)) throws a Nullpointerexception.
The bar chart can be generated. Please help to look into the issue.
Here my code:
CategoryDataset dataset = createDataset();
JFreeChart chart = createChart(dataset);
emffile = new EMFGraphics2D(
new File("C:\\Workspace\\eclipse\\MSReoprt\\chart.emf"),
new Dimension(1500, 600)
);
emffile.setDeviceIndependent(true);
emffile.setRenderingHint(
RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY
);
emffile.setRenderingHint(
RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_NORMALIZE
);
emffile.startExport();
chart.draw((Graphics2D) emffile.create(), new Rectangle(1500, 600));
emffile.endExport();
emffile.closeStream();
Category and jfreechart method:
private CategoryDataset createDataset()
{
String series = "Availability";
String category1 = "Portal";
String category2 = "DB";
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(100, series, category1);
dataset.addValue(90, series, category2);
return dataset;
}
public JFreeChart createChart(CategoryDataset dataset)
{
FreeChart chart = ChartFactory.createBarChart
(
"Bar Chart Demo", //chart title
"Category", //domain axis label
"", //range axis label
dataset, //data
PlotOrientation.VERTICAL, //orientation
true, //include legend
true, //tooltips?
false //URLs?
);
//set the background color for the chart...
chart.setBackgroundPaint(Color.white);
//get a reference to the plot for further customisation...
CategoryPlot plot = chart.getCategoryPlot();
plot.setBackgroundPaint(Color.white);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.gray);
//set the range axis to display integers only...
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
//disable bar outlines...
BarRenderer renderer = (BarRenderer) plot.getRenderer();
renderer.setDrawBarOutline(false);
renderer.setMaximumBarWidth(0.5);
renderer.setItemMargin(4);
//set up gradient paints for series...
GradientPaint gp0 = new GradientPaint(
0.0f, 0.0f, Color.blue,
0.0f, 0.0f, Color.MAGENTA
);
//GradientPaint gp1 = new GradientPaint(0.0f, 0.0f, Color.green,
//0.0f, 0.0f, Color.lightGray);
//GradientPaint gp2 = new GradientPaint(0.0f, 0.0f, Color.red,
//0.0f, 0.0f, Color.lightGray);
renderer.setSeriesPaint(0, gp0);
//renderer.setSeriesPaint(1, gp1);
//renderer.setSeriesPaint(2, gp2);
CategoryAxis domainAxis = plot.getDomainAxis();
domainAxis.setCategoryLabelPositions(
CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 6.0)
);
return chart;
}
Add stack trace:
Exception in thread "main" java.lang.NullPointerException
at org.freehep.graphicsio.emf.EMFGraphics2D.writePen(EMFGraphics2D.java:679)
at org.freehep.graphicsio.emf.EMFGraphics2D.writeStroke(EMFGraphics2D.java:575)
at org.freehep.graphicsio.AbstractVectorGraphicsIO.setStroke(AbstractVectorGraphicsIO.java:981)
at org.jfree.chart.plot.Plot.drawOutline(Plot.java:1125)
at org.jfree.chart.renderer.category.AbstractCategoryItemRenderer.drawOutline(AbstractCategoryItemRenderer.java:717)
at org.jfree.chart.plot.CategoryPlot.draw(CategoryPlot.java:3684)
at org.jfree.chart.JFreeChart.draw(JFreeChart.java:1229)
at org.jfree.chart.JFreeChart.draw(JFreeChart.java:1112)
at chart.BarChartDemo.export(BarChartDemo.java:61)
at chart.BarChartDemo.test(BarChartDemo.java:39)
at chart.BarChartDemo.main(BarChartDemo.java:137)
I posted this answer in the JFreeChart forum:
This looks to me like a bug in the EMFGraphics2D class. The null
pointer exception is happening at line 679:
678 private void writePen(BasicStroke stroke, Color color) throws IOException {
679 if (color.equals(penColor) && stroke.equals(getStroke()))
I didn't run the code, but presumably either 'color' or 'stroke' is
null. Since the code arrives here from line 575, it seems that
'color' is the null item (because 'stroke' isn't null, as it passed
the instance of test):
573 public void writeStroke(Stroke stroke) throws IOException {
574 if (stroke instanceof BasicStroke) {
575 writePen((BasicStroke) stroke, getColor());[/code]
Now in all the Graphics2D implementations I've seen, getColor()
never returns null (I've written test cases to explore this behaviour). But inspecting the EMFGraphics2D code, it seems as though
this is the default plus any call to setPaint() with a non-Color
argument will reset the colour to null. I think that is wrong.

JFreechart XYAreaChart changing color

I have an area chart , I want to color the area of the chart which is >0 in green and the area which is <0 in red. I tried the SetSeriesPaint() method but it makes all the area chart colored by one color. How to do this?
Here's my code:
final XYSeries series = new XYSeries("Data");
XYSeriesCollection dataset = new XYSeriesCollection(series);
JFreeChart chart = ChartFactory.createXYAreaChart("Fun Meter", "", "",
dataset, PlotOrientation.VERTICAL, false, false, false);
// jframe=new ChartFrame("Fun Meter", chart);
ChartPanel CP = new ChartPanel(chart);
XYPlot xyPlot = (XYPlot) chart.getPlot();
xyPlot.getRenderer().setSeriesPaint(0, Color.red);
xyPlot.setForegroundAlpha(0.75f);
Use a XYDifferenceRenderer:
XYDifferenceRenderer r = new XYDifferenceRenderer(Color.green,Color.red, false);
plot.setRenderer(r);

java How to GradientPaint a JFreeChart AreaChart

public static JFreeChart createAreaChart(double[] v1) {
XYSeriesCollection dataset = new XYSeriesCollection();
XYSeries series1 = new XYSeries("First");
for (int i=0;i<v1.length;i++){
series1.add( i,v1[i]);
}
dataset.addSeries(series1);
final JFreeChart chart = ChartFactory.createXYAreaChart(
"XY Area Chart Demo",
"Domain (X)", "Range (Y)",
dataset,
PlotOrientation.VERTICAL,
true, // legend
true, // tool tips
false // URLs
);
GradientPaint gp0 = new GradientPaint(
0.0f, 0.0f, Color.red,
0.0f, 100.0f, Color.blue
);
chart.setBackgroundPaint(Color.white);
final XYPlot plot = chart.getXYPlot();
plot.getRenderer().setSeriesPaint(0, gp0);
//plot.setOutlinePaint(Color.black);
plot.setBackgroundPaint(Color.lightGray);
plot.setForegroundAlpha(0.99f);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
final ValueAxis domainAxis = plot.getDomainAxis();
domainAxis.setTickMarkPaint(Color.black);
domainAxis.setLowerMargin(0.0);
domainAxis.setUpperMargin(0.0);
final ValueAxis rangeAxis = plot.getRangeAxis();
rangeAxis.setTickMarkPaint(Color.black);
rangeAxis.setAutoRange(false);
rangeAxis.setRange(-5.0, 5.0);
return chart;
}
I want something like this below. A gradient fill that switches colour slowly as we cross zero line.
I do not understand what I should put in:
GradientPaint gp0 = new GradientPaint(
0.0f, 0.0f, Color.red,
0.0f, 100.0f, Color.blue
);
The best way to do this is to have 3 shapes. One for the yellow line. Another for the green gradient, and a 3rd for the red gradient.
Then you paint the two last shapes independently.
I believe a better starting place would be a XYDifferenceRenderer have one series stay a zero so that when the second seires passes it the color will change.. Take a look at DifferenceChartDemo1 in JFreeChart. Put your two different Color GradientPaints in the constructor of the renderer.
Here is the API link the Renderer:
http://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart/renderer/xy/XYDifferenceRenderer.html

Categories

Resources