BarChart with Interval.

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
JIron
Posts: 20
Joined: Mon May 15, 2006 10:42 pm

BarChart with Interval.

Post by JIron » Tue May 30, 2006 5:43 am

I have 5bars, 4 bars with consecutive values(10,20,40,50), but the last have a huge value(2500)
I need to put a space in the last bar(representing the distance between huge values).
How I make a interval(a cut) on a vertical barChart?








Best Regards for All,
JIron

JIron
Posts: 20
Joined: Mon May 15, 2006 10:42 pm

Post by JIron » Thu Jun 01, 2006 7:21 pm

I tryed IntervalBarRenderer but a get many bars, and i have just the last(with huge value).I just want a "cut" or interval on my last bar...
my code:

Code: Select all

....
private static CategoryDataset createDataset() { 
        
        DefaultCategoryDataset dataset = new DefaultCategoryDataset(); 
        dataset.addValue(50.0, "Series 1", "CEPEL"); 
        dataset.addValue(44.3, "Series 1", "Ampla"); 
        dataset.addValue(33.0, "Series 1", "Itaipu"); 
        dataset.addValue(35.6, "Series 1", "Furnas"); 
        dataset.addValue(45.1, "Series 1", "ELETROBRAS"); 
        dataset.addValue(25.1, "Series 1", "SULGIPE"); 
        dataset.addValue(41.0, "Series 1", "ESCELSA"); 
        dataset.addValue(24.3, "Series 1", "CENF"); 
        dataset.addValue(23.0, "Series 1", "CAIUA"); 
        dataset.addValue(35.6, "Series 1", "CNEE"); 
        dataset.addValue(175.1, "Series 1", "CFLO"); 
        return dataset; 
        
    } 
    
    private static JFreeChart createChart(CategoryDataset dataset) { 
        
        JFreeChart chart = ChartFactory.createBarChart( 
            "Participação no mercado","Category","Valor",dataset,PlotOrientation.VERTICAL, 
            false,true,false); 

        chart.setBackgroundPaint(Color.white); 

        CategoryPlot plot = chart.getCategoryPlot(); 
        plot.setBackgroundPaint(Color.lightGray); 
        plot.setDomainGridlinePaint(Color.white); 
        plot.setRangeGridlinePaint(Color.white); 
        
        CategoryAxis domainAxis = plot.getDomainAxis(); 
        domainAxis.setVisible(false); 
        
        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis(); 
        rangeAxis.setUpperMargin(0.15); 
        
        CategoryItemRenderer renderer = plot.getRenderer(); 
        CategoryItemLabelGenerator generator 
            = new StandardCategoryItemLabelGenerator("{1}", 
                    NumberFormat.getInstance()); 
        renderer.setItemLabelGenerator(generator); 
        renderer.setItemLabelFont(new Font("SansSerif", Font.PLAIN, 12)); 
        renderer.setItemLabelsVisible(true); 
        renderer.setPositiveItemLabelPosition(new ItemLabelPosition( 
                ItemLabelAnchor.CENTER, TextAnchor.CENTER, TextAnchor.CENTER, 
                - Math.PI / 2)); 
        
        return chart; 
        
    } 
...
I want a interval just on the bar:
dataset.addValue(175.1, "Series 1", "CFLO");
Anyone tryed it??? :cry:

JIron
Posts: 20
Joined: Mon May 15, 2006 10:42 pm

Post by JIron » Fri Jun 02, 2006 8:10 pm

I´m not able to find an answer... :oops:
Anyone knows a similar API(Like JFreeChart) able to cut(put a space) vertical bar charts?
I have two hundred charts to make and this feature it´s very important!







Best Regards,
JIron

angel
Posts: 899
Joined: Thu Jan 15, 2004 12:07 am
Location: Germany - Palatinate

Post by angel » Tue Jun 06, 2006 7:28 am

To my knowledge this feature isn't implemented yet...

JIron
Posts: 20
Joined: Mon May 15, 2006 10:42 pm

Post by JIron » Wed Jun 07, 2006 8:20 am

Oh,lord... my money fly away...

Angel, how can i create a custom axis?I need one very simple(range 10,20,30,40,50 and 200), but should i extend CategoryAxis?Give me a way to do this!(Or a example)
I think i can put a space on a bar with Photoshop, but i need this special axis... normal axis made all the normal bars tiny, and i have one special huge bar, i wanna all the bars with "normal sizes" on the chart.

pmarsollier
Posts: 49
Joined: Thu Jul 08, 2004 8:54 am
Location: France

Post by pmarsollier » Wed Jun 07, 2006 10:30 am

could you post a sample graph of want you want ???

it's not very hard to build a custom renderer capable of handling differently "huge" column value based on your criteria.

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 » Wed Jun 07, 2006 4:10 pm

I think you need to do two things here:

(1) Create a custom axis that displays a regular range from 0 to 50, then a discontinuity, then resume the regular range from 2,500 onwards. I guess this could be done by subclassing NumberAxis and overriding the java2DToValue() and valueToJava2D() methods, as well as the refreshTicks() method. I didn't try this, though.

(2) Create a custom bar renderer that draws regular bars for values that don't cross the discontinuity, and a different bar for values that do (that is, some visual indicator that the bar is in fact much larger than it looks). This part is easier, as you only need to modify the drawItem() method in the BarRenderer class.
David Gilbert
JFreeChart Project Leader

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

JIron
Posts: 20
Joined: Mon May 15, 2006 10:42 pm

Post by JIron » Wed Jun 07, 2006 9:15 pm

pmarsollier, here goes the example:
Image

David, thanks for reply. I will go your steps, and try implement this features.I´ll report later my sucess(or no...)


Best Wishes,
JIron.

JIron
Posts: 20
Joined: Mon May 15, 2006 10:42 pm

Post by JIron » Wed Jun 21, 2006 5:54 am

David, i´m more lost than ...
a regular range from 0 to 50, then a discontinuity, then resume the regular range from 2,500 onwards.

How can i make this "discontinuity"???I´m make like the chart above.Make a chart with range to 2000 it´s easy, but the part without Y axis label assigned its very, very hard...
what do i put on java2DToValue() and and valueToJava2D to represent this???

Code: Select all

 class MyCustomAxis extends NumberAxis {

	@Override
	public double java2DToValue(double arg0, Rectangle2D arg1, RectangleEdge arg2) {
		return /*how the y axis values are printed
to Rectangle Edge*/
	}
}
This part is easier, as you only need to modify the drawItem() method in the BarRenderer class.
Easy???I´m afraid dave...(HAL9000 in 2001)
Haw can i repaint a bar without y axis label value assigned?If not possible i think i can put a huge value(like 25000 on last label on Y axis), but i´m confused wich param i pass on drawItem().

Code: Select all

public class MySpecialBar extends BarRenderer {

	@Override
	public void drawItem(Graphics2D arg0, CategoryItemRendererState arg1, Rectangle2D arg2, CategoryPlot arg3, CategoryAxis arg4, ValueAxis arg5, CategoryDataset arg6, int arg7, int arg8, int arg9) {   /*i wanna a huge special bar with 20000 value assigned
 but how i put her on the chart???*/      		
	}

}
Some snippets would be appreciade...

pmarsollier
Posts: 49
Joined: Thu Jul 08, 2004 8:54 am
Location: France

Post by pmarsollier » Wed Jun 21, 2006 8:01 am

- define 2 thresholds : one low and one high
- in your draw method (in either axis or renderer) use those to compute new values:
if you are under low threshold, just do it normaly.
if you are between, don't do anything
if you are over high threshold, compute a new corresponding value.
The rule to do it will depend on your data of course, so your renderer will probably not be useble for another kind of data ...

in your first example, a way to do it is to subract 100 or 130 from your 175.3 value.
low threshold could be 55 and high 170.
the idea is that value above 170 are converted to somthing near 60-65 ...

JIron
Posts: 20
Joined: Mon May 15, 2006 10:42 pm

Post by JIron » Thu Jun 22, 2006 8:29 am

pmarsollier,
I don't really understand how to subtract the values of the bars!
could you clarify this?
public class MySpecialBar extends BarRenderer {

@Override
public void drawItem(Graphics2D g2, CategoryItemRendererState state,
Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis,
CategoryDataset dataset, int row, int column, int pass) {

if(dataset.getValue(row,column).doubleValue()<55){
super.drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column, pass);

}else if(dataset.getValue(row,column).doubleValue()==55){

}else if(dataset.getValue(row,column).doubleValue()>170){
//?????? how subtract?rowBar-rowLowBar?
}
}
}
Thanks for reply!

Best Regards,
JIron

pmarsollier
Posts: 49
Joined: Thu Jul 08, 2004 8:54 am
Location: France

Post by pmarsollier » Thu Jun 22, 2006 8:45 am

in your case, you can't just overide and call the ancestor.

you have to duplicate the drawItem method AND patch the code.

in the beginning of that method, you get the value

// nothing is drawn for null values...
Number dataValue = dataset.getValue(row, column);
if (dataValue == null) {
return;
}

double value = dataValue.doubleValue();

here you can test dans change your value:

if ( value > 55 ) value -= 165;

then the trick is done.

for the axis , it's the same but You'll have to find where to do it ...
with just a quick glance, I didn't find where the tick are drawn ...

JIron
Posts: 20
Joined: Mon May 15, 2006 10:42 pm

Post by JIron » Fri Jun 23, 2006 7:47 am

Code: Select all

public void drawItem(Graphics2D g2, CategoryItemRendererState state,
			Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, ValueAxis rangeAxis,
			CategoryDataset dataset, int row, int column, int pass) {
		Number dataValue = dataset.getValue(row, column); 
		double value = dataValue.doubleValue(); 
		     if(dataValue==null){
		    	 return;
		     }else if(value>55){
		    	 value-=165;
		     }		  
	}//...
don´t show the bar!!!
You'll have to find where to do it ...
I´m reading the docs(javadocs), and i still dont´find where(and how) the thicks
are drawn!I haven´t found many examples with customized bars/axis on the net!

Sugestions to David Gilbert:
This should be good(if i could do this):
MyCustomizedAxis.setAxis(500,1000,1500,2000,10000,20000) //using varargs

And make a CustomizedBar:
myBar.setBlankSpace(100,135);//(begin,end)

or still:
myBar.setPieces(10);//split the bar on 10 pieces or fragments
myBar.setPieceColor(8,Color.lightGrey); /*piece position, color of piece*/

Good Idea,no?

JIron
Posts: 20
Joined: Mon May 15, 2006 10:42 pm

It´s hard to do this!

Post by JIron » Mon Jun 26, 2006 5:49 am

pmarsollier,
I have been talking with my boss...i`ll cut the bar with photoshop.
But i have a trouble yet:
-made a Yaxis like that:
MyCustomizedAxis.setYAxisLabels(500,1000,1500,2000,15000,30000);
I don´t understand how to reewrite java2DToValue() and and valueToJava2D() to do this!

with almost all the bars with values between 0 and 2000, just one out of this range.
-keep the huge bar(per example:22500) with equivalent size like others!(just with more length)
In normal chart, the others will be miniaturized to very small size(impossible to see labels and values).

I´m looking for a way to make what david says, but javadocs don´t helpme...
I need to understand how the axis and the bars are generated.It would good if i could dominate the chart.Ex.: with my chart 1800x800, i will put the bar on position(1700,0) and the same bar will end in (1764,750).

I´m thinking create a chart using just java.AWT, but it´s a "tour the force" make this...
anyone make something like this!!!


Best Regards,
JIron

pmarsollier
Posts: 49
Joined: Thu Jul 08, 2004 8:54 am
Location: France

Post by pmarsollier » Mon Jun 26, 2006 1:37 pm

well, if you rework the graph with photoshop, it 's quite easy :
build a graph with good bas values => your goal is to draw the good bars, of the good global size.
to do it, adjust values and labels.

then just do what you want with photoshop !
you can "cut" your bar, but you can also rewrite the labels ...

Locked