Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

WPF Graph log scale grid lines too dense

Solved!
Go to solution

Hi, I'm using logarithmic vertical scale and minor grid lines, and that's what I have when the range is too wide:

 

obrázok.png

 

How can I avoid grid lines being so dense that they touch each other?

 

I would like to preserve behavior that new "minor divisions scale" starts each major division, like here on the pic, and also I'm OK with major divisions being automatically chosen depending on how I resize the control. The most acceptable way for me would be setting number of minor divisions between neighboring major divisions, but I didn't find so far how I can set this.

0 Kudos
Message 1 of 4
(2,321 Views)
Solution
Accepted by topic author The_Bn

The way to change the subdivisions is by setting the Mode of the MinorDivisions on the axis. Unfortunately, the “Count” mode will always divide the range evenly across the screen, and will not reflect the logarithmic change in spacing. To achieve that, you can use a custom mode:

 

public class FixedCountSubdivisionsMode : RangeDivisionsMode {
    public int Count { get; set; } = 10;

    protected override IList<TData> GetDivisionsCore<TData>( IRangeDataMapper<TData> dataMapper, int divisionsEstimate ) {
        return Auto.GetDivisions( dataMapper, divisionsEstimate );
    }

    protected override IList<TData> GetSubdivisionsCore<TData>( IRangeDataMapper<TData> dataMapper, IList<TData> dependentDivisions ) {
        // (Note: this example assumes a "double" axis type)
        var majorDivisions = (IList<double>)dependentDivisions;
        var pairs = majorDivisions.Zip( majorDivisions.Skip( 1 ), Tuple.Create );
        var subdivisions = pairs.SelectMany( pair =>
            Enumerable.Repeat( (pair.Item1 + pair.Item2) / Count, Count - 1 )
                      .Select( ( interval, i ) => pair.Item1 + interval * i )
        );
        return subdivisions.Cast<TData>( ).ToList( );
    }
}

 

 

You can set this on your axis in XAML:

<ni:AxisDouble.MinorDivisions>
    <ni:RangeDivisions>
        <ni:RangeDivisions.Mode>
            <local:FixedCountSubdivisionsMode Count="5" />
        </ni:RangeDivisions.Mode>
    </ni:RangeDivisions>
</ni:AxisDouble.MinorDivisions>

Or in code:

axis.MinorDivisions = new RangeDivisions { Mode = new FixedCountSubdivisionsMode { Count = 5 } };

 

The CustomLogarithmicRangeDivisionsMode created for another question works similarly, but will always show subdivisions approaching every intervening logarithm power across the range, instead of just the major divisions.

~ Paul H
0 Kudos
Message 2 of 4
(2,261 Views)

Thanks! This works fine after few changes:

var subdivisions = pairs.SelectMany(pair =>
    Enumerable.Repeat((pair.Item2 - pair.Item1) / Count, Count - 1)
              .Select((interval, i) => pair.Item1 + interval * (i + 1))
);

 

Message 3 of 4
(2,251 Views)

(Sorry, was definitely paying more attention to the divisions setup, than the actual math — thanks for fixing my averaging and off-by-one errors ∶)

~ Paul H
0 Kudos
Message 4 of 4
(2,236 Views)