Help aligning top and bottom axes
Help aligning top and bottom axes
I'm trying to align the top axis labels with the bottom and round it off as well. I was able to align them using the OnGetAxisLabel and OnGetNextAxisLabel, but now I'm trying to adjust the top scale so it fits nicely(labels are rounded off). I need to do this before the axis events. What I really would like to know is the logic Steema uses to determine where to put labels, ie. the interval between the max and first label and each subsequent label. Can anyone help?
-
- Site Admin
- Posts: 1349
- Joined: Thu Jan 01, 1970 12:00 am
- Location: Riudellots de la Selva, Catalonia
- Contact:
Hi Craig,
Could you please send me a VB (or whatever) project that I can run "as is" here to show me where you've got to with this? You could post it to news://www.berneda.com/steema.public.attachments
It will be a pleasure!I'm trying to align the top axis labels with the bottom and round it off as well. I was able to align them using the OnGetAxisLabel and OnGetNextAxisLabel, but now I'm trying to adjust the top scale so it fits nicely(labels are rounded off). I need to do this before the axis events. What I really would like to know is the logic Steema uses to determine where to put labels, ie. the interval between the max and first label and each subsequent label. Can anyone help?
Could you please send me a VB (or whatever) project that I can run "as is" here to show me where you've got to with this? You could post it to news://www.berneda.com/steema.public.attachments
Thank you!
Christopher Ireland (Steema crew)
Please be aware of the newsgroup archives:
http://www.teechart.net/support/search.php
http://groups.google.com
http://codenewsfast.com/
Christopher Ireland (Steema crew)
Please be aware of the newsgroup archives:
http://www.teechart.net/support/search.php
http://groups.google.com
http://codenewsfast.com/
Hi Chris,
I figure it would be too complicated to attach the project since it is rather large and relies on many other files to get data, etc. So I'm hoping you can at least help with some of the general logic. I'll describe what I've done so far:
Here are my axis events:
Now, in my main graph function, I want to determine the max/min for top axis so the labels fall on more even numbers. Here's the logic I've tried first:
1. Determine a suitable increment based on range of top axis
2. Round off the max/min for both axes to nearest decimal
3. Increase the top axis by increment until it is equally divisable by or into bottom axis.
This actually works most of the time, but not if the difference between top and bottom scales is very large, or some other factors, I don't know.
Then I tried determining the top and bottom intervals, based on 1, 2 or 5, and the number of intervals. Then increasing the top axis until it's number of intervals is equally divisable by bottom number. Then make sure the remaining percentage is the same for top and bottom. This also works, almost, but doesn't round off very nice and sometimes get infinite loops because of the precision I have to use.
So this is where I'm stuck, any suggestions would be helpful. Thank you
I figure it would be too complicated to attach the project since it is rather large and relies on many other files to get data, etc. So I'm hoping you can at least help with some of the general logic. I'll describe what I've done so far:
Here are my axis events:
Code: Select all
void CWFGraphDlg::OnBeforeDrawAxesTchart1()
{
_Count = 0;
_Increment1Percentage = 0;
_Increment2Percentage = 0;
}
void CWFGraphDlg::OnGetAxisLabelTchart1(long Axis, long SeriesIndex, long ValueIndex, BSTR* LabelText)
{
// To line up the top axis, we need to first get the bottom axis increments
// When labels are rounded off, the increment between the first label and max point is different
// than the rest(while automatic), hence _Increment1 and _Increment2
// 1st time called, LabelText is maximum, 2nd is minimum, 3rd is the first auto generated label below max
if ( _SyncAxes )
{
if ( Axis == atBottom )
{
double max = m_Chart1.GetAxis().GetBottom().GetMaximum();
double min = m_Chart1.GetAxis().GetBottom().GetMinimum();
if ( (max != min) && (max > 0.00000001) ) // if you retrieve max of 0, it's not exactly 0
{
_Count++;
CString labelText = *LabelText;
labelText.Remove(',');
if ( _Count == 3 )
{
_FirstLabel = atof(labelText);
_Increment1Percentage = (max - _FirstLabel) / (max-min);
}
if ( _Count == 4 )
_Increment2Percentage = (_FirstLabel - atof(labelText)) / (max-min);
}
}
}
}
void CWFGraphDlg::OnGetNextAxisLabelTchart1(long Axis, long LabelIndex, double* LabelValue, BOOL* MoreLabels)
{
// This function allows us to manually set each label, it is called after OnGetAxisLabel
// It will be called as long as MoreLabels = true and LabelValue > min
if ( _SyncAxes )
{
if ( Axis == atTop )
{
double max = m_Chart1.GetAxis().GetTop().GetMaximum();
double min = m_Chart1.GetAxis().GetTop().GetMinimum();
// if you retrieve max of 0, it's not exactly 0
if ( (max != min) && (max > 0.00000001) && (_Increment2Percentage != 0) )
{
*MoreLabels = true;
if ( LabelIndex == 0 ) // The first label is max - increment1
{
*LabelValue = max - (_Increment1Percentage*(max-min));
_FirstLabel = *LabelValue;
}
else // Every other label is previous label - increment2
{
*LabelValue = _FirstLabel - (_Increment2Percentage*(max-min));
_FirstLabel = *LabelValue;
}
}
}
}
}
1. Determine a suitable increment based on range of top axis
2. Round off the max/min for both axes to nearest decimal
3. Increase the top axis by increment until it is equally divisable by or into bottom axis.
This actually works most of the time, but not if the difference between top and bottom scales is very large, or some other factors, I don't know.
Then I tried determining the top and bottom intervals, based on 1, 2 or 5, and the number of intervals. Then increasing the top axis until it's number of intervals is equally divisable by bottom number. Then make sure the remaining percentage is the same for top and bottom. This also works, almost, but doesn't round off very nice and sometimes get infinite loops because of the precision I have to use.
So this is where I'm stuck, any suggestions would be helpful. Thank you
-
- Site Admin
- Posts: 1349
- Joined: Thu Jan 01, 1970 12:00 am
- Location: Riudellots de la Selva, Catalonia
- Contact:
Hi --
I've had a go at a similar problem and came up with the following solution (please excuse the VB code, but the TeeChart AXv6 objects and members are identical):
Please tell me what problems you see with the above proposed solution
Mmm, well, these routines are going to depend, to some extent, on the type of data being fed into each series.So this is where I'm stuck, any suggestions would be helpful. Thank you
I've had a go at a similar problem and came up with the following solution (please excuse the VB code, but the TeeChart AXv6 objects and members are identical):
Code: Select all
Private Sub Form_Load()
With TChart1
.Aspect.View3D = False
.AddSeries scLine
For i = 0 To 90000 Step 10000
.Series(0).AddXY i, Rnd * 100, "", clTeeColor
Next i
.AddSeries scLine
For i = 0 To 17
.Series(1).AddXY i, Rnd * 100, "", clTeeColor
Next i
.Series(1).HorizontalAxis = aTopAxis
.Environment.InternalRepaint
BAxisMax = .Axis.Bottom.Maximum
BAxisMin = .Axis.Bottom.Minimum
BAxisRange = BAxisMax - BAxisMin
BAxisIncrement = .Axis.Bottom.CalcIncrement
BAxisNoLabels = BAxisRange / BAxisIncrement
TAxisMax = .Axis.Top.Maximum
TAxisMin = .Axis.Top.Minimum
TAxisRange = TAxisMax - TAxisMin
TAxisIncrement = TAxisRange / BAxisNoLabels
.Axis.Top.Increment = TAxisIncrement
End With
End Sub
Thank you!
Christopher Ireland (Steema crew)
Please be aware of the newsgroup archives:
http://www.teechart.net/support/search.php
http://groups.google.com
http://codenewsfast.com/
Christopher Ireland (Steema crew)
Please be aware of the newsgroup archives:
http://www.teechart.net/support/search.php
http://groups.google.com
http://codenewsfast.com/
Chris,
That won't work. In your example, the top axis increment would be 1.888888, that doesn't look like a nice label to me
The whole top range needs to be expanded until the number of bottom increments fits evenly into the top, or vice versa.
I still haven't been able to get it yet, I'm about to give up. Although, I wish I new about the .InternalRepaint and .CalcIncrement sooner, that certainly makes things easier!
Let me know if you have any other ideas.
Thanks.
That won't work. In your example, the top axis increment would be 1.888888, that doesn't look like a nice label to me
The whole top range needs to be expanded until the number of bottom increments fits evenly into the top, or vice versa.
I still haven't been able to get it yet, I'm about to give up. Although, I wish I new about the .InternalRepaint and .CalcIncrement sooner, that certainly makes things easier!
Let me know if you have any other ideas.
Thanks.
-
- Site Admin
- Posts: 1349
- Joined: Thu Jan 01, 1970 12:00 am
- Location: Riudellots de la Selva, Catalonia
- Contact:
Hi --
I guess that when mCount = 4 you have "nice" labels -- it's then a case specifying a conditional that defines the label increment you would like to see while stepping through the above logic.
OK, then try running the code below:The whole top range needs to be expanded until the number of bottom increments fits evenly into the top, or vice versa.
Code: Select all
Dim BAxisRange, TAxisRange, BAxisIncrement, TBAxisIncrement, mCount
Private Sub Command1_Click()
With TChart1
.Axis.Top.Increment = TAxisRange / mCount
.Axis.Bottom.Increment = BAxisRange / mCount
End With
mCount = mCount + 1
End Sub
Private Sub Form_Load()
mCount = 2
With TChart1
.Aspect.View3D = False
.AddSeries scLine
For i = 0 To 90000 Step 10000
.Series(0).AddXY i, Rnd * 100, "", clTeeColor
Next i
.AddSeries scLine
For i = 0 To 17
.Series(1).AddXY i, Rnd * 100, "", clTeeColor
Next i
.Series(1).HorizontalAxis = aTopAxis
.Environment.InternalRepaint
BAxisMax = .Axis.Bottom.Maximum
BAxisMin = .Axis.Bottom.Minimum
BAxisRange = BAxisMax - BAxisMin
BAxisIncrement = .Axis.Bottom.CalcIncrement
BAxisNoLabels = BAxisRange / BAxisIncrement
TAxisMax = .Axis.Top.Maximum
TAxisMin = .Axis.Top.Minimum
TAxisRange = TAxisMax - TAxisMin
TAxisIncrement = .Axis.Top.CalcIncrement
TAxisNoLabels = TAxisRange / TAxisIncrement
End With
End Sub
Thank you!
Christopher Ireland (Steema crew)
Please be aware of the newsgroup archives:
http://www.teechart.net/support/search.php
http://groups.google.com
http://codenewsfast.com/
Christopher Ireland (Steema crew)
Please be aware of the newsgroup archives:
http://www.teechart.net/support/search.php
http://groups.google.com
http://codenewsfast.com/
Sorry Chris, that won't work either. The answer is not to change the increment, but the max/min values so the top scale will fit evenly into the bottom.
Actually, I found a solution. Here's what I do:
- Round off both max/min top and bottom to nearest increment.
- Increase the top range by an amount that makes its' number of increments equally divisible by or into the bottom number of increments.
- Let my axis events handle the rest.
It was just a matter of getting that second calculation correct.
Thanks for your help.
Actually, I found a solution. Here's what I do:
- Round off both max/min top and bottom to nearest increment.
- Increase the top range by an amount that makes its' number of increments equally divisible by or into the bottom number of increments.
- Let my axis events handle the rest.
It was just a matter of getting that second calculation correct.
Thanks for your help.