Page 1 of 2
Howto make automatic labels of the left axis be a multiple of some value
Posted: Tue Aug 01, 2023 10:07 am
by 15685014
Hello.
I need to make automatic labels of the left axis be a multiple of
125. And ensure horizontal gridlines to be drawn for
every label.
So that my chart would look something like this (depending on the actual
Y values):
- 1.png (48.39 KiB) Viewed 75112 times
- 2.png (51.56 KiB) Viewed 75112 times
Re: Howto make automatic labels of the left axis be a multiple of some value
Posted: Tue Aug 01, 2023 11:06 am
by Christopher
Hello,
I think this does it for you:
Code: Select all
public Form1()
{
InitializeComponent();
var line1 = new Line(tChart1.Chart);
var line2 = new Line(tChart1.Chart);
var rnd = new Random();
var max = 900;
for (int i = 0; i < 50; i++)
{
line1.Add(rnd.Next(max));
line2.Add(rnd.Next(max));
}
tChart1.Axes.Left.Increment = 125;
tChart1.Axes.Left.Labels.Separation = 1;
tChart1.Axes.Left.Grid.DrawEvery = 1;
tChart1.Axes.Left.AutomaticMinimum = false;
tChart1.Axes.Left.Minimum = 0;
tChart1.Axes.Left.GetAxisDrawLabel += Left_GetAxisDrawLabel;
}
private void Left_GetAxisDrawLabel(object sender, GetAxisDrawLabelEventArgs e)
{
e.DrawLabel = e.LabelValue % 125 == 0;
}
Try changing the value of 'max'.
Re: Howto make automatic labels of the left axis be a multiple of some value
Posted: Tue Aug 01, 2023 11:38 am
by 15685014
Thank you. That is exactly what I need. Only one question left: what does tChart1.Axes.Left.Labels.Separation = 1; stand for? I see no changes on a chart when adjusting that value (I've tried 2, 3, 5 and 10).
Re: Howto make automatic labels of the left axis be a multiple of some value
Posted: Tue Aug 01, 2023 2:07 pm
by Christopher
Hello,
in theory it:
- Screenshot from 2023-08-01 15-45-53.png (17.83 KiB) Viewed 75102 times
but it doesn't seem to work very well. What does work is setting max to a high value (e.g. 9000) and setting Separation to 0—here we can see that it leaves no minimum distance, as it should.
Re: Howto make automatic labels of the left axis be a multiple of some value
Posted: Wed Aug 02, 2023 5:23 am
by 15685014
I guess you have a TeeChart.xml file. Could you share it so I don't have to go online every time I need a property description. Thank you.
Re: Howto make automatic labels of the left axis be a multiple of some value
Posted: Wed Aug 02, 2023 7:48 am
by Christopher
There's a Steema.TeeChart.chm file shipped in the TeeChart NuGet packages which has the xml documentation compiled into it. This is what we would suggest you use for 'offline' API documentation.
- Screenshot from 2023-08-02 09-46-43.png (102.4 KiB) Viewed 75065 times
Re: Howto make automatic labels of the left axis be a multiple of some value
Posted: Wed Aug 02, 2023 8:05 am
by 15685014
But I would like to see function/property description right into IntelliSense. Could you share TeeChart.xml please.
Re: Howto make automatic labels of the left axis be a multiple of some value
Posted: Wed Aug 02, 2023 8:10 am
by 15685014
I have done further testing and found that your code does not always work correctly. I you change
125 to
350 and set
max = 8000 - it is ok:
- Безымянный.png (74.46 KiB) Viewed 75063 times
But you set
max = 9000 (and more) - most labels are not multiples of
350:
- Безымянный1.png (64.71 KiB) Viewed 75063 times
I've expected auto labels to be set to a multiple of 350 (for example
0,
1750,
3500,
5250,
7000 and
8750). Are there any workarounds?
Re: Howto make automatic labels of the left axis be a multiple of some value
Posted: Thu Aug 03, 2023 7:52 am
by Christopher
Hello,
for finer control, you can use the GetNextAxisLabel event, e.g.
Code: Select all
const int _increment = 350;
const int _max = 20000;
public Form1()
{
InitializeComponent();
var line1 = new Line(tChart1.Chart);
var line2 = new Line(tChart1.Chart);
var rnd = new Random();
for (int i = 0; i < 50; i++)
{
line1.Add(rnd.Next(_max));
line2.Add(rnd.Next(_max));
}
tChart1.Axes.Left.Increment = _increment;
tChart1.Axes.Left.Labels.Separation = 1;
tChart1.Axes.Left.Grid.DrawEvery = 1;
tChart1.Axes.Left.AutomaticMinimum = false;
tChart1.Axes.Left.Minimum = 0;
tChart1.GetNextAxisLabel += TChart1_GetNextAxisLabel;
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
tChart1.Header.Text = $"v.{Utils.Version}, size: {tChart1.Height}x{tChart1.Width}, increment: {_increment}, max: {_max}";
}
private void TChart1_GetNextAxisLabel(object sender, GetNextAxisLabelEventArgs e)
{
var multiplier = Utils.Round(tChart1.Axes.Left.Maximum / _increment / 10);
int GetValue(int index)
{
return _increment * multiplier * index;
}
if (sender == tChart1.Axes.Left)
{
e.Stop = false;
switch (e.LabelIndex)
{
case 0: e.LabelValue = 0; break;
case 1: e.LabelValue = GetValue(1); break;
case 2: e.LabelValue = GetValue(2); break;
case 3: e.LabelValue = GetValue(3); break;
case 4: e.LabelValue = GetValue(4); break;
case 5: e.LabelValue = GetValue(5); break;
case 6: e.LabelValue = GetValue(6); break;
case 7: e.LabelValue = GetValue(7); break;
case 8: e.LabelValue = GetValue(8); break;
case 9: e.LabelValue = GetValue(9); break;
default: e.Stop = true; break;
}
}
}
- Screenshot from 2023-08-03 09-50-40.png (261.52 KiB) Viewed 75037 times
I'm working on getting the xml file to you and will do so when I can.
Re: Howto make automatic labels of the left axis be a multiple of some value
Posted: Thu Aug 03, 2023 8:34 am
by Christopher
A more generic solution would be:
Code: Select all
private void TChart1_GetNextAxisLabel(object sender, GetNextAxisLabelEventArgs e)
{
var max_labels = 20;
var num = Utils.Round(_max / _increment);
num = num >= max_labels ? max_labels : num;
var multiplier = Utils.Round(_max / _increment / num);
int GetValue(int index)
{
return _increment * multiplier * index;
}
if (sender == tChart1.Axes.Left)
{
e.Stop = false;
if(e.LabelIndex <= num)
{
e.LabelValue = GetValue(e.LabelIndex);
}
else
{
e.Stop = true;
}
}
}
- Screenshot from 2023-08-03 10-34-03.png (265.58 KiB) Viewed 75032 times
Re: Howto make automatic labels of the left axis be a multiple of some value
Posted: Thu Aug 03, 2023 3:11 pm
by Christopher
bairog wrote: ↑Wed Aug 02, 2023 8:05 am
But I would like to see function/property description right into IntelliSense. Could you share
TeeChart.xml please.
I've uploaded new NuGet packages containing the necessary xml documentation comments—they are only needed in .NET Framework, according to my tests, as Visual Studio is somehow able to read these comments directly from .NET Core assemblies without the need for the xml file.
Re: Howto make automatic labels of the left axis be a multiple of some value
Posted: Fri Aug 04, 2023 7:00 am
by 15685014
Christopher wrote: ↑Thu Aug 03, 2023 8:34 am
A more generic solution would be:
Your code is not working very well when
_max / _increment is close to a multiple of
max_labels but is slightly less.
In your specific example (
max_labels = 20 and
_increment = 175) you can just set
_max = 13900 (13900 / 175 =
79.428) and get the following picture (there is a big gap between the last label and left axis actual maximum):
- Безымянный.png (74.38 KiB) Viewed 75003 times
I have tested some workarounds and the best I have come up with is changing
_multiplier formula from
Utils.Round(_max / _increment / _num) to
(Int32)Math.Round((Double)_max / _increment / _num). With this approach, a greater multiplier is chosen in 50% cases.
So the situation I've decribed (
max_labels = 20,
_increment = 175 and
_max = 13900) becomes:
- Безымянный1.png (72.19 KiB) Viewed 75003 times
My approach is not always perfect: when
(Double)_max / _increment / _num is close to
n.5 but slightly less there is same gap (but it is 2 times smaller). For example for
_max = 12200 (12200/175/20 =
3.485, so
_multiplier is still
3) I get the following picture:
- Безымянный2.png (72.11 KiB) Viewed 75003 times
If you have any ideas how to further improve my adjusted algorithm - please share it. Thank you.
Re: Howto make automatic labels of the left axis be a multiple of some value
Posted: Fri Aug 04, 2023 8:03 am
by Christopher
bairog wrote: ↑Fri Aug 04, 2023 7:00 am
If you have any ideas how to further improve my adjusted algorithm - please share it. Thank you.
How about:
Code: Select all
private void TChart1_GetNextAxisLabel(object sender, GetNextAxisLabelEventArgs e)
{
var mod = _max % _increment;
var local_max = _max;
if(mod != 0)
{
local_max = _max + (_increment - mod);
}
var max_labels = 20;
var num = Utils.Round(local_max / _increment);
var multiplier = Utils.Round(num / max_labels);
int GetValue(int index)
{
return _increment * multiplier * index;
}
if (sender == tChart1.Axes.Left)
{
e.Stop = false;
if(e.LabelIndex <= num)
{
e.LabelValue = GetValue(e.LabelIndex);
}
else
{
e.Stop = true;
}
}
}
Re: Howto make automatic labels of the left axis be a multiple of some value
Posted: Fri Aug 04, 2023 8:40 am
by 15685014
Unfortunately with this code labels count can greatly exceed
max_labels value. For example for
_max = 5300 the are
30 labels:
- Безымянный.png (69.46 KiB) Viewed 74994 times
Re: Howto make automatic labels of the left axis be a multiple of some value
Posted: Fri Aug 04, 2023 8:49 am
by Christopher
bairog wrote: ↑Fri Aug 04, 2023 8:40 am
Unfortunately with this code labels count can greatly exceed max_labels value. For example for _max = 5300 the are 30 labels:
Yes, that's true. But I'm sure you get the idea now of what the TeeChart possibilities are, and so can adapt your code to them.