Perhaps an axis property NumberOfDisplayedLabels could be implemented ?
Also, I notice that the axis property Increment is a mininum value to be used. That is, sometimes the axis will display an increment that is greater than the specified Increment but is not an integer multiple of that Increment. If I specifiy 0.2 for the Increment, at times the increment may be shown as 0.5. Any way to force the displayed increment to be an integer multiple of the one specified so that in my example it would show as 0.4 or 0.8 or 1.0 etc /
scale problem on bottom axis (overlap)
-
- Newbie
- Posts: 50
- Joined: Wed Mar 10, 2004 5:00 am
Hi, Marjan.Marjan wrote:Hi, Leroy.
Using the latest TeeChart version (7.04) and the code bellow axis label increment value was not changed even when chart was scrolled. The trick is to set LabelsSeparation to 0 and force, regardless of possible overlaps, display of all labels.Code: Select all
Series1->FillSampleValues(5000); Series1->GetHorizAxis->LabelsSeparation = 0; Series1->GetHorizAxis->Increment = 200.0; Series1->GetHorizAxis->LabelsOnAxis := true; Series1->GetHorizAxis->RoundFirstLabel = true;
I’m back to trying to solve this problem again.
I think that the problem is that I must display X-Axis labels in two different formats. The actual values stored in the chart are sample numbers that start at 1 and increment by 1. Thus, in a typical chart my X-Axis values range from 1 to, perhaps, 2,000,000.
One of the X-Axis display formats is just the sample number as described above. The other format is time-based, with the sample number converted into microseconds or milliseconds, for example:
200 uS or 10000.200 mS
When I use your suggested settings with the time-based format, the labels overlap:
When I use them with the sample count format, they work for small numbers, but the labels are sparser than I’d like:
But if I change the increment value to 100, with larger sample count values they overlap:
Setting LabelSeparation to various values doesn’t solve the problem either. For example, with LabelSeparation set to 10, the values between 100,000 and 1,000,000 display as a nearly continuous series of digits:
Setting LabelSeparation to 20 results in the same display. If I set LabelSeparation to 30, the above range is displayed properly, but values between 10,000 and 100,000 are crowded too closely.
I tried creating a list of coordinates and labels in the OnDrawLabel event handler and setting Text to “” so that it wouldn’t display any labels. Then in the OnAfterDraw event, I looped through my list of labels and drew them with DrawAxisLabel so that I could skip labels as needed. This didn’t work because OnDrawLabel fired again when I called DrawAxisLabel.
Matters are complicated by the fact that the chart is resizable and the user can choose the number of points to display across the width of the chart.
I need to find some way to handle labeling properly for both my label formats. How can I accomplish this?
-Leroy
P.S. Last time I posted in this thread it took about 2 weeks to get an answer. I hope you will be able to respond more quickly this time.
>This didn’t work because OnDrawLabel fired again when I called >DrawAxisLabel.
Perhaps try to temporarily turn off that event firing, then do your change, then turn the event back on ?
chart1.OnGetAxisLabel := nil;
{
make changes to property that normally fires the bove event
}
chart1.OnGetAxisLabel := Chart1GetAxisLabel;
Perhaps try to temporarily turn off that event firing, then do your change, then turn the event back on ?
chart1.OnGetAxisLabel := nil;
{
make changes to property that normally fires the bove event
}
chart1.OnGetAxisLabel := Chart1GetAxisLabel;
-
- Newbie
- Posts: 50
- Joined: Wed Mar 10, 2004 5:00 am
Thanks for the suggestion, Steve. I'd thought of that, but if I turn off the event, then TeeChart will be redrawing its labels directly (the event is where I set the label text to an empty string to prevent the chart's labels from showing).9333098 wrote:>This didn’t work because OnDrawLabel fired again when I called >DrawAxisLabel.
Perhaps try to temporarily turn off that event firing, then do your change, then turn the event back on ?
chart1.OnGetAxisLabel := nil;
{
make changes to property that normally fires the bove event
}
chart1.OnGetAxisLabel := Chart1GetAxisLabel;
The problem with the event firing is that when it fires, I add the label to my list of pending labels and, since it fires when I draw a pending label, I end up in an infinite loop - draw a label from my list, OnDrawLabel fires, I add another label to the list, etc. I guess I could set a flag when I drawing labels from my list that would be checked in OnDrawLabel to prevent a new list entry, but this is a rather ugly solution.
I also thought of setting Axis->Labels to false so the chart doesn't draw labels at all, but if I do that the chart doesn't reserve room for my labels and I also have to go to the work of computing label positions and drawing my X-Axis grid lines and ticks.
There's got to be a better solution!
-Leroy
-
- Newbie
- Posts: 50
- Joined: Wed Mar 10, 2004 5:00 am
Hi, Leroy.
When chart size or axis increment changes, all you have to do is calculate best new labels and add repopulate the Axes.Bottom.Items. Using this approach you can fully control not only the axis labels, but axis increment and (if needed) additional axis label properties (like font, etc..).
In this case I'd manually calculate all axis labels needed for display and then repopulate chart each time it's drawn. This way you'll be able to fully control individual axis labels and even use variable increment. Here is an example (of course, you'll use more complex code <g>):tried creating a list of coordinates and labels in the OnDrawLabel event handler and setting Text to “” so that it wouldn’t display any labels. Then in the OnAfterDraw event, I looped through my list of labels and drew them with DrawAxisLabel so that I could skip labels as needed. This didn’t work because OnDrawLabel fired again when I called DrawAxisLabel
Code: Select all
procedure TForm1.FormCreate(Sender: TObject);
var labels: Array of double;
i: Integer;
begin
Series1.FillSampleValues(2000);
// example : show 7 labels
SetLength(Labels,7);
Labels[0] := 0;
Labels[1] := 300;
Labels[3] := 600;
Labels[4] := 900;
Labels[5] := 1400;
Labels[6] := 1900;
With Chart1.Axes.Bottom.Items do
begin
Clear;
for i := 0 to High(Labels) do
Add(Labels[i],FormatFloat('0.00 ys',Labels[i]));
end;
end;
Marjan Slatinek,
http://www.steema.com
http://www.steema.com
-
- Newbie
- Posts: 50
- Joined: Wed Mar 10, 2004 5:00 am
How do I know what values the labels should have? In other words, how do I know where the chart has placed the grid lines and ticks? There doesn't seem to be any way to specify them - increment and separation seem to be more suggestions than anything.Marjan wrote:Hi, Leroy.
In this case I'd manually calculate all axis labels needed for display and then repopulate chart each time it's drawn. This way you'll be able to fully control individual axis labels and even use variable increment. Here is an example (of course, you'll use more complex code <g>):tried creating a list of coordinates and labels in the OnDrawLabel event handler and setting Text to “” so that it wouldn’t display any labels. Then in the OnAfterDraw event, I looped through my list of labels and drew them with DrawAxisLabel so that I could skip labels as needed. This didn’t work because OnDrawLabel fired again when I called DrawAxisLabelWhen chart size or axis increment changes, all you have to do is calculate best new labels and add repopulate the Axes.Bottom.Items. Using this approach you can fully control not only the axis labels, but axis increment and (if needed) additional axis label properties (like font, etc..).Code: Select all
procedure TForm1.FormCreate(Sender: TObject); var labels: Array of double; i: Integer; begin Series1.FillSampleValues(2000); // example : show 7 labels SetLength(Labels,7); Labels[0] := 0; Labels[1] := 300; Labels[3] := 600; Labels[4] := 900; Labels[5] := 1400; Labels[6] := 1900; With Chart1.Axes.Bottom.Items do begin Clear; for i := 0 to High(Labels) do Add(Labels[i],FormatFloat('0.00 ys',Labels[i])); end; end;
Where (in what event handler) do I do this?
As I said:
Also, how do I prevent the chart from drawing its own labels while saving room for me to draw my own? If I disable labels entirely then the chart draws without leaving room for me to draw the labels.tried creating a list of coordinates and labels in the OnDrawLabel event handler and setting Text to “” so that it wouldn’t display any labels. Then in the OnAfterDraw event, I looped through my list of labels and drew them with DrawAxisLabel so that I could skip labels as needed. This didn’t work because OnDrawLabel fired again when I called DrawAxisLabel