|
Ordering the datasets in a stacked bar chart. |
Posted by Andy on Mar-08-2011 21:37 |
|
I currently have a bar chart with datsets stacked upon one another, using the java version of chart director
I am looking to order the data in the bar chart, so that the part of the stack with the largest value/chunk of the bar is at the bottom of the stack, rising up to the smallest value, as opposed to the data just appearing in the order that the datasets are added, which is what is currently happening.
The datasets are currently fed onto the layer by iterating a List of values into layer.addDataSet(), but sorting the values in the list, will just put the wrong data in the wrong dataset.
Is there a method in the chart director API that can order of the values in the stacked bar chart, after the datasets have been added to the layer?
....or will I need to find a cleverer solution in the surrounding java code (if in fact, a solution is possible at all)
Cheers. |
Re: Ordering the datasets in a stacked bar chart. |
Posted by Peter Kwan on Mar-09-2011 01:07 |
|
Hi Andy,
May be you can consider to use "Overlay" instead of "Stack".
Suppose in a bar the values for the red, green and blue segments are { 20, 40, 30 }. The actual position of the top edges of the bar segments are { 20, 60, 90 } (as they are stacked up). But what you really want is { 90, 40, 70 }.
To do this, you can compute the final top edges { 90, 40, 70 } with your own code, and use Overlay instead of Stack. (There is no need for ChartDirector to stack the data, and the data are pre-stacked by your code.)
The following is an example of the code that pre-stacked the data with the largest segment at the lowest position:
//assume you have 3 data series
final double[][] allData = {data0, data1, data2};
for (int i = 0; i < data0.length; ++i)
{
//sort the data, so we can know which one is the largest
final double[] values = { data0[i], data1[i], data2[i] };
Integer[] index = { new Integer(0), new Integer(1), new Integer(2) };
java.util.Arrays.sort(index, new java.util.Comparator() {
public int compare(Object o1, Object o2) {
return Double.compare(values[((Integer)o1).intValue()], values[((Integer)o2).intValue()]);}});
//stack the data with the largest segment at the lowest position.
double acc = 0;
for (int j = 0; j < index.length; ++j)
allData[index[j].intValue()][i] = acc += values[index[j].intValue()];
}
BarLayer layer = c.addBarLayer2(Chart.Overlay);
// Add the three data sets to the bar layer
layer.addDataSet(data0, 0xff8080, "Server # 1");
layer.addDataSet(data1, 0x80ff80, "Server # 2");
layer.addDataSet(data2, 0x8080ff, "Server # 3");
One thing to note is that if you enable data labels / tooltips in the bar segments, by default, they will show the accumulated values, instead of the original data values (as the original values are never passed to ChartDirector). You would need to use custom labelling (eg. using addExtraFields) to show the original values.
Hope this can help.
Regards
Peter Kwan |
Re: Ordering the datasets in a stacked bar chart. |
Posted by Andy on Mar-09-2011 19:47 |
|
Hi Peter,
Thanks very much for you reply.
The problem is that I need to reorder the values in the stacked bars.
Several datasets are passed in. The first dataset for example will have values of varying sizes,
spread accross the the x axis from left to right, their left to right order needing to be retained to match the labelling I subsequently carry out.
These values, if reordered in the stack, will have to maintain the same colour as one another, so as to match their description in the legend as belonging to that dataset.
Then the next dataset is added to the stacked bar, spread accross the the x axis from left to right, again with varying values and again with the need
that if reordered, these values be shown in the same color. Then the next dataset and the next etc.
From what you're suggesting, it looks like you are using the overlay to show which bit of data is largest for each dataset, however I need to reorder them in the stack, to maintain
their given colour and order
Problem is that if I sort the values to biggest to smallest before adding the data to the layer, the wrong data will be represented by the dataset ie the first dataset will
just have all the biggest values in it and not relate to what the data is meant to represent.
I think my aim may not be possible to achieve, but if you could confirm that, I'd appreciate it and I can just put up with the way it's working already.
Once again many thanks for your help so far. |
Re: Ordering the datasets in a stacked bar chart. |
Posted by Peter Kwan on Mar-09-2011 23:41 |
|
Hi Andy,
I think the code in my last message already achieved what you need. You may try it using the "Stacked Bar Chart" sample code included in ChartDirector. It does not change the data values horizontally. It also does not change the data color associated with any data value. It never "moves" any data value from your data array, only "stacks" the data values.
For each bar, the code creates a separate array called "index" and sort that array. Note that it does not sort your data array, so it does not change the position of any data value. The code sorts the indexes to determine the order of the stack sequence.
Next the code stacks your data value based on the stack sequence. Suppose your data values for a bar are (30, 40, 20) - these 3 values are from 3 different data sets. According to your requirement, the 40 should be at the bottom, followed by 30, followed by 20 on the top. So after stacking, the top edge would be (70, 40, 90). The 30 value becomes 70 because it is stacked on top of 40, and the 20 value becomes 90 because it is stacked on top of 70. The 40 value remains unchanged because it is at the bottom of the stack. Note that the color of the values have not been changed. The first value 30 is still at the first position (that is, it is in the same data set and having the same color as before), but it changed to 70 because it is stacked on top of 40.
For simplicity, the code in my last message is hard coded to use 3 data sets. You may want to modify the code to support the number of data sets you need.
Hope this can help.
Regards
Peter Kwan |
|