|
Bar Gap when two Barcharts |
Posted by Maxx Power on Feb-20-2009 14:27 |
|
Hi,
I am trying to add two separate BarLayers on the same chart and there seems to be a
small gap between the two even when the data should join up.
Eg: if layer1 has (1,2,3,4) and layer2 has (5,6,7,8) there is a small gap between the two
charts.
I am using TouchBar to make the bars join which works OK within each layer.
It seems the first and last bar is only half-width for some reason.
Is there some function I am missing that will make them join up..???
Thanks. |
Re: Bar Gap when two Barcharts |
Posted by Peter Kwan on Feb-20-2009 16:46 |
|
Hi Maxx,
The first and last bar are only half-width if there is insufficient space for full width bars. If the x-axis is a label based x-axis (Axis.setLabels), ChartDirector will automatically add some margin to the x-axis to ensure there are sufficient space for all bars.
However, if your code specify the x-axis scale, or if you use other x-coordinates (eg. explicitly providing x-coordinates using setXData), it is possible half of the the first and last bars are outside the plot area.
(A bar at x=1 means the center of the bar is at x=1. It means half of the bar is to the left of x=1, and half of the bar is to the right of x=1. Depending on how the x-axis scale is configured, half of the bar may fall outside the plot area and not drawn.)
By default, in a vertical bar chart, ChartDirector will try to draw the chart so that each bar is of the same width. For example, if the plot area has 202 pixels, and there are 5 bars, and you set the bar gap as 0, ChartDirector may use a bar width of 40 pixels per bar. (This is the maximum possible width without the bars overlapping.) That means there must be 2 pixels extra leaving as gaps somewhere. The key reason is the plot area width may not be exactly divisible by the number of bars.
If you use TouchBar, ChartDirector will ensure the bars are touched, and so they may not be of the same width. In the above example, some bars may be 40 pixels and some bars 41 pixels. This may not look so bad, since it is hard for a human eye to distinguish between 40 and 41 pixels. However, if your bars are very narrow (just 1 or 2 pixels wide), the 1 pixel difference may be noticible.
Since your two layers are not configured (and cannot be configured) as "touched", ChartDirector will not adjust the bar width of one layer to make it touch another layer, so the bars may not touch.
In your case, I think it is better to use one bar layer instead of two bar layers. If you must use two bar layers, you may add all 8 bars into both bar layers. In the first layer, you may set the bars 5, 6, 7, 8 to 0 or to NoValue, and do the reverse for the second layer.
If you need further help, is it possible to inform me the charting part of your code and attach a chart image to help me understand how your chart are drawn, and what you get so far?
Hope this can help.
Regards
Peter Kwan |
Re: Bar Gap when two Barcharts |
Posted by Maxx Power on Feb-20-2009 18:34 |
|
Thanks for the detailed reply.
I will try to attach some sample code and resulting graph.
test.php |
---|
<?php
require_once("../lib/phpchartdir.php");
$xdata0 = array();
$ydata0 = array();
$xdata1 = array();
$ydata1 = array();
for ($x=0; $x<100; $x++) {
$xdata0[] = 3;
$ydata0[] = $x;
}
for ($x=100; $x<200; $x++) {
$xdata1[] = 4;
$ydata1[] = $x;
}
$c = new XYChart(600, 300, 0xeeeeff, 0x000000, 1);
$c->setPlotArea(55, 58, 520, 195, 0xffffff, -1, -1, 0xcccccc, 0xcccccc);
$layer = $c->addBarLayer2(Side);
$layer->setBarGap(TouchBar, TouchBar);
$layer->addDataSet($xdata0, 0xff0000);
$layer->setXData($ydata0);
$layer = $c->addBarLayer2(Side);
$layer->setBarGap(TouchBar, TouchBar);
$layer->addDataSet($xdata1, 0x008800);
$layer->setXData($ydata1);
$c->makeChart("test.png");
?> |
|
| |
Re: Bar Gap when two Barcharts |
Posted by Maxx Power on Feb-20-2009 18:41 |
|
I am trying to get rid of the gap in the middle of the two layers.
To put this in perspective, I have two (or more) separate timelines split by a date (year).
Eg, I have historical data up to a certain year, and then predicted data, which I need to
show on the same chart using different colours/legends.
I know I can combine the two arrays and then use zones or color arrays but it makes it
harder to show individual legend entries as well as using moving averages/trendlines. |
Re: Bar Gap when two Barcharts |
Posted by Peter Kwan on Feb-20-2009 19:18 |
|
Hi Maxx,
You have 200 bars and the plot area width is 520 pixels. If you use "touch", each bar would be 2 to 3 pixels. You also have a 1 pixel border for each bar. So the bar fill region is 1 to 2 pixels. It is not surprising some bars are half the width of other bars.
Also, your code have two separate layers, and they are not guaranteed to touch.
In your case, I suggest you use the same x-coordinates for the two layers, like:
$ydata = array_pad(array(), 200, 0);
$xdata0 = array_pad(array(), 200, 0);
$xdata1 = array_pad(array(), 200, 0);
for ($x=0; $x<200; $x++)
$ydata[$x] = $x;
for ($x=0; $x<100; $x++)
$xdata0[$x] = 3;
for ($x=100; $x<200; $x++)
$xdata1[$x] = 4;
$layer = $c->addBarLayer2(Side);
$layer->setBarGap(TouchBar, TouchBar);
$layer->addDataSet($xdata0, 0xff0000);
$layer->setXData($ydata);
$layer = $c->addBarLayer2(Side);
$layer->setBarGap(TouchBar, TouchBar);
$layer->addDataSet($xdata1, 0x008800);
$layer->setXData($ydata);
Hope this can help.
Regards
Peter Kwan |
Re: Bar Gap when two Barcharts |
Posted by Maxx Power on Feb-21-2009 11:26 |
|
Thanks Peter,
While that does remove the gap between the two layers it means that I can't put a
trendline through the data points (or do other maths) without creating additional arrays
of just the values.
It seems that you have answered my question. There is no 'easy' way to do what I
want, but there are a few work-arounds which will let me do it with a bit more work.
Thanks for your help....
(looking forward to V5) |
Re: Bar Gap when two Barcharts |
Posted by Peter Kwan on Feb-21-2009 17:11 |
|
Hi Maxx,
I have not tried myself, but I think you can use the $xdata0 and $ydata for a trend layer (and similarly with $xdata1 and $ydata) if you initialize the data to NoValue instead of 0, like:
$xdata0 = array_pad(array(), 200, NoValue);
$xdata1 = array_pad(array(), 200, NoValue);
You also mentioned "do other maths". If you are using the ChartDirector "ArrayMath" object to "do other maths", you may use the above arrays unchanged.
If your are using your own code to do other maths, you may or may not need to create additional arrays. It depends on how your code is written.
In any case, creating your original arrays from the new arrays is easy. It just needs one line of code (eg. use array_splice).
Hope this can help.
Regards
Peter Kwan |
|