Setting Target Line In JFreeCharts

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
omuiri166
Posts: 3
Joined: Sun Apr 06, 2014 6:18 pm
antibot: No, of course not.

Setting Target Line In JFreeCharts

Post by omuiri166 » Sun Apr 06, 2014 6:39 pm

Hi There,
I have a BarGraph which contains no fixed amount of bars, it depends on the logged in user

see here for a sample graph i wish to produce [img][https://www.google.ie/search?q=pasture+ ... B500%3B220]

I want to calculate the grey line in the image above.

the Target Line(grey line in image) has two points based on some computed figures which would roughly be

point1=(0.0, computedValue1 that corresponds to the y-axis)

point2(theEndLastBar, some computed value that corresponds to the y-axis)

***************NOTE****************************
ValueMarker will not work either as the line has a high point and a low point, the high point being point 1 and the low point being point 2

***************ENDNOTE**************************************

Am use DefaultCategoryDataset to create the chart and use the addValue Method.

I have tried using CategoryLineAnnotation but seem to get it correct.

Could someone please help me out please..

omuiri166
Posts: 3
Joined: Sun Apr 06, 2014 6:18 pm
antibot: No, of course not.

Re: Setting Target Line In JFreeCharts

Post by omuiri166 » Mon Apr 07, 2014 3:09 pm

I have tried using CategoryLineAnnotation but can't seem to get it correct as I keep getting an error category index -1,


Could someone please help me out please..

david.gilbert
JFreeChart Project Leader
Posts: 11734
Joined: Fri Mar 14, 2003 10:29 am
antibot: No, of course not.
Contact:

Re: Setting Target Line In JFreeCharts

Post by david.gilbert » Tue Apr 08, 2014 10:27 am

CategoryLineAnnotation will work fine, you need to read the first and last category from the dataset and the corresponding values:

Code: Select all

        Comparable firstKey = dataset.getColumnKey(0);
        double firstValue = dataset.getValue("Series 1", firstKey).doubleValue();
        Comparable lastKey = dataset.getColumnKey(dataset.getColumnCount() - 1);
        double lastValue = dataset.getValue("Series 1", lastKey).doubleValue();
        CategoryLineAnnotation annotation = new CategoryLineAnnotation(
            firstKey, firstValue, lastKey, lastValue, Color.GRAY, 
                new BasicStroke(3.0f));
        plot.addAnnotation(annotation);
Here is a self-contained demo using the above code:

Code: Select all

/* ------------------
 * BarChartDemo2.java
 * ------------------
 * (C) Copyright 2014, by Object Refinery Limited.
 * 
 */

package org.jfree.chart.demo;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.CategoryLineAnnotation;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

public class BarChartDemo2 extends ApplicationFrame {

    public BarChartDemo2(String title) {
        super(title);
        JFreeChart chart = createChart(createDataset());
        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new Dimension(500, 270));
        setContentPane(chartPanel);
    }

    private static CategoryDataset createDataset() {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        int barCount = (int) (Math.random() * 8 + 2);
        for (int i = 0; i < barCount; i++) {
            dataset.addValue(Math.random() * 10.0, "Series 1", "C" + i);
        }
        return dataset;
    }

    private static JFreeChart createChart(CategoryDataset dataset) {
        JFreeChart chart = ChartFactory.createBarChart(
            "Bar Chart Demo 2",       // chart title
            "Category",               // domain axis label
            "Value",                  // range axis label
            dataset);
        chart.removeLegend();
        chart.setBackgroundPaint(Color.white);
        CategoryPlot plot = (CategoryPlot) chart.getPlot();
        BarRenderer renderer = (BarRenderer) plot.getRenderer();
        renderer.setDrawBarOutline(false);
        
        Comparable firstKey = dataset.getColumnKey(0);
        double firstValue = dataset.getValue("Series 1", firstKey).doubleValue();
        Comparable lastKey = dataset.getColumnKey(dataset.getColumnCount() - 1);
        double lastValue = dataset.getValue("Series 1", lastKey).doubleValue();
        CategoryLineAnnotation annotation = new CategoryLineAnnotation(
            firstKey, firstValue, lastKey, lastValue, Color.GRAY, 
                new BasicStroke(3.0f));
        plot.addAnnotation(annotation);
        return chart;
    }

    /**
     * Starting point for the demonstration application.
     *
     * @param args  ignored.
     */
    public static void main(String[] args) {
        BarChartDemo2 demo = new BarChartDemo2("Bar Chart Demo 2");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    }

}
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Support JFree via the Github sponsorship program

omuiri166
Posts: 3
Joined: Sun Apr 06, 2014 6:18 pm
antibot: No, of course not.

Re: Setting Target Line In JFreeCharts

Post by omuiri166 » Tue Apr 08, 2014 2:41 pm

Hi David thank you for your feedback it clears up the issues I was having with the category index.

[img][https://www.google.ie/search?q=pasture+ ... B735%3B460]

The image above is a better representative of what the graph can look like as the category bars might not reach the line.

So I was wondering if the value for point1 and point2 have to be contained within the first category and last category, as the line is used as a marker line (Target line to reach but mite not be reached)

The values for points are determined by a computed value and not by the value contained within the category.


So I was wondering if an XYLineAnnotation would be a better solution BUT can a XYPLOT be applied to a DefaultCategoryDataset.

Also how would I tackle this in the form of getting the X Coordinate of the last bar(is the first bar X=1 and the second =2 etc etc)

Thanks for your help David

Locked