Background Paint of Bar Graph

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

Background Paint of Bar Graph

Post by mathematical » Thu May 03, 2007 2:47 pm

Is there a way to set the background paint of a bar graph into a different color for every category? Or to have the background paint gray on one category and white on the next and so on. I need this functionality because it would make my graph easier to read. I'm working with a lot of data and the margins cannot change. Thanks in advance.

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

Re: Background Paint of Bar Graph

Post by RichardWest » Thu May 03, 2007 5:17 pm

mathematical wrote:Is there a way to set the background paint of a bar graph into a different color for every category?
See my response in Bar Chart Colors. 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 » Thu May 03, 2007 8:48 pm

That actually did not address my question. I know how to set the color of the bars in a bar graph. What I wanted to know was is there a way to set a color behind the bars for a given category. In the api the only real way to do this is to dynamically create an image and then set the image using the setBackgroundImage() method. I solved that part of it already.

So heres my next question, is there a way to get the number of pixels in width and height of the background before I set an image?

After numerous attempts I'm leaning towards no, but ill keep looking and if you know then let me know. Thanks.

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

Post by RichardWest » Thu May 03, 2007 9:16 pm

mathematical wrote:That actually did not address my question. I know how to set the color of the bars in a bar graph. What I wanted to know was is there a way to set a color behind the bars for a given category.
Sorry, I misinterpreted what you meant by background. I am not sure how to do eactly what you are trying to do with the images, but I have a possible solution using a CategoryMarker for every other category. Once you have created your CategoryPlot using a CategoryDataset, loop through all the category names returned by the dataset's getColumnKeys() and create a CategoryMarker for every other category which you can add to the plot. 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 » Thu May 03, 2007 10:14 pm

Heres some sample code to illustrate my issue:

Code: Select all

//initialize JFreeChart object....

//set up background image
Image image;
double BAR_WIDTH_PERCENT = 0.06;
double BAR_SPACE_PERCENT = 0.02;
double CLIENT_SPACE_PERCENT = 0.05;
double TOP_MARGIN_PERCENT = 0.05;
int BAR_OFFSET_PIXELS = 8;
int BACKGROUND_TAB_COLOR = 0x00bfffff;
int BACKGROUND_DIVIDER_COLOR = 0x00ffffff;
int imageHeight = 316; // I dont want this to be hard coded
int imageWidth = 558;  // I want to take this from the background
int color = 0; 
int count = 0;
int[] imagePixels = new int[imageHeight * imageWidth];   
double pixelStart = TOP_MARGIN_PERCENT * imageHeight;
double pixelEnd = ((BAR_WIDTH_PERCENT * barsPerClient) + (BAR_SPACE_PERCENT * (barsPerClient - 1))) * imageHeight + pixelStart + BAR_OFFSET_PIXELS;
boolean changePixelRange = false;
for (int r = 0, i = 0; r < imageHeight; r++)
{        	
    	for (int c = 0; c < imageWidth; c++)
       	{
       		if ((r >= pixelStart)&&(r <= pixelEnd)&&(count < displayedClients.length))
       		{        			
       			color = BACKGROUND_TAB_COLOR;
       			changePixelRange = true;        			
       		}
       		else
       		{
       			color = BACKGROUND_DIVIDER_COLOR;        		
       		}        		
       		imagePixels[i++] = color; 
       	}
       	if ((changePixelRange == true)&&(r > pixelEnd))
       	{
       		count++;
       		pixelStart = pixelEnd + (CLIENT_SPACE_PERCENT * imageHeight) - BAR_OFFSET_PIXELS;
       		pixelEnd = pixelStart + ((BAR_WIDTH_PERCENT * barsPerClient) + (BAR_SPACE_PERCENT * (barsPerClient - 1))) * imageHeight + BAR_OFFSET_PIXELS;   
       		changePixelRange = false;        		
       	}
}
image = createImage(new MemoryImageSource(imageWidth, imageHeight, imagePixels, 0, imageWidth));
categoryPlot.setBackgroundImage(image);

//more code....
Setting the background color is not a problem as you can see, the only issue I'm having now is getting the height and width of the Rectangle that is painted as the background. I want to be able to get these values before I create my image that way I can set the image height and width accordingly. Although your CategoryMarker is a possible solution, I rather use this method because I have more control over what is being displayed pixel by pixel :).

Let me know if you find a way to get the height and width, mean while, I will be trying to override my way to a solution. Thank you.

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

Post by RichardWest » Thu May 03, 2007 11:12 pm

mathematical wrote:Let me know if you find a way to get the height and width, mean while, I will be trying to override my way to a solution.
There is no means to get this information via the API. The way the background image is drawn is slightly complicated since in Swing there is no easy means to get component height/widths before they are actually packed, validated, and painting. JFreeChart handles this by calling each sub-component's (axes, plots, legends, etc) draw routine with a rectangular area in which it fits. This area is then subdivided again for each sub-sub-component. This goes on until all components of the plot are drawn.

The Plot class' drawBackgroundImage method creates the actual background image from the image provided. The background image is created in a rectangle with a height and width equal to that of the image. This rectangle is then passed to the Align class' align method which then scales and centers the background image to the supplied area rectangle. (NOTE: this is not precisely how it happens, but this is the intuitive intepretation.)

How does this long description help you? If you want to make your background image exactly the same size as the background of the plot, you will have to create your background image within the drawBackgroundImage method. Your desired height and width will be the height and width of the area argument.

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 » Fri May 04, 2007 7:07 pm

Solved it. Heres what i did, I created a class called CustomCategoryPlot that extends CategoryPlot. Then I overrided the draw method and the getPlotType method and in the draw method I took the dataArea width and height and simply assigned it to two private int variables. Finally I made the two accessor methods and that was it. Thank you RichardWest for pointing me in the right direction.

Locked