|
Multi-layer Bar Chart & Bar Width |
Posted by Goldie Lesser on Jan-26-2011 07:41 |
|
Hi,
I am having trouble with a bar chart I have created (see code below).
The issue is that I do not want to have a very wide bar if there is only one or two bar layers.
I thought I could solve this by using Layer.SetBarWidth(70, 7).
However, when I try to use that function and I have 2 bars, the bars do not touch.
I have already set Layer.setBarGap(0.3, Chart.TouchBar).
Any suggestions would be much appreciated.
Thanks,
Goldie
<%@ Language="C#" Debug="true"%>
<%@ Import Namespace="ChartDirector" %>
<%@ Register TagPrefix="chart" Namespace="ChartDirector" Assembly="netchartdir" %>
<html>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
/*
Green #9bbb59
Red #c0504d
Blue #4f81bd
Orange #e79e11
Purple #8653a0
Yellow #e2e43e
Darker Blue #5048bd
*
Brighter Red #cf3535
Lime #44c147
Pink #d72eb5
*/
int[] colors = { 0xc0504d, 0x4f81bd, 0xe79e11, 0x9bbb59, 0x8653a0, 0xe2e43e, 0x5048bd, 0xcf3535, 0x44c147, 0xd72eb5
,0xc0504d, 0x4f81bd, 0xe79e11, 0x9bbb59, 0x8653a0, 0xe2e43e, 0x5048bd, 0xcf3535, 0x44c147, 0xd72eb5 };
string[] groupNames = { "A", "B", "C", "D", "E", "F" };
double minScoreRange = 1300.0;
double maxScoreRange = 1700.0;
double[][] scores = new double[3][];
scores[0] = new double[6] {1345, 1389, 1500, 1490, 1475, 1525 };
scores[1] = new double[6] { 1500, 1659, 1625, 1550, 1475, 1575 };
scores[2] = new double[6] { 1345, 1389, 1500, 1490, 1475, 1525 };
//scores[3] = new double[6] { 1500, 1659, 1625, 1550, 1475, 1575 };
//scores[4] = new double[6] { 1345, 1389, 1500, 1490, 1475, 1525 };
string[] legendLabels = new string[10] { "01/21/2011", "01/30/2011", "02/29/2011", "03/04/2011", "03/15/2011", "04/02/2011", "04/27/2011", "05/13/2011", "07/24/2011", "07/31/2011" };
// Create a XYChart object of size 550 x 250 pixels
XYChart chart = new XYChart(1100, 600);
// Set the plot area at (110, 0) and of size 350 x 225.
// background colors (0xffffff and 0xffffff)
chart.setPlotArea(350, 0, 630, 540, 0xffffff, 0xffffff, Chart.Transparent);
// Add a legend box at (447, 75) using horizontal layout. Use 11 pt Calibri font,
// with transparent background
chart.addLegend(1000, 50, true, "Calibri", 11).setBackground(Chart.Transparent, Chart.Transparent);
// Reserve 20 pixels at the top of the y-axis for the legend box
chart.yAxis().setTopMargin(20);
chart.yAxis().setLinearScale(minScoreRange, maxScoreRange + 1, 50);
// Draw the ticks between label positions (instead of at label positions)
chart.xAxis().setTickOffset(0.5);
chart.xAxis().setLabelStyle("Calibri", 11);
chart.yAxis().setLabelStyle("Calibri", 11);
chart.xAxis().setLabelGap(10);
chart.yAxis().setLabelGap(5);
// Set the x axis labels
chart.xAxis().setLabels(groupNames);
//swap the axes so chart is horizontal
chart.swapXY();
// Add a multi-bar layer with 3 data sets
BarLayer layer = chart.addBarLayer2(Chart.Side, 0);
// Configure the bars within a group to touch each others (no gap)
layer.setBarGap(0.3, Chart.TouchBar);
layer.setBarWidth(70, 7);
layer.setBorderColor(Chart.Transparent);
//layer.setOverlapRatio(0.01, false);
int numAttempts = scores.Length;
for (int i = 0; i < numAttempts; i++)
{
layer.addDataSet(scores[i], colors[i], legendLabels[i]);
}
// output the chart
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "image/png";
Response.BinaryWrite(chart.makeChart2(Chart.PNG));
Response.End();
}
</script>
</html> |
Re: Multi-layer Bar Chart & Bar Width |
Posted by Peter Kwan on Jan-26-2011 17:42 |
|
Hi Goldie,
If your x-axis (by default, it is the bottom of the plot area) is 630 pixels wide, and you plot 10 bars, then each "bar slot" will be 63 pixels wide. In each bar slot, there will be a bar, and possibly some empty space (the bar gap). If you use setBarWidth to configure the bar width (say to 30 pixels), the remaining space (63 - 30 = 33 pixels) will be the bar gap. If you use setBarGap to configure the gap size, the remaining space will be the bar width. So you should only use either setBarGap or setBarWidth. If you use both, the last one will prevail.
For your case, do you mean you want to "pack" the bars so that they are on the left side of the chart, and that the right side is empty? You can do this by "shortening" the x-axis. For example, if you have 10 bars, but the x-axis is only 300 pixels wide, then each bar slot will be 30 pixels wide.
To shorten the x-axis, you may shorten the plot area, or you may use Axis.setMargin to reserve part of the x-axis as "margin". For example:
//The bar should not exceed 70 pixels wide. The x-axis is shortened if necessary.
if (scores[0].Length * 70 < c.getPlotArea().getWidth())
c.xAxis().setMargin(c.getPlotArea().getWidth() - scores[0].Length * 70);
Hope this can help.
Regards
Peter Kwan |
Re: Multi-layer Bar Chart & Bar Width |
Posted by Goldie Lesser on Jan-26-2011 22:49 |
|
Hi Peter,
Yes I want to "pack" the bars together, so it is more visually appealing.
I seem to not have a definition for getPlotArea().
I could have an older version of the library, but I am not sure how to know what version the DLL is?
Thanks,
Goldie |
Re: Multi-layer Bar Chart & Bar Width |
Posted by Peter Kwan on Jan-27-2011 00:49 |
|
Hi Goldie,
There is a sample ASPX "ChartDirector/CSharpASP/cdinfo.aspx" included in ChartDirector. Please try that ASPX page. It will tell you your ChartDirector version.
If you do not have the getPlotArea, you may simply hard coded the width:
//assume plot area width is 600
if (scores[0].Length * 70 < 600)
c.xAxis().setMargin(600 - scores[0].Length * 70);
Hope this can help.
Regards
Peter Kwan |
Re: Multi-layer Bar Chart & Bar Width |
Posted by Goldie Lesser on Jan-27-2011 02:09 |
|
Hi Peter,
This code makes the bars next to each other.
I want the sub-bars to be next to each other.
Is that possible?
PS still working on figuring out the version. |
Re: Multi-layer Bar Chart & Bar Width |
Posted by Goldie Lesser on Jan-27-2011 02:57 |
|
Hi Peter,
We are using version 4.1 of the ChartDirector.
Thanks,
Goldie |
Re: Multi-layer Bar Chart & Bar Width |
Posted by Peter Kwan on Jan-27-2011 11:24 |
|
Hi Goldie,
If you use:
layer.setBarGap(0.8, Chart.TouchBar);
then the subBar is always next to each other.
For example:
if (scores[0].Length * 70 < 600)
c.xAxis().setMargin(600 - scores[0].Length * 70);
layer.setBarGap(0.8, Chart.TouchBar);
Hope this can help.
Regards
Peter Kwan |
Re: Multi-layer Bar Chart & Bar Width |
Posted by Goldie Lesser on Jan-27-2011 22:25 |
|
Hi Peter,
Thanks so much for all of your help with this.
As you can see in my code above, I already am setting the sub-bars to touch with this
line:
layer.setBarGap(0.3, Chart.TouchBar);
However, when I set the fixed with on the bars with the following line, the bars no longer touch:
layer.setBarWidth(70, 7);
Is there a way to have the sub-bars touch, even if they have a fixed width?
Thanks,
Goldie |
Re: Multi-layer Bar Chart & Bar Width |
Posted by Peter Kwan on Jan-28-2011 01:54 |
|
Hi Goldie,
Logically, for the sub-bars to touch, ChartDirector must be allowed to set the bars to variable width.
For example, if the total width of the bar group is 70 pixels, and you have 4 sub-bars, then some sub-bars must be 17 pixels wide, and some must be 18 pixels wide, otherwise the sub-bars cannot touch and still meet the 70 pixels total width criteria.
For your case, I suggest you just use setBarGap to set a gap so that the bar group width is close to 70 pixels, and let ChartDirector determine the sub-bar widths so that they touch.
Assuming you are not using Axis.setMargin, the the normal bar slot width is (assume the plot area width is 600).
double slotWidth = 600.0 / scores[0].Length;
double barGap = 1 - 70 / slotWidth;
layer.setBarGap(barGap, Chart.TouchBar);
Hope this can help.
Regards
Peter Kwan |
|