|
Custom label alignment over bars |
Posted by Gerrit on Sep-15-2009 21:06 |
|
Hi,
I use an overlapping Bar Chart with label over the bars. If I set the labels with ?barLayer.addCustomGroupLabel(dataGroup, dataItem, label, font, fontSize, fontColor, fontAngle)? ? the labels are displayed centered over the bars.
The problem with overlapping bar is that the labels partly overlapped from the bar before.
I try to set the alignment to the right with ?barLayer.addCustomGroupLabel(?).set Alignment(Chart.TopRight)?. But it doesn?t work, the labels are still centered.
Is where another way to set the alignment?
Regards
Gerrit Scholz |
Re: Custom label alignment over bars |
Posted by Peter Kwan on Sep-16-2009 01:27 |
|
Hi Gerrit,
Currently, for labels outside the bars (aggregate or group labels), ChartDirector will automatically put them at the "far end" of the bar, which can be top, bottom, left or right, depending on whether the bar is positive or negative, and whether it is a vertical or horizontal. It always center align the labels along the center axes of the bars.
In your case, the easiest method I can think of is to simply shift the labels by a fixed amount (like 10 pixels to the right). The code is like (in VB.NET):
Dim t As ChartDirector.TextBox = barLayer.addCustomGroupLabel(?)
t.setPos(10, 0) 'shift the x-coordinate by 10 pixels
Hope this can help.
Regards
Peter Kwan |
Re: Custom label alignment over bars |
Posted by Gerrit on Nov-09-2009 18:48 |
|
Hi Peter,
The bar label text box should start on top-center of the bar.
I tried the following code:
TextBox barLabel = baeLayer.addCustomGroupLabel(?);
int shift = barLabel.getWidth() / 2;
barLabel.setPos(shift, 0);
But it doesn?t work because the width I get from barLabel.getWidth() is always 0.
Please help.
Gerrit Scholz |
Re: Custom label alignment over bars |
Posted by Peter Kwan on Nov-10-2009 01:19 |
|
Hi Gerrit,
ChartDirector does not really compute the text in the label until it needs to draw the label.
(The text in a data label, group label, aggregate label, etc., is variable and subjected to change. For example, your code can add more data, change the x-axis labels, change the default number formats, etc.. Depending on how the label is configured, these changes can affect the label text. So ChartDirector will not compute the label before the chart is drawn.)
In your case, if you know the text in the custom group label, you can measure the text width using:
int width = c.addText(-9999, -9999, textInGroupLabel, "arial.ttf", 8).getWidth();
Instead of shifting the labels, there is a method to force the label to stay in front of the bars, so they cannot be hidden by the bars. The method is to draw two layers, one for the labels, and one for the bars.
The code is like:
//a transparent bar layer just for the labels
BarLayer labelLayer = c.addBarLayer(....);
labelLayer.setBorderColor(Chart.Transparent, Chart.Transparent);
labelLayer.addDataSet(myData0, Chart.Transparent);
labelLayer.addDataSet(myData1, Chart.Transparent);
labelLayer.addDataSet(myData2, Chart.Transparent);
labelLayer.setOverlapRatio(.....);
//add the labels to this layer
labelLayer.addCustomGroupLabel(.....);
......
//the real bar layer for the bars
BarLayer myBarLayer = c.addBarLayer(....);
myBarLayer .addDataSet(myData0, ....);
.......
Hope this can help.
Regards
Peter Kwan |
Re: Custom label alignment over bars |
Posted by Gerrit on Nov-11-2009 00:22 |
|
Hi Peter,
Thank you, for your help. One last question: Is it possible to calculate the top-center coordinate of overlapping bars?
Regards
Gerrit Scholz |
Re: Custom label alignment over bars |
Posted by Peter Kwan on Nov-11-2009 16:51 |
|
Hi Gerrit,
To compute the pixel coordinates, ChartDirector needs to determine the axis scale first. To determine the axis scale, ChartDirector needs all your data. That means you cannot add any other data after you have computed the coordinates (because you should have passed all the data to ChartDirector before computing the coordinates).
The method to use is XYChart.getXCoor and XYChart.getYCoor. For overlapped bars, you may use the boxOffset function below (which is posted in various place in this forum) to compute the overlapping offset.
//A utility function to compute the amount of shifting required
double boxOffset(double barGap, double subBarGap, int noOfDataSets, int currentDataSet)
{
return 0.5 * (1 - barGap) * (2 * currentDataSet - noOfDataSets + 1) / (noOfDataSets - subBarGap);
}
The code is like:
//auto-scale axis - no more data can be added (no addDataSet or adding layers)
c.layout();
int yCoor = c.getYCoor(dataValueOfBar);
int xCoor = c.getXCoor(indexOfBar + boxOffset(0.2, -overlapRatio, noOfDataSets, dataSetNoOfTheBar));
The indexOfBar is the array index that corresponds to your bar.
The overlappingRatio is the parameter you use in setOverlapRatio.
The noOfDataSets are the number of datasets in your bar layer.
The dataSetNoOfTheBar is the data set number of the bar you are interested (the first data set is 0, the second data set is 1, and so on).
Hope this can help.
Regards
Peter Kwan |
|