08-25-2020 10:25 AM
Hi,
I'm using a graph with RangeLabeledDivisions on horizontal axis with mode AutoWithoutExtremes, and what I found out is that major lines density depends on the range:
I expected that the graphs will look the same except of values being 10 times lower/greater, but it isn't so and it's confusing for me and for users.
The XAML is
<ni:Graph>
<ni:Graph.Axes>
<ni:AxisDouble Name="AxisHoriz1" Orientation="Horizontal"
Adjuster="None" MinorDivisions="{x:Null}" Range="0,1">
<ni:AxisDouble.MajorDivisions>
<ni:RangeLabeledDivisions Mode="AutoWithoutExtremes"></ni:RangeLabeledDivisions>
</ni:AxisDouble.MajorDivisions>
</ni:AxisDouble>
</ni:Graph.Axes>
</ni:Graph>
and the same goes for the second graph with range from 0 to 10.
I've found a topic on this forum
https://forums.ni.com/t5/Measurement-Studio-for-NET/wpf-graph-scale-with-dynamic-ticks/m-p/2698977
and what I did for my case is:
protected override IList<TData> GetDivisionsCore<TData>(IRangeDataMapper<TData> dataMapper, int divisionsEstimate)
{
return AutoWithoutExtremes.GetDivisions<TData>(dataMapper, 10);
}
and it works just great! However, if I do so, I will get 10 grid lines no matter the width of the control, but I'd like to preserve the behavior that new lines are added/hidden dynamically in between when I resize.
What I want to get is:
1) Cut off lines count dependency on the range
2) Preserve lines count dependency on the control's width
As I understand, I cannot rely solely on divisionsEstimate for that, since it already depends on both.
As an option, I'm ready to implement my fully custom divisions mode, if it's the only way. In this case I assume that I have implemented the function which takes:
a) axis range
b) size of the graph's plot area along this axis
And returns set of values at which grid lines should be.
But with assumption that I implement such an algorithm, I didn't manage to figure out how I can apply this logic correctly by overriding methods, and which methods to override.
Solved! Go to Solution.
08-26-2020 02:35 PM
You are correct that the built-in estimate uses both the size of the plot area and the labels to try to fill the space with divisions. To achieve your desired effect (same size = same division count), you could try creating an estimate only based on the plot area size:
public class SizeEstimateRangeDivisionsMode : RangeDivisionsMode {
private readonly Axis<double> axis;
public SizeEstimateRangeDivisionsMode( Axis<double> axis ) => this.axis = axis;
public override bool RequiresDivisionsEstimate => true;
protected override IList<TData> GetDivisionsCore<TData>( IRangeDataMapper<TData> dataMapper, int divisionsEstimate ) {
const double DivisionSpacing = 40;
Size plotAreaSize = axis.GraphParent.GetPlotAreaSize( false );
double size = axis.Orientation == Orientation.Horizontal ? plotAreaSize.Width : plotAreaSize.Height;
int estimate = (int)(size / DivisionSpacing);
return Auto.GetDivisions( dataMapper, estimate );
}
protected override IList<TData> GetSubdivisionsCore<TData>( IRangeDataMapper<TData> dataMapper, IList<TData> dependentDivisions ) {
return Auto.GetSubdivisions( dataMapper, dependentDivisions );
}
}
08-27-2020 04:46 AM
Thanks, that's what I need