Search code examples
javajfreechartrenderer

JFreeChart different colors in different regions for the same dataSeries


In JFreeChart I'm trying to color different regions of an XY line chart/curve based on y value. I'm overriding the XYLineAndShapeRenderer's getItemPaint(int row, int col), however I'm not sure how it handles the coloring of the line between the xs since it's only getting itemPaint on the x (integer values).

final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer() {
    @Override

    @Override
    public Paint getItemPaint(int row, int col) {
        System.out.println(col+","+dataset.getY(row, col));
        double y=dataset.getYValue(row, col);
        if(y<=3)return ColorUtil.hex2Rgb("#7DD2F7");
        if(y<=4)return ColorUtil.hex2Rgb("#9BCB3B");
        if(y<=5)return ColorUtil.hex2Rgb("#FFF100");
        if(y<=6)return ColorUtil.hex2Rgb("#FAA419");
        if(y<=10)return ColorUtil.hex2Rgb("#ED1B24");

        //getPlot().getDataset(col).
        return super.getItemPaint(row,col);
    }
}

Solution

  • It looks like the handling of the colouring between lines is implemented in drawFirstPassShape

    The line colour appears to be based on the preceding point

    enter image description here

    This modification to your XYLineAndShapeRenderer uses a gradient fill to blend the line colour.

    XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(){
            @Override
            public Paint getItemPaint(int row, int col) {
                Paint cpaint = getItemColor(row, col);
                if (cpaint == null) {
                    cpaint = super.getItemPaint(row, col);
                }
                return cpaint;
            }
    
        public Color getItemColor(int row, int col) {
            System.out.println(col + "," + dataset.getY(row, col));
            double y = dataset.getYValue(row, col);
            if(y<=3) return Color.black;
            if(y<=4) return Color.green;;
            if(y<=5) return Color.red;;
            if(y<=6) return Color.yellow;;
            if(y<=10) return Color.orange;;
            return null;
        }
    
        @Override
        protected void drawFirstPassShape(Graphics2D g2, int pass, int series,
            int item, Shape shape) {
            g2.setStroke(getItemStroke(series, item));
            Color c1 = getItemColor(series, item);
            Color c2 = getItemColor(series, item - 1);
            GradientPaint linePaint = new GradientPaint(0, 0, c1, 0, 300, c2);
            g2.setPaint(linePaint);
            g2.draw(shape);
        }
    };
    

    enter image description here

    I've removed ColorUtil.hex2Rgb as I don't have access to that class/method. You may want to modify GradientPaint to take account of the distance/gradient between points.