Search code examples
javajfreechart

JFreechart fill color outside polygon


I create a polygon annotation on my chart and would like to know how to fill the chart with color only outside of the drawn polygon. I'm using Jfreechart 1.0.17.

I do it this way at the moment:

Color plotBackground = (Color) plot.getBackgroundPaint();
plot.setBackgroundPaint(new Color(0xff0000));
XYLineAndShapeRenderer renderer
   = (XYLineAndShapeRenderer) plot.getRenderer();

XYPolygonAnnotation a = new XYPolygonAnnotation(new double[] {2.0,
   5.0, 2.5, 8.0, 3.0, 5.0, 2.5, 2.0}, null, null,
   new Color(plotBackground.getRed(), plotBackground.getGreen(),
             plotBackground.getBlue(), 255));

But it is not really what I want, we can't see grid lines this way.

Here is possible solution :

    Rectangle2D r2d = new Rectangle2D.Double(plot.getQuadrantOrigin().getX(),
                                             plot.getQuadrantOrigin().getY(),
                                             3.2, 9);
    Area a1 = new Area(r2d);
    Path2D.Float p = new Path2D.Float();
    p.moveTo(2.0, 5.0);
    p.lineTo(2.5, 8.0);
    p.lineTo(3.0, 5.0);
    p.lineTo(2.5, 2.0);
    p.closePath();
    Area a2 = new Area(p);
    a1.subtract(a2);

    XYShapeAnnotation a = new XYShapeAnnotation(a1, new BasicStroke(), 
                                                new Color(0xff0000), 
                                                new Color(0xff0000));
    renderer.addAnnotation(a, Layer.BACKGROUND);

Solution

  • Looking into jfreecharts source code the annotations are always drawn after gridlines are painted. So there seems to be no possiblity to draw them before the gridlines. I would give the XOR - mode drawing a try.

    XYPolygonAnnotation a = new XYPolygonAnnotation(new double[]{2.0,
                5.0, 2.5, 8.0, 3.0, 5.0, 2.5, 2.0}, null, null,
                    new Color(plotBackground.getRed(), plotBackground.getGreen(),
                 plotBackground.getBlue(), 255)) {
    
                @Override
                public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea, ValueAxis domainAxis, ValueAxis rangeAxis, int rendererIndex, PlotRenderingInfo info) {
                    Graphics2D g22 = (Graphics2D) g2.create();
                    g22.setXORMode(new Color(0xff0000));
                    super.draw(g22, plot, dataArea, domainAxis, rangeAxis, rendererIndex, info); 
                }
            };
    
    renderer.addAnnotation(a,  Layer.BACKGROUND);
    

    With xor combined drawing the annotations are somekind merged with the background and the gridlines. So the following result appears:

    simplegraph