Align center of Bar rendered by XYBarRenderer with the grid

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
vijay
Posts: 13
Joined: Thu Nov 17, 2005 3:20 pm
Location: India

Align center of Bar rendered by XYBarRenderer with the grid

Post by vijay » Thu Dec 01, 2005 2:53 pm

Hi

While trying get around with not able to set the data area on category plot i am stuck with the following problems using XYPlot.

I have tried out few steps from my end, i have the following requirement:

1. I want the vertical grid line of the plot to pass throught the mid point of the Bar rendered by XYBarRenderer

2. I have customised the Symbol axis in a form such that i can have the labels rotated by 90 degress. But the problem is i am not able to get the label just below the tick - it is getting offset to left by some value.

Can anyone shed some light as to how i can get point 1 and point 2 achieved.

Code: Select all


import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisState;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.SymbolAxis;
import org.jfree.chart.axis.ValueTick;

import org.jfree.chart.axis.ValueAxis;
//import org.jfree.chart.labels.StandardXYItemLabelGenerator;
import org.jfree.chart.plot.DatasetRenderingOrder;
import org.jfree.chart.plot.XYPlot;

import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.IntervalXYDataset;

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;
import org.jfree.ui.TextAnchor;




public class OverlaidXYChartDemo extends ApplicationFrame
{
	
	OverlaidXYChartDemo()
	{
		super("test");		
		JFreeChart chart = new JFreeChart(
				                           "Overlaid Plot Example", 
				                           JFreeChart.DEFAULT_TITLE_FONT, 
				                           getXYPlot(),
				                           true);
        
		ChartPanel panel = new ChartPanel(chart, true, true, true, true, true);
        panel.setPreferredSize(new java.awt.Dimension(500, 270));
        setContentPane(panel);		
	}
	
	XYPlot getXYPlot()
	{
		IntervalXYDataset dso = getDataset(getBarSeries());
		IntervalXYDataset ds1 = getDataset(getXYLineSeries1());
		IntervalXYDataset ds2 = getDataset(getXYLineSeries2());
		
		XYItemRenderer renderero = new XYBarRenderer(0.2);
				

		
		SymbolAxis domainAxis = new CustomSymbolAxis(getCategories());
		domainAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
		
		domainAxis.setAutoRange(false);
		domainAxis.setRange(0,7);
		domainAxis.setLowerMargin(0.2);
		domainAxis.setUpperMargin(0.2);
				
        ValueAxis rangeAxis = new NumberAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());        
        rangeAxis.setAutoRange(false);
        rangeAxis.setRange(0,7);
        
        
        XYItemRenderer renderer1 = new XYLineAndShapeRenderer();
        XYItemRenderer renderer2 = new XYLineAndShapeRenderer();
        
        XYPlot plot = new XYPlot();
        plot.setDomainAxis(0, domainAxis);
        plot.setRangeAxis(0, rangeAxis);
        
        plot.setDataset(0, dso);
        plot.setDataset(1, ds1);
        plot.setDataset(2, ds2);
        
        plot.setRenderer(0, renderero);
        plot.setRenderer(1, renderer1);
        plot.setRenderer(2, renderer2);
        
        
                
        plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
        return plot;
	}


	XYSeriesCollection getDataset(XYSeries theSeries)
	{
		XYSeriesCollection seriesCollection = new XYSeriesCollection();
		seriesCollection.addSeries(theSeries);
		return seriesCollection;
	}
	
	
	XYSeries getBarSeries()
	{
		XYSeries barSeries = new XYSeries("bar");
		barSeries.add(0.5, 2.0);
		barSeries.add(1.5, 2.0);
		barSeries.add(2.5, 0.0);
		barSeries.add(3.5, 2.0);
		barSeries.add(4.5, 2.0);
		barSeries.add(5.5, 1.0);
		barSeries.add(6.5, 2.0);
		barSeries.add(7.5, 0.0);
		barSeries.add(8.5, 0.0);
		barSeries.add(9.5, 0.0);
		return barSeries;
	}
	
	XYSeries getXYLineSeries1()
	{
		XYSeries xySeries1 = new XYSeries("x1");
		xySeries1.add(0.5, 4.02);
		xySeries1.add(1.5, 4.02);
		xySeries1.add(2.5, 4.24);
		xySeries1.add(3.5, 4.04);
		xySeries1.add(4.5, 5.02);
		xySeries1.add(5.5, 4.24);
		xySeries1.add(6.5, 3.34);
		xySeries1.add(7.5, 3.71);
		xySeries1.add(8.5, 4.89);
		xySeries1.add(9.5, 5.00);
		return xySeries1;
	}
	
	XYSeries getXYLineSeries2()
	{
		XYSeries xySeries2 = new XYSeries("x1");
		xySeries2.add(0.5, 2.28);
		xySeries2.add(1.5, 2.0);
		xySeries2.add(2.5, 2.75);
		xySeries2.add(3.5, 2.22);
		xySeries2.add(4.5, 3.28);
		xySeries2.add(5.5, 2.39);
		xySeries2.add(6.5, 1.5);
		xySeries2.add(7.5, 2.0);
		xySeries2.add(8.5, 2.5);
		xySeries2.add(9.5, 2.58);
		return xySeries2;
	}
	
	String[] getCategories()
	{
		String[] cats 
		  = new String[]{
				          "Values",
				          "Achiever",
				          "Exactness",
				          "Resourceful",
				          "WorkIntensity",
				          "Positivity",
				          "Relationship",
				          "R-E",
				          "Persuation",
				          "Command",
		                };
		return cats;
			                          
	}
	
	public static void main(String args[])
	{		
		OverlaidXYChartDemo demo 
		  = new OverlaidXYChartDemo();
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
	}
}


class CustomSymbolAxis extends SymbolAxis
{		
	CustomSymbolAxis(String[] categories)
	{	
		super("", categories);
		setGridBandsVisible(false);
		setStandardTickUnits(NumberAxis.createIntegerTickUnits());
		setVerticalTickLabels(false);
	}
	
	 /**
     * Converts a value to a string, using the list of symbols.
     *
     * @param value  value to convert.
     *
     * @return The symbol.
     */
    public String valueToString(double value) 
    {
    	int intValue = (int) value;
    	return getSymbols()[intValue];
    }
    
    public List refreshTicks(
    	Graphics2D g2, 
    	AxisState state, 
    	Rectangle2D dataArea, 
    	RectangleEdge edge)    	 
    {
    	List ticks = super.refreshTicks(g2, state, dataArea, edge);
    	List customAngleTicks = new ArrayList(ticks.size());
    	for (int i = 0; i < ticks.size(); i++) 
    	{    		
    		Object oTick =  ticks.get(i);
    		ValueTick  tick = (ValueTick)oTick;
    		customAngleTicks.add(new CustomAngleTick(tick, Math.PI/2));
	}
    	return customAngleTicks;
    }    
}

class CustomAngleTick extends ValueTick
{
    
	CustomAngleTick(
        ValueTick theActualTick,
        double theAngle)        
    {
	   super(  theActualTick.getValue(),
			   theActualTick.getText(),			   
			   //theActualTick.getTextAnchor(),
			   TextAnchor.TOP_LEFT,			   
			   //theActualTick.getRotationAnchor(),			   
			   TextAnchor.TOP_LEFT,
			   theAngle);	   
    }
}
If someone runs this demo what i mentioned in point 1 and 2 will be obvious.


In the example OverlaidXYPlotDemo1 and OverlaidXYPlotDemo2

I see that the grid line intersects the centre of the bar - This is what i want to achieve (Point 1)

When using category plot demos - if i set

Code: Select all

categoryplot.getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.DOWN_90);
The labels come fine exactly below the ticks along the grid line. This is my second requirement.

Can some body let me know or give some inputs please?

EDIT : Working with rc3 and using JDK 1.5

Thanks,
Vijay Venkataraman

vijay
Posts: 13
Joined: Thu Nov 17, 2005 3:20 pm
Location: India

Post by vijay » Fri Dec 02, 2005 3:40 pm

Sorry folks. There was some misunderstanding of concepts from my end and the data values are wrong. I have been able fix the problem, Point 1 of my previous post. While aligning the tick labels exactly below the tick marks remains.

Thanks,
Vijay Venkataraman

vijay
Posts: 13
Joined: Thu Nov 17, 2005 3:20 pm
Location: India

Post by vijay » Fri Dec 02, 2005 4:27 pm

Another mistake i identified is that - I was setting the achor to wrong value.

It should have been TextAnchor.CENTER_LEFT

Thanks,
Vijay Venkataraman

kasineedis
Posts: 7
Joined: Tue Mar 10, 2009 8:50 pm

Re: Align center of Bar rendered by XYBarRenderer with the grid

Post by kasineedis » Wed May 13, 2009 6:01 pm

HI ,

I have similler problem .My requrment is The Girid line of Symbol axis(Y-axis) should pass center of the Stacked bar that is rendered by XYBarRenderer .Right now it is passing at the bottem of the stacked bar .If you run the following demo one can understand what the problelm is .....Can any body Please shed light on it .






import java.awt.Color;
import java.awt.Font;
import java.text.SimpleDateFormat;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickUnit;
import org.jfree.chart.axis.SymbolAxis;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StandardXYBarPainter;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.data.time.RegularTimePeriod;
import org.jfree.data.xy.IntervalXYDataset;
import org.jfree.data.xy.XYIntervalSeries;
import org.jfree.data.xy.XYIntervalSeriesCollection;
import org.jfree.date.DateUtilities;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.HorizontalAlignment;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.RefineryUtilities;


public class XYBarChartDemo7_2 extends ApplicationFrame {
private static final long serialVersionUID = 1L;

/**
* Constructs the demo application.
*
* @param title
* the frame title.
*/
public XYBarChartDemo7_2(String title) {
super(title);

JPanel chartPanel = createDemoPanel();
chartPanel.removeAll();

chartPanel.repaint();

chartPanel.setPreferredSize(new java.awt.Dimension(500, 300));

setContentPane(chartPanel);
}

private static JFreeChart createChart(IntervalXYDataset dataset) {


JFreeChart chart = ChartFactory.createXYBarChart("SymbolAxis",
"Date", true, "Y", dataset, PlotOrientation.VERTICAL, true,
false, false);

chart.setBackgroundPaint(Color.white);

XYPlot plot = (XYPlot)chart.getPlot();
chart.getTitle().setHorizontalAlignment(HorizontalAlignment.LEFT);
chart.getTitle().setFont(new Font("Default", Font.BOLD, 15));

plot.setAxisOffset(RectangleInsets.ZERO_INSETS);

DateAxis domainAxis = new DateAxis("");
domainAxis.setVerticalTickLabels(true);

double lower = DateUtilities.createDate(2006, 11, 1,
DateUtil.getHour("00:00"),DateUtil.getMinutes("00:00"))
.getTime();

double upper = DateUtilities.createDate(2006, 11, 1,
DateUtil.getHour("23:59"), DateUtil.getMinutes("23:59"))
.getTime();
SimpleDateFormat dateFm = new SimpleDateFormat("HH:MM");
DateTickUnit dtUnit = new DateTickUnit(DateTickUnit.HOUR, 1, dateFm);

domainAxis.setTickUnit(dtUnit);
domainAxis.setAutoTickUnitSelection(true);
plot.getDomainAxis().setLowerMargin(0.02);
plot.getDomainAxis().setUpperMargin(0.02);
domainAxis.setUpperBound(upper);
domainAxis.setLowerBound(lower);
plot.setDomainAxis(0,domainAxis);


SymbolAxis rangeAxis = new SymbolAxis("Series", new String[] { " ","S1", "S2",
"S3" });
rangeAxis.setGridBandsVisible(false);
plot.setRangeAxis(0,rangeAxis);
plot.getRangeAxis().setLowerMargin(0.0);
plot.getRangeAxis().setUpperMargin(0.9);
plot.getRangeAxis().setRange(0.0,3.0);


plot.setBackgroundPaint(Color.white);
plot.setDomainGridlinePaint(new Color(0xB29999));
plot.setRangeGridlinePaint(new Color(0xB29999));
plot.setRangeGridlinePaint(new Color(0xB29999));




//Renderer
XYBarRenderer lDisributionChartRenderer = (XYBarRenderer) plot.getRenderer();
lDisributionChartRenderer.setUseYInterval(true);
lDisributionChartRenderer.setShadowVisible(false);
lDisributionChartRenderer.setAutoPopulateSeriesFillPaint(false);
lDisributionChartRenderer.setBarPainter(new StandardXYBarPainter());
lDisributionChartRenderer.setDrawBarOutline(true);
lDisributionChartRenderer.setAutoPopulateSeriesPaint(false);
lDisributionChartRenderer.setAutoPopulateSeriesOutlineStroke(false);
lDisributionChartRenderer.setAutoPopulateSeriesStroke(true);
lDisributionChartRenderer.setSeriesOutlinePaint(0, Color.DARK_GRAY);
lDisributionChartRenderer.setSeriesOutlinePaint(1, Color.DARK_GRAY);
lDisributionChartRenderer.setSeriesOutlinePaint(2, Color.DARK_GRAY);
lDisributionChartRenderer.setSeriesOutlinePaint(3, Color.DARK_GRAY);
lDisributionChartRenderer.setSeriesOutlinePaint(4, Color.DARK_GRAY);
lDisributionChartRenderer.setSeriesOutlinePaint(5, Color.DARK_GRAY);
lDisributionChartRenderer.setSeriesPaint(0, new Color(0xB2CCFF)); //R
lDisributionChartRenderer.setSeriesPaint(1, new Color(0xCCFFB2)); //D
lDisributionChartRenderer.setSeriesPaint(2, new Color(0xFFFF00)); //H
lDisributionChartRenderer.setUseYInterval(true);


lDisributionChartRenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator());

/*plot.setBackgroundPaint(Color.lightGray);
plot.setRenderer(lDisributionChartRenderer);
plot.setBackgroundPaint(Color.lightGray);
plot.setRangeGridlinePaint(Color.white);*/
return chart;
}

/**
* Creates a sample dataset.
*/
private static IntervalXYDataset createDataset() {

XYIntervalSeriesCollection dataset = new XYIntervalSeriesCollection();
XYIntervalSeries s1 = new XYIntervalSeries("S1");
XYIntervalSeries s2 = new XYIntervalSeries("S2");
XYIntervalSeries s3 = new XYIntervalSeries("S3");

// addItem(s1, d0, d1, 0);

double startTime = DateUtilities.createDate(2006, 11, 1,
DateUtil.getHour("04:48"), DateUtil.getMinutes("04:48")).getTime();
double stopTime = DateUtilities.createDate(2006, 11, 1,
DateUtil.getHour("05:37"), DateUtil.getMinutes("05:37"))
.getTime();
double xValue = (startTime + stopTime) / 2.0;




double startTime18 = DateUtilities.createDate(2006, 11, 1,
DateUtil.getHour("07:09"), DateUtil.getMinutes("07:09"))
.getTime();
double stopTime18 = DateUtilities.createDate(2006, 11, 1,
DateUtil.getHour("07:34"), DateUtil.getMinutes("07:34"))
.getTime();
double xValue18 = (startTime + stopTime) / 2.0;



double startTime23 = DateUtilities.createDate(2006, 11, 1,
DateUtil.getHour("10:22"), DateUtil.getMinutes("10:22"))
.getTime();
double stopTime23 = DateUtilities.createDate(2006, 11, 1,
DateUtil.getHour("12:00"), DateUtil.getMinutes("12:00"))
.getTime();
double xValue23 = (startTime + stopTime) / 2.0;


double startTime24 = DateUtilities.createDate(2006, 11, 1,
DateUtil.getHour("14:02"), DateUtil.getMinutes("14:02"))
.getTime();
double stopTime24 = DateUtilities.createDate(2006, 11, 1,
DateUtil.getHour("14:36"), DateUtil.getMinutes("14:36"))
.getTime();
double xValue24 = (startTime + stopTime) / 2.0;


s1.add(xValue, startTime, stopTime, 0.0, 0.0, 1.0);
s2.add(xValue18, startTime18, stopTime18, 1.0, 1.0,2.0 );
s3.add(xValue24, startTime24, stopTime24, 2.0, 2.0, 3.0);

dataset.addSeries(s1);
dataset.addSeries(s2);
dataset.addSeries(s3);
return dataset;
}

private static void addItem(XYIntervalSeries s, RegularTimePeriod p0,
RegularTimePeriod p1, int index) {
System.out.println("p0.getFirstMillisecond() is "
+ p0.getFirstMillisecond() / (1000 * 60 * 60 * 24));
s.add(p0.getFirstMillisecond(), p0.getFirstMillisecond(), p1
.getLastMillisecond(), index, index - 0.45, index + 0.45);
s.add(1.0, 1.0, 3.0, 2.0, 2.0, 2.0);
}

/**
* Creates a panel for the demo.
*
* @return A panel.
*/
public static JPanel createDemoPanel() {
return new ChartPanel(createChart(createDataset()));
}


public static int getMinutes(String time) {
return Integer.parseInt(time.substring(3));
}


public static int getHour(String time) {
return Integer.parseInt(time.substring(0, 2));
}



/**
* Starting point for the demonstration application.
*
* @param args
* ignored.
*/
public static void main(String[] args) {
XYBarChartDemo7_2 demo = new XYBarChartDemo7_2(
"JFreeChart : XYBarChartDemo7.java");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}

}

Locked