Quantcast
Channel: OxyPlot (moved to GitHub)
Viewing all articles
Browse latest Browse all 2061

New Post: Steps with LogarithmicAxis

$
0
0
Hello there,
it's been a while... Finally got to work on this.
everytimer: Thanks for pointing me in the right direction!

Main differences between my implementation and original (assuming base=10, but works with any other base):
-You can zoom out and display many decades without messing up the labels
-A Decade is subdivided if there's enough space for the labels
-The IntervalLength property is actually used by the algorithm

Example:
Image

For several reasons, I did my fix in the form of a simple override.
In case anyone's interested and not bothered by a little VB:
Imports System.Math

Public Class MyLogAxis
    Inherits Axes.LogarithmicAxis

    Public Overrides Sub GetTickValues(ByRef majorLabelValues As IList(Of Double), ByRef majorTickValues As IList(Of Double), ByRef minorTickValues As IList(Of Double))

        majorTickValues = New List(Of Double)
        minorTickValues = New List(Of Double)

        Dim width As Integer = Me.ScreenMax.X - Me.ScreenMin.X
        Dim totalBW As Double = Log(Me.ActualMaximum, Me.Base) - Log(Me.ActualMinimum, Me.Base)
        Dim BWratio As Double = width / totalBW

        If totalBW < 1 Then
            MyBase.GetTickValues(majorLabelValues, majorTickValues, minorTickValues)

        ElseIf BWratio < Me.IntervalLength Then
            Dim steps As Integer = Ceiling(Me.IntervalLength / BWratio)
            Dim c As Double = Ceiling(Log(Me.ActualMinimum, Me.Base))

            While c < Floor(Log(Me.ActualMaximum, Me.Base))
                minorTickValues.Add(Round(Pow(Me.Base, c), 10))
                If c Mod steps = 0 Then
                    majorTickValues.Add(Round(Pow(Me.Base, c), 10))
                End If
                c += 1
            End While

        Else
            Dim c As Double = Floor(Log(Me.ActualMinimum, Me.Base))
            Dim v As Double
            Dim c2 As Double
            Dim lower As Double
            While c < Ceiling(Log(Me.ActualMaximum, Me.Base)) + 1

                v = Pow(Me.Base, c)
                If v > Me.ActualMinimum And v < Me.ActualMaximum Then
                    majorTickValues.Add(Round(v, 10))
                End If

                Dim a As Integer = 1
                lower = c

                While a < Me.Base
                    c2 = c + Log(a, Me.Base)
                    v = Pow(Me.Base, c2)
                    If v + 0.00001 >= Me.ActualMinimum And v <= Me.ActualMaximum + 0.00001 Then
                        minorTickValues.Add(Round(Pow(Me.Base, c2), 10))
                        If BWratio * Min(c2 - lower, c + 1 - c2) > Me.IntervalLength Then
                            majorTickValues.Add(Round(v, 10))
                            lower = c2
                        End If
                    End If

                    a += 1
                End While
                c += 1
            End While
        End If
        majorLabelValues = majorTickValues
    End Sub
End Class

Viewing all articles
Browse latest Browse all 2061

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>