CategoryPlot and BarRenderer issue

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
mathematical
Posts: 13
Joined: Mon Apr 30, 2007 3:24 pm

CategoryPlot and BarRenderer issue

Post by mathematical » Mon Apr 30, 2007 3:56 pm

I am trying to figure out how to display a String inside every bar in my horizontal bar graph. I want to be able to display different Strings inside different bars on the same graph. I already have the ItemLabel alignment all I need is the ability to show different Strings that have nothing to do with the graphs x or y axis data.

The code below displays the x axis data in the money format:

Code: Select all

BarRenderer barRenderer = (BarRenderer) categoryPlot.getRenderer();
NumberFormat moneyFormat = NumberFormat.getCurrencyInstance();

barRenderer.setItemLabelGenerator(new StandardCategoryItemLabelGenerator("{2}", moneyFormat));
barRenderer.setItemLabelsVisible(true);	
I've tried to modify this to get the functionality that I need with the following changes:

Code: Select all

BarRenderer barRenderer = (BarRenderer) categoryPlot.getRenderer();
NumberFormat moneyFormat = NumberFormat.getCurrencyInstance();

String text = "text inside bar";
barRenderer.setItemLabelGenerator(new StandardCategoryItemLabelGenerator(text, moneyFormat));
barRenderer.setItemLabelsVisible(true);	
And yes I know that this is not an elegant way of doing things but it aleast displays the text. The issue is that I want to show different text on different bars. I looked at the BarRenderer API and I didn't see a way to set the ItemLabel on different bars.

If any one has any questions, just post and I'll answer. Hopfully my issue is clear enough. Thanks in advance.

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

Post by david.gilbert » Mon Apr 30, 2007 5:05 pm

Replace StandardCategoryItemLabelGenerator with your own class that implements the CategoryItemLabelGenerator interface.
David Gilbert
JFreeChart Project Leader

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

mathematical
Posts: 13
Joined: Mon Apr 30, 2007 3:24 pm

Post by mathematical » Mon Apr 30, 2007 6:10 pm

Ok so here is what I did:

Code: Select all

BarRenderer barRenderer = (BarRenderer) categoryPlot.getRenderer();
CustomCategoryItemLabelGenerator generator = new CustomCategoryItemLabelGenerator("text in bar");
barRenderer.setItemLabelGenerator(generator);
barRenderer.setItemLabelsVisible(true);	 
And here is the code for the CustomCategoryItemLabelGenerator class:

Code: Select all

public class CustomCategoryItemLabelGenerator implements CategoryItemLabelGenerator
{
	private String textLabel = null; 
				
	public CustomCategoryItemLabelGenerator(String textLabel)
	{
		this.textLabel = textLabel;
	}
        
   public void setTextLabel(String textLabel)
	{
		this.textLabel = textLabel;
	}
		
	public String generateColumnLabel(CategoryDataset dataset, int row) 
	{			
		return textLabel;
	}

	public String generateLabel(CategoryDataset dataset, int row, int column) 
	{			
		return textLabel;
	}

	public String generateRowLabel(CategoryDataset dataset, int row) 
	{			
		return textLabel;
	}		
}
What I see when I run this is that all the bars on the horizontal bar graph contain the String "text in bar". I want to be able to set different text on to different bars. It seems to me that the BarRenderer class needs a method like setBarLabel(String label, int barIndex) or something like that.
Thanks for your reply though.

RichardWest
Posts: 844
Joined: Fri Oct 13, 2006 9:29 pm
Location: Sunnyvale, CA

Post by RichardWest » Mon Apr 30, 2007 6:48 pm

mathematical wrote:What I see when I run this is that all the bars on the horizontal bar graph contain the String "text in bar". I want to be able to set different text on to different bars. It seems to me that the BarRenderer class needs a method like setBarLabel(String label, int barIndex) or something like that.
If you look at your class, it should be obvious why "text in bar" is the only String returned for each and every bar. All of your get*Label methods return the String you supply in your constructor regardless of what row or column the label is being generated for. Depending upon what you wish to display as labels, you need to modify the code to return a string specific to that bar as determined by the row and/or column. If you want fixed Strings, create a private static array of Strings which you index based upon the row and/or column. If you wish to create labels that rely on the value of the bar in some way, use the row and column to query the CategoryDataset for the value.

Hope that helps,
Richard West
Design Engineer II
Advanced Micro Devices
Sunnyvale, CA

mathematical
Posts: 13
Joined: Mon Apr 30, 2007 3:24 pm

Post by mathematical » Mon Apr 30, 2007 8:02 pm

Thank you Mr West for pointing out the obvious fact that I didn't see how to derive row and columns out of a bar graph. Now that I made the connection here is some code for those that have the same issue or that dont see the "obvious".

Code: Select all

String[] labels = 
{
	"test1a", "test2a", "test3a", "test4a", //first bar text labels
	"test1b", "test2b", "test3b", "test4b"  //second bar text labels
};
Vector<Vector<String>> textLabels = new Vector<Vector<String>>();
			
int CATEGORIES = 4;
int SERIES = 2;
int iterator = 0;
for (int row = 0; row < SERIES; row++)
{
	textLabels.add(new Vector<String>());
	for (int column = 0; column < CATEGORIES; column++)
	{
		textLabels.elementAt(row).add(labels[iterator++]);
	}
}
			
CustomCategoryItemLabelGenerator generator = new CustomCategoryItemLabelGenerator(textLabels);
barRenderer.setItemLabelGenerator(generator);
barRenderer.setItemLabelsVisible(true);
And here is my "obvious" CustomCategoryItemLabelGenerator class:

Code: Select all

private class CustomCategoryItemLabelGenerator implements CategoryItemLabelGenerator
{
	private Vector<Vector<String>> textLabels = null; 
				
	public CustomCategoryItemLabelGenerator(Vector<Vector<String>> textLabels)
	{
		this.textLabels = textLabels;
	}
		
	public void setTextLabels(Vector<Vector<String>> textLabels)
	{
		this.textLabels = textLabels;
	}		
		
	public String generateColumnLabel(CategoryDataset dataset, int row) 
	{			
		return null; //not needed
	}

	public String generateLabel(CategoryDataset dataset, int row, int column) 
	{			
		return textLabels.elementAt(row).elementAt(column);
	}

	public String generateRowLabel(CategoryDataset dataset, int row) 
	{			
		return null; //not needed
	}		
}
This issue is obviously closed. Thank you.

Locked