customize the x axis and y axis labels in XYAreaChart

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
sri@78
Posts: 6
Joined: Mon Dec 08, 2014 2:34 pm
antibot: No, of course not.

customize the x axis and y axis labels in XYAreaChart

Post by sri@78 » Sat Dec 13, 2014 7:17 am

HI,
I have a requirement to show the x and y axis labels differently as showed in the image. Those are custom values. I am using XYAreaChart to meet the requirement.I almost achieved except to show the custom values on x and y axis. Please see below code and suggest me how can I achieve the same. I tried to use symbol axis but when I set the range to the axis, it is overriding the symbol axis.

Requirement is to show "Start","2015", "2020", "2025","2030","2035","2040" on x axis instead of "2,010",2,015","2,020" etc..
similarly need to show "5k", "10k", "15k", "20k","25k","30k","35k" on y axis instead of "5,000","10,000","15,000" etc..

Image

Code: Select all

/* ---------------------
* XYAreaChartDemo3.java
* ---------------------
* (C) Copyright 2005, by Object Refinery Limited.
*
* Changes
* -------
* 22-Dec-2005 : Version 1 (DG);
*
*/

package demo;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.util.List;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Map;
import java.util.TreeMap;

import javax.swing.JPanel;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.XYLineAnnotation;
import org.jfree.chart.axis.AxisState;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTick;
import org.jfree.chart.axis.TickType;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RefineryUtilities;

/**
* A simple demonstration application showing how to create an area chart with 
* a date axis for the domain values.
*/
public class XYAreaChartDemo3 extends ApplicationFrame {

    /**
     * Creates a new demo.
     *
     * @param title  the frame title.
     */
    public XYAreaChartDemo3(String title) {
        super(title);
        JPanel chartPanel = createDemoPanel();
        chartPanel.setPreferredSize(new java.awt.Dimension(600, 300));
        setContentPane(chartPanel);
    }
    
    private static XYDataset createDataset() {
       /* TimeSeries series1 = new TimeSeries("Random 1");
        
        series1.add(new Year(2010),1800.0);
        series1.add(new Year(2015),3025.0);
        series1.add(new Year(2020),9325.0);
        series1.add(new Year(2025),15950.0);
        series1.add(new Year(2030),22900.0);
        series1.add(new Year(2035),30250.0);
        series1.add(new Year(2040),26000.0);
       TimeSeriesCollection dataset = new TimeSeriesCollection(series1);*/
       /* double value = 0.0;
        Day day = new Day();
        for (int i = 0; i < 50; i++) {
            value = value + Math.random() - 0.5;
            series1.add(day, value);
            day = (Day) day.next();
        }*/
        //Year y = new Year();
    	 XYSeries series1 = new XYSeries("Random 1");
    	 Map<String,String> mChartData = getChartData();
 
    	 for(Map.Entry<String,String> entry: mChartData.entrySet()){
    		 series1.add(Double.parseDouble(entry.getKey()),Double.parseDouble(entry.getValue()));
    	 }
 
        XYSeriesCollection dataset = new XYSeriesCollection(series1);
        
        return dataset;    
    }
    
    /**
     * Creates a chart.
     * 
     * @param dataset  the dataset.
     * 
     * @return The chart.
     */
    private static JFreeChart createChart(XYDataset dataset) {
        JFreeChart chart = ChartFactory.createXYAreaChart(
            "",
            "", "Dollars",
            dataset,
            PlotOrientation.VERTICAL,
            false,  // legend
            false,  // tool tips
            false  // URLs
        );
        
        XYPlot plot = (XYPlot) chart.getPlot();
        //MyXYAreaRenderer renderer = new MyXYAreaRenderer();
        XYItemRenderer renderer = plot.getRenderer();
        //plot.setRenderer(0, renderer);
        plot.setBackgroundPaint(new Color(255,255,255));
        plot.setDomainGridlinesVisible(false);
        plot.setRangeGridlinesVisible(true);
        plot.setRangeGridlineStroke(Plot.DEFAULT_OUTLINE_STROKE);
        plot.setRangeGridlinePaint(new Color(230,230,230));
        //renderer.setSeriesFillPaint(0, new Color(225, 225, 225));
        //renderer.setOutline(true);
        renderer.setSeriesPaint(0, new Color(225, 225, 225));
        renderer.setSeriesOutlinePaint(0, new Color(103, 103, 103));
        renderer.setSeriesOutlineStroke(0, new BasicStroke(4.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER,1.0f, new float[] {1.5f, 1.5f}, 0.0f));        
        NumberAxis domainAxis = (NumberAxis)plot.getDomainAxis();
 
        domainAxis.setLowerMargin(0.0);
        domainAxis.setUpperMargin(0.02);
        domainAxis.setAxisLineVisible(false);
        
        
        plot.setDomainAxis(domainAxis);
        plot.setForegroundAlpha(0.8f);
        ValueAxis rangeAxis = plot.getRangeAxis();
        rangeAxis.setAxisLineVisible(false);
        rangeAxis.setLowerBound(0.0);
        rangeAxis.setUpperBound(35000.0);
        rangeAxis.setAutoRangeMinimumSize(5000.0);
        plot.setRangeAxis(rangeAxis);
        plot.setOutlineVisible(false);
        
        
 
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
       
       XYLineAnnotation lineAn = new XYLineAnnotation(Double.parseDouble(""+year),0.0,Double.parseDouble(""+year),3025.0,new BasicStroke(3.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,1.0f, new float[] {4.0f, 4.0f}, 0.0f),new Color(153,153,153));
        
        plot.addAnnotation(lineAn);
        
        XYLineAnnotation lineAn1 = new XYLineAnnotation(2035.0,0.0,2035.0,30250.0);
        plot.addAnnotation(lineAn1);
 
        plotLine(plot);
        /*XYLineAnnotation lineAn2 = new XYLineAnnotation(2010.0,1800.0,2015.0,3025.0,new BasicStroke(5.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,1.0f, new float[] {15.0f, 0.0f}, 0.0f),new Color(103,103,103));
        XYLineAnnotation lineAn3 = new XYLineAnnotation(2015.0,3025.0,2020.0,9325.0,new BasicStroke(5.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,1.0f, new float[] {15.0f, 0.0f}, 0.0f),new Color(103,103,103));
        XYLineAnnotation lineAn4 = new XYLineAnnotation(2020.0,9325.0,2025.0,15950.0,new BasicStroke(5.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,1.0f, new float[] {15.0f, 0.0f}, 0.0f),new Color(103,103,103));
        XYLineAnnotation lineAn5 = new XYLineAnnotation(2025.0,15950.0,2030.0,22900.0,new BasicStroke(5.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,1.0f, new float[] {15.0f, 0.0f}, 0.0f),new Color(103,103,103));
        XYLineAnnotation lineAn6 = new XYLineAnnotation(2030.0,22900.0,2035.0,30250.0,new BasicStroke(5.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,1.0f, new float[] {15.0f, 0.0f}, 0.0f),new Color(103,103,103));
        XYLineAnnotation lineAn7 = new XYLineAnnotation(2035.0,30250.0,2040.0,26000.0,new BasicStroke(5.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,1.0f, new float[] {15.0f, 0.0f}, 0.0f),new Color(103,103,103));
        
        plot.addAnnotation(lineAn2);
        plot.addAnnotation(lineAn3);
        plot.addAnnotation(lineAn4);
        plot.addAnnotation(lineAn5);
        plot.addAnnotation(lineAn6);
        plot.addAnnotation(lineAn7);*/
       
 
        
 //       renderer.setToolTipGenerator(new StandardXYToolTipGenerator(StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT,new SimpleDateFormat("d-MMM-yyyy"), new DecimalFormat("#,##0.00")));
        return chart;      
    }
    
    /**
     * Creates a panel for the demo.
     *  
     * @return A panel.
     */
    public static JPanel createDemoPanel() {
        return new ChartPanel(createChart(createDataset()));
    }
    
    /**
     * Starting point for the demonstration application.
     *
     * @param args  ignored.
     */
    public static void main(String[] args) {
        XYAreaChartDemo3 demo = new XYAreaChartDemo3("");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    	
  	 /* JFreeChart localJFreeChart = createChart(createDataset());
  	  localJFreeChart.clearSubtitles();

  	  
  	  try{
  		  ChartUtilities.saveChartAsPNG(new File("D:\\XYAreaChartDemo3.png"), localJFreeChart, 640, 331);
  	  }catch(IOException io){
  		  System.out.println("*******Exception occured*****");
  	  }*/
    }
    
    public static Map<String,String> getChartData(){
    	TreeMap<String,String> mData = new TreeMap<String,String>();

    	mData.put("2010","1800");
    	mData.put("2015","3025");
    	mData.put("2020","9325");
    	mData.put("2025","15950");
    	mData.put("2030","22900");
    	mData.put("2035","30250");
    	mData.put("2040","26000");
    	
    	return mData;
    }
    
    public static void plotLine(XYPlot plot){
    	double x0=0,y0=0,x1,y1;
    	int i = 0;
      	 Map<String,String> mChartData = getChartData();
      	 
    	 for(Map.Entry<String,String> entry1: mChartData.entrySet()){
    		 if(i==0){
	    		 x0 = Double.parseDouble(entry1.getKey());
	    		 y0 = Double.parseDouble(entry1.getValue());
    		 }else{
    			 x1 = Double.parseDouble(entry1.getKey());
    			 y1 = Double.parseDouble(entry1.getValue());
    			 //System.out.println("***x0,y0,x1,y1"+x0+" "+y0+" "+x1+" "+y1);
    			 XYLineAnnotation lineAn = new XYLineAnnotation(x0,y0,x1,y1,new BasicStroke(5.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,1.0f, new float[] {15.0f, 0.0f}, 0.0f),new Color(103,103,103));
    			 plot.addAnnotation(lineAn);
    			 x0 = x1;
    			 y0 = y1;
    		 }
    		 i++;

    	 }    	
    }

}

sri@78
Posts: 6
Joined: Mon Dec 08, 2014 2:34 pm
antibot: No, of course not.

Re: customize the x axis and y axis labels in XYAreaChart

Post by sri@78 » Sun Dec 14, 2014 6:37 pm

Please help me about my query. Waiting for the reply. Thanks in advance.

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

Re: customize the x axis and y axis labels in XYAreaChart

Post by david.gilbert » Sun Dec 14, 2014 6:43 pm

On the y-axis, you could achieve this by creating your own NumberFormat subclass - see HexNumberFormat for an example of the general approach.

For the x-axis, you could just override the refreshTicksHorizontal() method and look for the code where it creates the tick labels:

Code: Select all

Tick tick = new NumberTick(new Double(currentTickValue), tickLabel, anchor, rotationAnchor, angle);
When the currentTickValue is 2010 (or whatever your starting year is), change the label to "Start" in code.
David Gilbert
JFreeChart Project Leader

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

sri@78
Posts: 6
Joined: Mon Dec 08, 2014 2:34 pm
antibot: No, of course not.

Re: customize the x axis and y axis labels in XYAreaChart

Post by sri@78 » Sun Dec 14, 2014 6:53 pm

Thank you so much David for the reply. Let me try this approach.

sri@78
Posts: 6
Joined: Mon Dec 08, 2014 2:34 pm
antibot: No, of course not.

Re: customize the x axis and y axis labels in XYAreaChart

Post by sri@78 » Mon Dec 15, 2014 3:31 pm

Hi David,

Now I am able to achieve the y- axis values after overriding the NumberFormat as suggested. But still not able to accomplish the x axis values as I am not able to understand the refreshHorizontal method. But I tried to apply the NumberFormat fix for x-axis values as well and I achieved it for smaller size of the chart image. But if I increase the size of the image, x axis values are getting changed as below. And I am not able to set the range for the x axis.

Expected : start , 2015, 2020, 2025 etc
Output : start, 2012,2014,2016,2018 etce

So please guide me how can I fix this issue. If possible can u share sample piece of code for overriding the refreshHorizontal method.
Thank you in advance.

Regards,
Srinath

sri@78
Posts: 6
Joined: Mon Dec 08, 2014 2:34 pm
antibot: No, of course not.

Re: customize the x axis and y axis labels in XYAreaChart

Post by sri@78 » Tue Dec 16, 2014 8:49 am

Got the way to do. After overriding the refreshTicksHorizontal, got the required format of output. Thanks David for the help.

Locked