    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Graphics.Rendering.Chart.Axis.Floating
    -- Copyright   :  (c) Tim Docker 2010, 2014
    -- License     :  BSD-style (see chart/COPYRIGHT)
    --
    -- Calculate and render floating value axes
    -- including doubles with linear, log, and percentage scaling.
    --

    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE TemplateHaskell #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# OPTIONS_GHC -fno-warn-orphans #-}

    module Graphics.Rendering.Chart.Axis.Floating(
        Percent(..),
        LinearAxisParams(..),
        LogValue(..),
        LogAxisParams(..),
        scaledAxis,
        autoScaledAxis,
        autoScaledLogAxis,
        autoSteps,

        la_labelf,
        la_nLabels,
        la_nTicks,

        loga_labelf
    ) where

    import Data.List(minimumBy, nub)
    import Data.Ord (comparing)
    import Data.Default.Class
    import Numeric (showEFloat, showFFloat)

    import Control.Lens
    import Graphics.Rendering.Chart.Geometry
    import Graphics.Rendering.Chart.Utils
    import Graphics.Rendering.Chart.Axis.Types

    -- Note: the following code uses explicit Integer types
    -- to avoid -Wall 'defaulting to Integer' messages.

    instance PlotValue Double where
        toValue :: Double -> Double
    toValue  = Double -> Double
    forall a. a -> a
    id
        fromValue :: Double -> Double
    fromValue= Double -> Double
    forall a. a -> a
    id
        autoAxis :: AxisFn Double
    autoAxis = LinearAxisParams Double -> AxisFn Double
    forall a. RealFloat a => LinearAxisParams a -> AxisFn a
    autoScaledAxis LinearAxisParams Double
    forall a. Default a => a
    def

    instance PlotValue Float where
        toValue :: Float -> Double
    toValue  = Float -> Double
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac
        fromValue :: Double -> Float
    fromValue= Double -> Float
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac
        autoAxis :: AxisFn Float
    autoAxis = LinearAxisParams Float -> AxisFn Float
    forall a. RealFloat a => LinearAxisParams a -> AxisFn a
    autoScaledAxis LinearAxisParams Float
    forall a. Default a => a
    def

    -- | A wrapper class for doubles used to indicate they are to
    -- be plotted against a percentage axis.
    newtype Percent = Percent {Percent -> Double
    unPercent :: Double}
        deriving (Percent -> Percent -> Bool
    (Percent -> Percent -> Bool)
    -> (Percent -> Percent -> Bool) -> Eq Percent
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Percent -> Percent -> Bool
    == :: Percent -> Percent -> Bool
    $c/= :: Percent -> Percent -> Bool
    /= :: Percent -> Percent -> Bool
    Eq,Eq Percent
    Eq Percent =>
    (Percent -> Percent -> Ordering)
    -> (Percent -> Percent -> Bool)
    -> (Percent -> Percent -> Bool)
    -> (Percent -> Percent -> Bool)
    -> (Percent -> Percent -> Bool)
    -> (Percent -> Percent -> Percent)
    -> (Percent -> Percent -> Percent)
    -> Ord Percent
    Percent -> Percent -> Bool
    Percent -> Percent -> Ordering
    Percent -> Percent -> Percent
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: Percent -> Percent -> Ordering
    compare :: Percent -> Percent -> Ordering
    $c< :: Percent -> Percent -> Bool
    < :: Percent -> Percent -> Bool
    $c<= :: Percent -> Percent -> Bool
    <= :: Percent -> Percent -> Bool
    $c> :: Percent -> Percent -> Bool
    > :: Percent -> Percent -> Bool
    $c>= :: Percent -> Percent -> Bool
    >= :: Percent -> Percent -> Bool
    $cmax :: Percent -> Percent -> Percent
    max :: Percent -> Percent -> Percent
    $cmin :: Percent -> Percent -> Percent
    min :: Percent -> Percent -> Percent
    Ord,Integer -> Percent
    Percent -> Percent
    Percent -> Percent -> Percent
    (Percent -> Percent -> Percent)
    -> (Percent -> Percent -> Percent)
    -> (Percent -> Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Integer -> Percent)
    -> Num Percent
    forall a.
    (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (Integer -> a)
    -> Num a
    $c+ :: Percent -> Percent -> Percent
    + :: Percent -> Percent -> Percent
    $c- :: Percent -> Percent -> Percent
    - :: Percent -> Percent -> Percent
    $c* :: Percent -> Percent -> Percent
    * :: Percent -> Percent -> Percent
    $cnegate :: Percent -> Percent
    negate :: Percent -> Percent
    $cabs :: Percent -> Percent
    abs :: Percent -> Percent
    $csignum :: Percent -> Percent
    signum :: Percent -> Percent
    $cfromInteger :: Integer -> Percent
    fromInteger :: Integer -> Percent
    Num,Num Percent
    Ord Percent
    (Num Percent, Ord Percent) => (Percent -> Rational) -> Real Percent
    Percent -> Rational
    forall a. (Num a, Ord a) => (a -> Rational) -> Real a
    $ctoRational :: Percent -> Rational
    toRational :: Percent -> Rational
    Real,Num Percent
    Num Percent =>
    (Percent -> Percent -> Percent)
    -> (Percent -> Percent)
    -> (Rational -> Percent)
    -> Fractional Percent
    Rational -> Percent
    Percent -> Percent
    Percent -> Percent -> Percent
    forall a.
    Num a =>
    (a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
    $c/ :: Percent -> Percent -> Percent
    / :: Percent -> Percent -> Percent
    $crecip :: Percent -> Percent
    recip :: Percent -> Percent
    $cfromRational :: Rational -> Percent
    fromRational :: Rational -> Percent
    Fractional,Fractional Percent
    Real Percent
    (Real Percent, Fractional Percent) =>
    (forall b. Integral b => Percent -> (b, Percent))
    -> (forall b. Integral b => Percent -> b)
    -> (forall b. Integral b => Percent -> b)
    -> (forall b. Integral b => Percent -> b)
    -> (forall b. Integral b => Percent -> b)
    -> RealFrac Percent
    forall b. Integral b => Percent -> b
    forall b. Integral b => Percent -> (b, Percent)
    forall a.
    (Real a, Fractional a) =>
    (forall b. Integral b => a -> (b, a))
    -> (forall b. Integral b => a -> b)
    -> (forall b. Integral b => a -> b)
    -> (forall b. Integral b => a -> b)
    -> (forall b. Integral b => a -> b)
    -> RealFrac a
    $cproperFraction :: forall b. Integral b => Percent -> (b, Percent)
    properFraction :: forall b. Integral b => Percent -> (b, Percent)
    $ctruncate :: forall b. Integral b => Percent -> b
    truncate :: forall b. Integral b => Percent -> b
    $cround :: forall b. Integral b => Percent -> b
    round :: forall b. Integral b => Percent -> b
    $cceiling :: forall b. Integral b => Percent -> b
    ceiling :: forall b. Integral b => Percent -> b
    $cfloor :: forall b. Integral b => Percent -> b
    floor :: forall b. Integral b => Percent -> b
    RealFrac,Fractional Percent
    Percent
    Fractional Percent =>
    Percent
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent -> Percent)
    -> (Percent -> Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> (Percent -> Percent)
    -> Floating Percent
    Percent -> Percent
    Percent -> Percent -> Percent
    forall a.
    Fractional a =>
    a
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> Floating a
    $cpi :: Percent
    pi :: Percent
    $cexp :: Percent -> Percent
    exp :: Percent -> Percent
    $clog :: Percent -> Percent
    log :: Percent -> Percent
    $csqrt :: Percent -> Percent
    sqrt :: Percent -> Percent
    $c** :: Percent -> Percent -> Percent
    ** :: Percent -> Percent -> Percent
    $clogBase :: Percent -> Percent -> Percent
    logBase :: Percent -> Percent -> Percent
    $csin :: Percent -> Percent
    sin :: Percent -> Percent
    $ccos :: Percent -> Percent
    cos :: Percent -> Percent
    $ctan :: Percent -> Percent
    tan :: Percent -> Percent
    $casin :: Percent -> Percent
    asin :: Percent -> Percent
    $cacos :: Percent -> Percent
    acos :: Percent -> Percent
    $catan :: Percent -> Percent
    atan :: Percent -> Percent
    $csinh :: Percent -> Percent
    sinh :: Percent -> Percent
    $ccosh :: Percent -> Percent
    cosh :: Percent -> Percent
    $ctanh :: Percent -> Percent
    tanh :: Percent -> Percent
    $casinh :: Percent -> Percent
    asinh :: Percent -> Percent
    $cacosh :: Percent -> Percent
    acosh :: Percent -> Percent
    $catanh :: Percent -> Percent
    atanh :: Percent -> Percent
    $clog1p :: Percent -> Percent
    log1p :: Percent -> Percent
    $cexpm1 :: Percent -> Percent
    expm1 :: Percent -> Percent
    $clog1pexp :: Percent -> Percent
    log1pexp :: Percent -> Percent
    $clog1mexp :: Percent -> Percent
    log1mexp :: Percent -> Percent
    Floating,Floating Percent
    RealFrac Percent
    (RealFrac Percent, Floating Percent) =>
    (Percent -> Integer)
    -> (Percent -> Int)
    -> (Percent -> (Int, Int))
    -> (Percent -> (Integer, Int))
    -> (Integer -> Int -> Percent)
    -> (Percent -> Int)
    -> (Percent -> Percent)
    -> (Int -> Percent -> Percent)
    -> (Percent -> Bool)
    -> (Percent -> Bool)
    -> (Percent -> Bool)
    -> (Percent -> Bool)
    -> (Percent -> Bool)
    -> (Percent -> Percent -> Percent)
    -> RealFloat Percent
    Int -> Percent -> Percent
    Integer -> Int -> Percent
    Percent -> Bool
    Percent -> Int
    Percent -> Integer
    Percent -> (Int, Int)
    Percent -> (Integer, Int)
    Percent -> Percent
    Percent -> Percent -> Percent
    forall a.
    (RealFrac a, Floating a) =>
    (a -> Integer)
    -> (a -> Int)
    -> (a -> (Int, Int))
    -> (a -> (Integer, Int))
    -> (Integer -> Int -> a)
    -> (a -> Int)
    -> (a -> a)
    -> (Int -> a -> a)
    -> (a -> Bool)
    -> (a -> Bool)
    -> (a -> Bool)
    -> (a -> Bool)
    -> (a -> Bool)
    -> (a -> a -> a)
    -> RealFloat a
    $cfloatRadix :: Percent -> Integer
    floatRadix :: Percent -> Integer
    $cfloatDigits :: Percent -> Int
    floatDigits :: Percent -> Int
    $cfloatRange :: Percent -> (Int, Int)
    floatRange :: Percent -> (Int, Int)
    $cdecodeFloat :: Percent -> (Integer, Int)
    decodeFloat :: Percent -> (Integer, Int)
    $cencodeFloat :: Integer -> Int -> Percent
    encodeFloat :: Integer -> Int -> Percent
    $cexponent :: Percent -> Int
    exponent :: Percent -> Int
    $csignificand :: Percent -> Percent
    significand :: Percent -> Percent
    $cscaleFloat :: Int -> Percent -> Percent
    scaleFloat :: Int -> Percent -> Percent
    $cisNaN :: Percent -> Bool
    isNaN :: Percent -> Bool
    $cisInfinite :: Percent -> Bool
    isInfinite :: Percent -> Bool
    $cisDenormalized :: Percent -> Bool
    isDenormalized :: Percent -> Bool
    $cisNegativeZero :: Percent -> Bool
    isNegativeZero :: Percent -> Bool
    $cisIEEE :: Percent -> Bool
    isIEEE :: Percent -> Bool
    $catan2 :: Percent -> Percent -> Percent
    atan2 :: Percent -> Percent -> Percent
    RealFloat)

    instance Show Percent where
        show :: Percent -> String
    show (Percent Double
    d) = Double -> String
    forall d. RealFloat d => d -> String
    showD (Double
    dDouble -> Double -> Double
    forall a. Num a => a -> a -> a
    *Double
    100) String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "%"

    instance PlotValue Percent where
        toValue :: Percent -> Double
    toValue  = Percent -> Double
    unPercent
        fromValue :: Double -> Percent
    fromValue= Double -> Percent
    Percent
        autoAxis :: AxisFn Percent
    autoAxis = LinearAxisParams Percent -> AxisFn Percent
    forall a. RealFloat a => LinearAxisParams a -> AxisFn a
    autoScaledAxis LinearAxisParams Percent
    forall a. Default a => a
    def {-_la_labelf=-}

    -- | A wrapper class for doubles used to indicate they are to
    -- be plotted against a log axis.
    newtype LogValue = LogValue {LogValue -> Double
    unLogValue :: Double}
        deriving (LogValue -> LogValue -> Bool
    (LogValue -> LogValue -> Bool)
    -> (LogValue -> LogValue -> Bool) -> Eq LogValue
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: LogValue -> LogValue -> Bool
    == :: LogValue -> LogValue -> Bool
    $c/= :: LogValue -> LogValue -> Bool
    /= :: LogValue -> LogValue -> Bool
    Eq, Eq LogValue
    Eq LogValue =>
    (LogValue -> LogValue -> Ordering)
    -> (LogValue -> LogValue -> Bool)
    -> (LogValue -> LogValue -> Bool)
    -> (LogValue -> LogValue -> Bool)
    -> (LogValue -> LogValue -> Bool)
    -> (LogValue -> LogValue -> LogValue)
    -> (LogValue -> LogValue -> LogValue)
    -> Ord LogValue
    LogValue -> LogValue -> Bool
    LogValue -> LogValue -> Ordering
    LogValue -> LogValue -> LogValue
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: LogValue -> LogValue -> Ordering
    compare :: LogValue -> LogValue -> Ordering
    $c< :: LogValue -> LogValue -> Bool
    < :: LogValue -> LogValue -> Bool
    $c<= :: LogValue -> LogValue -> Bool
    <= :: LogValue -> LogValue -> Bool
    $c> :: LogValue -> LogValue -> Bool
    > :: LogValue -> LogValue -> Bool
    $c>= :: LogValue -> LogValue -> Bool
    >= :: LogValue -> LogValue -> Bool
    $cmax :: LogValue -> LogValue -> LogValue
    max :: LogValue -> LogValue -> LogValue
    $cmin :: LogValue -> LogValue -> LogValue
    min :: LogValue -> LogValue -> LogValue
    Ord, Integer -> LogValue
    LogValue -> LogValue
    LogValue -> LogValue -> LogValue
    (LogValue -> LogValue -> LogValue)
    -> (LogValue -> LogValue -> LogValue)
    -> (LogValue -> LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (Integer -> LogValue)
    -> Num LogValue
    forall a.
    (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (Integer -> a)
    -> Num a
    $c+ :: LogValue -> LogValue -> LogValue
    + :: LogValue -> LogValue -> LogValue
    $c- :: LogValue -> LogValue -> LogValue
    - :: LogValue -> LogValue -> LogValue
    $c* :: LogValue -> LogValue -> LogValue
    * :: LogValue -> LogValue -> LogValue
    $cnegate :: LogValue -> LogValue
    negate :: LogValue -> LogValue
    $cabs :: LogValue -> LogValue
    abs :: LogValue -> LogValue
    $csignum :: LogValue -> LogValue
    signum :: LogValue -> LogValue
    $cfromInteger :: Integer -> LogValue
    fromInteger :: Integer -> LogValue
    Num, Num LogValue
    Ord LogValue
    (Num LogValue, Ord LogValue) =>
    (LogValue -> Rational) -> Real LogValue
    LogValue -> Rational
    forall a. (Num a, Ord a) => (a -> Rational) -> Real a
    $ctoRational :: LogValue -> Rational
    toRational :: LogValue -> Rational
    Real, Num LogValue
    Num LogValue =>
    (LogValue -> LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (Rational -> LogValue)
    -> Fractional LogValue
    Rational -> LogValue
    LogValue -> LogValue
    LogValue -> LogValue -> LogValue
    forall a.
    Num a =>
    (a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
    $c/ :: LogValue -> LogValue -> LogValue
    / :: LogValue -> LogValue -> LogValue
    $crecip :: LogValue -> LogValue
    recip :: LogValue -> LogValue
    $cfromRational :: Rational -> LogValue
    fromRational :: Rational -> LogValue
    Fractional, Fractional LogValue
    Real LogValue
    (Real LogValue, Fractional LogValue) =>
    (forall b. Integral b => LogValue -> (b, LogValue))
    -> (forall b. Integral b => LogValue -> b)
    -> (forall b. Integral b => LogValue -> b)
    -> (forall b. Integral b => LogValue -> b)
    -> (forall b. Integral b => LogValue -> b)
    -> RealFrac LogValue
    forall b. Integral b => LogValue -> b
    forall b. Integral b => LogValue -> (b, LogValue)
    forall a.
    (Real a, Fractional a) =>
    (forall b. Integral b => a -> (b, a))
    -> (forall b. Integral b => a -> b)
    -> (forall b. Integral b => a -> b)
    -> (forall b. Integral b => a -> b)
    -> (forall b. Integral b => a -> b)
    -> RealFrac a
    $cproperFraction :: forall b. Integral b => LogValue -> (b, LogValue)
    properFraction :: forall b. Integral b => LogValue -> (b, LogValue)
    $ctruncate :: forall b. Integral b => LogValue -> b
    truncate :: forall b. Integral b => LogValue -> b
    $cround :: forall b. Integral b => LogValue -> b
    round :: forall b. Integral b => LogValue -> b
    $cceiling :: forall b. Integral b => LogValue -> b
    ceiling :: forall b. Integral b => LogValue -> b
    $cfloor :: forall b. Integral b => LogValue -> b
    floor :: forall b. Integral b => LogValue -> b
    RealFrac, Fractional LogValue
    LogValue
    Fractional LogValue =>
    LogValue
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue -> LogValue)
    -> (LogValue -> LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> (LogValue -> LogValue)
    -> Floating LogValue
    LogValue -> LogValue
    LogValue -> LogValue -> LogValue
    forall a.
    Fractional a =>
    a
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> Floating a
    $cpi :: LogValue
    pi :: LogValue
    $cexp :: LogValue -> LogValue
    exp :: LogValue -> LogValue
    $clog :: LogValue -> LogValue
    log :: LogValue -> LogValue
    $csqrt :: LogValue -> LogValue
    sqrt :: LogValue -> LogValue
    $c** :: LogValue -> LogValue -> LogValue
    ** :: LogValue -> LogValue -> LogValue
    $clogBase :: LogValue -> LogValue -> LogValue
    logBase :: LogValue -> LogValue -> LogValue
    $csin :: LogValue -> LogValue
    sin :: LogValue -> LogValue
    $ccos :: LogValue -> LogValue
    cos :: LogValue -> LogValue
    $ctan :: LogValue -> LogValue
    tan :: LogValue -> LogValue
    $casin :: LogValue -> LogValue
    asin :: LogValue -> LogValue
    $cacos :: LogValue -> LogValue
    acos :: LogValue -> LogValue
    $catan :: LogValue -> LogValue
    atan :: LogValue -> LogValue
    $csinh :: LogValue -> LogValue
    sinh :: LogValue -> LogValue
    $ccosh :: LogValue -> LogValue
    cosh :: LogValue -> LogValue
    $ctanh :: LogValue -> LogValue
    tanh :: LogValue -> LogValue
    $casinh :: LogValue -> LogValue
    asinh :: LogValue -> LogValue
    $cacosh :: LogValue -> LogValue
    acosh :: LogValue -> LogValue
    $catanh :: LogValue -> LogValue
    atanh :: LogValue -> LogValue
    $clog1p :: LogValue -> LogValue
    log1p :: LogValue -> LogValue
    $cexpm1 :: LogValue -> LogValue
    expm1 :: LogValue -> LogValue
    $clog1pexp :: LogValue -> LogValue
    log1pexp :: LogValue -> LogValue
    $clog1mexp :: LogValue -> LogValue
    log1mexp :: LogValue -> LogValue
    Floating, Floating LogValue
    RealFrac LogValue
    (RealFrac LogValue, Floating LogValue) =>
    (LogValue -> Integer)
    -> (LogValue -> Int)
    -> (LogValue -> (Int, Int))
    -> (LogValue -> (Integer, Int))
    -> (Integer -> Int -> LogValue)
    -> (LogValue -> Int)
    -> (LogValue -> LogValue)
    -> (Int -> LogValue -> LogValue)
    -> (LogValue -> Bool)
    -> (LogValue -> Bool)
    -> (LogValue -> Bool)
    -> (LogValue -> Bool)
    -> (LogValue -> Bool)
    -> (LogValue -> LogValue -> LogValue)
    -> RealFloat LogValue
    Int -> LogValue -> LogValue
    Integer -> Int -> LogValue
    LogValue -> Bool
    LogValue -> Int
    LogValue -> Integer
    LogValue -> (Int, Int)
    LogValue -> (Integer, Int)
    LogValue -> LogValue
    LogValue -> LogValue -> LogValue
    forall a.
    (RealFrac a, Floating a) =>
    (a -> Integer)
    -> (a -> Int)
    -> (a -> (Int, Int))
    -> (a -> (Integer, Int))
    -> (Integer -> Int -> a)
    -> (a -> Int)
    -> (a -> a)
    -> (Int -> a -> a)
    -> (a -> Bool)
    -> (a -> Bool)
    -> (a -> Bool)
    -> (a -> Bool)
    -> (a -> Bool)
    -> (a -> a -> a)
    -> RealFloat a
    $cfloatRadix :: LogValue -> Integer
    floatRadix :: LogValue -> Integer
    $cfloatDigits :: LogValue -> Int
    floatDigits :: LogValue -> Int
    $cfloatRange :: LogValue -> (Int, Int)
    floatRange :: LogValue -> (Int, Int)
    $cdecodeFloat :: LogValue -> (Integer, Int)
    decodeFloat :: LogValue -> (Integer, Int)
    $cencodeFloat :: Integer -> Int -> LogValue
    encodeFloat :: Integer -> Int -> LogValue
    $cexponent :: LogValue -> Int
    exponent :: LogValue -> Int
    $csignificand :: LogValue -> LogValue
    significand :: LogValue -> LogValue
    $cscaleFloat :: Int -> LogValue -> LogValue
    scaleFloat :: Int -> LogValue -> LogValue
    $cisNaN :: LogValue -> Bool
    isNaN :: LogValue -> Bool
    $cisInfinite :: LogValue -> Bool
    isInfinite :: LogValue -> Bool
    $cisDenormalized :: LogValue -> Bool
    isDenormalized :: LogValue -> Bool
    $cisNegativeZero :: LogValue -> Bool
    isNegativeZero :: LogValue -> Bool
    $cisIEEE :: LogValue -> Bool
    isIEEE :: LogValue -> Bool
    $catan2 :: LogValue -> LogValue -> LogValue
    atan2 :: LogValue -> LogValue -> LogValue
    RealFloat)

    instance Show LogValue where
        show :: LogValue -> String
    show (LogValue Double
    x) = Double -> String
    forall a. Show a => a -> String
    show Double
    x

    instance PlotValue LogValue where
        toValue :: LogValue -> Double
    toValue (LogValue Double
    x) = Double -> Double
    forall a. Floating a => a -> a
    log Double
    x
        fromValue :: Double -> LogValue
    fromValue Double
    d          = Double -> LogValue
    LogValue (Double -> Double
    forall a. Floating a => a -> a
    exp Double
    d)
        autoAxis :: AxisFn LogValue
    autoAxis             = LogAxisParams LogValue -> AxisFn LogValue
    forall a. RealFloat a => LogAxisParams a -> AxisFn a
    autoScaledLogAxis LogAxisParams LogValue
    forall a. Default a => a
    def

    -- | Show a list of axis labels.
    -- If some are too big or all are too small, switch to scientific notation for all.
    -- If the range is much smaller than the mean, use an offset.
    -- TODO: show this offset only once, not on every label.
    -- When thinking about improving this function,
    -- https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/ticker.py
    -- is a good read.
    --
    -- >>> showDs [0, 1, 2 :: Double]
    -- ["0","1","2"]
    --
    -- >>> showDs [0, 1000000, 2000000 :: Double]
    -- ["0.0e0","1.0e6","2.0e6"]
    --
    -- >>> showDs [0, 0.001, 0.002 :: Double]
    -- ["0","0.001","0.002"]
    --
    -- >>> showDs [-10000000, -1000000, 9000000 :: Double]
    -- ["-1.0e7","-1.0e6","9.0e6"]
    --
    -- >>> showDs [10, 11, 12 :: Double]
    -- ["10","11","12"]
    --
    -- >>> showDs [100, 101, 102 :: Double]
    -- ["100","101","102"]
    --
    -- >>> showDs [100000, 100001, 100002 :: Double]
    -- ["100000","100001","100002"]
    --
    -- >>> showDs [1000000, 1000001, 1000002 :: Double]
    -- ["1.0e6 + 0","1.0e6 + 1","1.0e6 + 2"]
    --
    -- >>> showDs [10000000, 10000001, 10000002 :: Double]
    -- ["1.0e7 + 0","1.0e7 + 1","1.0e7 + 2"]
    --
    -- >>> showDs [-10000000, -10000001, -10000002 :: Double]
    -- ["-1.0e7 + 2","-1.0e7 + 1","-1.0e7 + 0"]
    --
    -- prop> let [s0, s1] = showDs [x, x + 1.0 :: Double] in s0 /= s1
    showDs :: forall d . (RealFloat d) => [d] -> [String]
    showDs :: forall d. RealFloat d => [d] -> [String]
    showDs [d]
    xs = case [d] -> [String]
    forall d. RealFloat d => [d] -> [String]
    showWithoutOffset [d]
    xs of
      (String
    s0:[String]
    others)
        | String -> [String] -> Bool
    forall {t}. Eq t => t -> [t] -> Bool
    anyEqualNeighbor String
    s0 [String]
    others -> ShowS -> [String] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map ShowS
    addShownOffset ([String] -> [String]) -> [String] -> [String]
    forall a b. (a -> b) -> a -> b
    $ [d] -> [String]
    forall d. RealFloat d => [d] -> [String]
    showWithoutOffset ((d -> d) -> [d] -> [d]
    forall a b. (a -> b) -> [a] -> [b]
    map (\d
    x -> d
    x d -> d -> d
    forall a. Num a => a -> a -> a
    - d
    offset) [d]
    xs)
      [String]
    s -> [String]
    s
      where
        anyEqualNeighbor :: t -> [t] -> Bool
    anyEqualNeighbor t
    z0 (t
    z1:[t]
    others)
          | t
    z0 t -> t -> Bool
    forall a. Eq a => a -> a -> Bool
    == t
    z1 = Bool
    True
          | Bool
    otherwise = t -> [t] -> Bool
    anyEqualNeighbor t
    z1 [t]
    others
        anyEqualNeighbor t
    _ [] = Bool
    False

        -- Use the min for offset. Another good choice could be the mean.
        offset :: d
        offset :: d
    offset = [d] -> d
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    minimum [d]
    xs
        shownOffset :: String
    shownOffset = case [d] -> [String]
    forall d. RealFloat d => [d] -> [String]
    showWithoutOffset [d
    offset] of
          [String
    r] -> String
    r
          [String]
    rs -> ShowS
    forall a. HasCallStack => String -> a
    error ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ String
    "showDs: shownOffset expected 1 element, got " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show ([String] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [String]
    rs)

        addShownOffset :: String -> String
        addShownOffset :: ShowS
    addShownOffset (Char
    '-':String
    x) = String
    shownOffset String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " - " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    x
        addShownOffset String
    x = String
    shownOffset String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " + " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    x

    showWithoutOffset :: RealFloat d => [d] -> [String]
    showWithoutOffset :: forall d. RealFloat d => [d] -> [String]
    showWithoutOffset [d]
    xs
      | Bool
    useScientificNotation = (d -> String) -> [d] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (Maybe Int -> d -> String
    forall d. RealFloat d => Maybe Int -> d -> String
    showEFloat' (Int -> Maybe Int
    forall a. a -> Maybe a
    Just Int
    1)) [d]
    xs
      | Bool
    otherwise = (d -> String) -> [d] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map d -> String
    forall d. RealFloat d => d -> String
    showD [d]
    xs
      where
        -- use scientific notation if max value is too big or too small
        useScientificNotation :: Bool
    useScientificNotation = d
    maxAbs d -> d -> Bool
    forall a. Ord a => a -> a -> Bool
    >= d
    1e6 Bool -> Bool -> Bool
    || d
    maxAbs d -> d -> Bool
    forall a. Ord a => a -> a -> Bool
    <= d
    1e-6
        maxAbs :: d
    maxAbs = [d] -> d
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum ((d -> d) -> [d] -> [d]
    forall a b. (a -> b) -> [a] -> [b]
    map d -> d
    forall a. Num a => a -> a
    abs [d]
    xs)

    -- | Changes the behavior of showEFloat to drop more than one trailings 0.
    -- Instead of 1.000e4 you get 1.0e4
    showEFloat' :: forall d . RealFloat d => Maybe Int -> d -> String
    showEFloat' :: forall d. RealFloat d => Maybe Int -> d -> String
    showEFloat' Maybe Int
    mdigits d
    x = ShowS
    forall a. [a] -> [a]
    reverse ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ ShowS
    cleanup0 (ShowS
    forall a. [a] -> [a]
    reverse String
    shown0)
      where
        shown0 :: String
    shown0 = Maybe Int -> d -> ShowS
    forall a. RealFloat a => Maybe Int -> a -> ShowS
    showEFloat Maybe Int
    mdigits d
    x String
    ""

        -- wait until we get the "e"
        cleanup0 :: String -> String
        cleanup0 :: ShowS
    cleanup0 (e :: Char
    e@Char
    'e':String
    ys) = Char
    eChar -> ShowS
    forall a. a -> [a] -> [a]
    :ShowS
    cleanup1 String
    ys
        cleanup0 (Char
    y:String
    ys) = Char
    y Char -> ShowS
    forall a. a -> [a] -> [a]
    : ShowS
    cleanup0 String
    ys
        cleanup0 [] = ShowS
    forall a. [a] -> [a]
    reverse String
    shown0 -- something went wrong, just return the original

        -- get rid of redundant 0s before the '.'
        cleanup1 :: String -> String
        cleanup1 :: ShowS
    cleanup1 (Char
    '0':ys :: String
    ys@(Char
    '0':String
    _)) = ShowS
    cleanup1 String
    ys
        cleanup1 String
    y = String
    y

    showD :: (RealFloat d) => d -> String
    showD :: forall d. RealFloat d => d -> String
    showD d
    x = case ShowS
    forall a. [a] -> [a]
    reverse ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ Maybe Int -> d -> ShowS
    forall a. RealFloat a => Maybe Int -> a -> ShowS
    showFFloat Maybe Int
    forall a. Maybe a
    Nothing d
    x String
    "" of
                Char
    '0':Char
    '.':String
    r -> ShowS
    forall a. [a] -> [a]
    reverse String
    r
                String
    r         -> ShowS
    forall a. [a] -> [a]
    reverse String
    r

    data LinearAxisParams a = LinearAxisParams {
        -- | The function used to show the axes labels.
        forall a. LinearAxisParams a -> [a] -> [String]
    _la_labelf  :: [a] -> [String],

        -- | The target number of labels to be shown.
        forall a. LinearAxisParams a -> Int
    _la_nLabels :: Int,

        -- | The target number of ticks to be shown.
        forall a. LinearAxisParams a -> Int
    _la_nTicks  :: Int
    }

    instance (Show a, RealFloat a) => Default (LinearAxisParams a) where
      def :: LinearAxisParams a
    def = LinearAxisParams
        { _la_labelf :: [a] -> [String]
    _la_labelf    = [a] -> [String]
    forall d. RealFloat d => [d] -> [String]
    showDs
        , _la_nLabels :: Int
    _la_nLabels   = Int
    5
        , _la_nTicks :: Int
    _la_nTicks    = Int
    50
        }

    -- | Generate a linear axis with the specified bounds
    scaledAxis :: RealFloat a => LinearAxisParams a -> (a,a) -> AxisFn a
    scaledAxis :: forall a. RealFloat a => LinearAxisParams a -> (a, a) -> AxisFn a
    scaledAxis LinearAxisParams a
    lap rs :: (a, a)
    rs@(a
    minV,a
    maxV) [a]
    ps0 = (a -> Double)
    -> (Double -> a)
    -> ([a] -> [String])
    -> ([a], [a], [a])
    -> AxisData a
    forall x.
    Ord x =>
    (x -> Double)
    -> (Double -> x)
    -> ([x] -> [String])
    -> ([x], [x], [x])
    -> AxisData x
    makeAxis' a -> Double
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac Double -> a
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac
                                             (LinearAxisParams a -> [a] -> [String]
    forall a. LinearAxisParams a -> [a] -> [String]
    _la_labelf LinearAxisParams a
    lap) ([a]
    labelvs,[a]
    tickvs,[a]
    gridvs)
      where
        ps :: [a]
    ps        = (a -> Bool) -> [a] -> [a]
    forall a. (a -> Bool) -> [a] -> [a]
    filter a -> Bool
    forall a. RealFloat a => a -> Bool
    isValidNumber [a]
    ps0
        range :: [a] -> (a, a)
    range []  = (a
    0,a
    1)
        range [a]
    _   | a
    minV a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    maxV = if a
    minVa -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    ==a
    0 then (-a
    1,a
    1) else
                                   let d :: a
    d = a -> a
    forall a. Num a => a -> a
    abs (a
    minV a -> a -> a
    forall a. Num a => a -> a -> a
    * a
    0.01) in (a
    minVa -> a -> a
    forall a. Num a => a -> a -> a
    -a
    d,a
    maxVa -> a -> a
    forall a. Num a => a -> a -> a
    +a
    d)
                  | Bool
    otherwise    = (a, a)
    rs
        labelvs :: [a]
    labelvs   = (Rational -> a) -> [Rational] -> [a]
    forall a b. (a -> b) -> [a] -> [b]
    map Rational -> a
    forall a. Fractional a => Rational -> a
    fromRational ([Rational] -> [a]) -> [Rational] -> [a]
    forall a b. (a -> b) -> a -> b
    $ a -> (a, a) -> [Rational]
    forall a. RealFloat a => a -> (a, a) -> [Rational]
    steps (Int -> a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (LinearAxisParams a -> Int
    forall a. LinearAxisParams a -> Int
    _la_nLabels LinearAxisParams a
    lap)) (a, a)
    r
        tickvs :: [a]
    tickvs    = (Rational -> a) -> [Rational] -> [a]
    forall a b. (a -> b) -> [a] -> [b]
    map Rational -> a
    forall a. Fractional a => Rational -> a
    fromRational ([Rational] -> [a]) -> [Rational] -> [a]
    forall a b. (a -> b) -> a -> b
    $ a -> (a, a) -> [Rational]
    forall a. RealFloat a => a -> (a, a) -> [Rational]
    steps (Int -> a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (LinearAxisParams a -> Int
    forall a. LinearAxisParams a -> Int
    _la_nTicks LinearAxisParams a
    lap))
                                             ([a] -> a
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    minimum [a]
    labelvs,[a] -> a
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum [a]
    labelvs)
        gridvs :: [a]
    gridvs    = [a]
    labelvs
        r :: (a, a)
    r         = [a] -> (a, a)
    forall {a}. [a] -> (a, a)
    range [a]
    ps

    -- | Generate a linear axis automatically, scaled appropriately for the
    -- input data.
    autoScaledAxis :: RealFloat a => LinearAxisParams a -> AxisFn a
    autoScaledAxis :: forall a. RealFloat a => LinearAxisParams a -> AxisFn a
    autoScaledAxis LinearAxisParams a
    lap [a]
    ps0 = LinearAxisParams a -> (a, a) -> AxisFn a
    forall a. RealFloat a => LinearAxisParams a -> (a, a) -> AxisFn a
    scaledAxis LinearAxisParams a
    lap (a, a)
    rs [a]
    ps
      where
        ps :: [a]
    ps = (a -> Bool) -> [a] -> [a]
    forall a. (a -> Bool) -> [a] -> [a]
    filter a -> Bool
    forall a. RealFloat a => a -> Bool
    isValidNumber [a]
    ps0
        rs :: (a, a)
    rs = ([a] -> a
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    minimum [a]
    ps,[a] -> a
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum [a]
    ps)

    steps :: RealFloat a => a -> (a,a) -> [Rational]
    steps :: forall a. RealFloat a => a -> (a, a) -> [Rational]
    steps a
    nSteps rs :: (a, a)
    rs@(a
    minV,a
    maxV) = (Integer -> Rational) -> [Integer] -> [Rational]
    forall a b. (a -> b) -> [a] -> [b]
    map ((Rational
    sRational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    *) (Rational -> Rational)
    -> (Integer -> Rational) -> Integer -> Rational
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral) [Integer
    min' .. Integer
    max']
      where
        s :: Rational
    s    = a -> (a, a) -> Rational
    forall a. RealFloat a => a -> (a, a) -> Rational
    chooseStep a
    nSteps (a, a)
    rs
        min' :: Integer
        min' :: Integer
    min' = Rational -> Integer
    forall b. Integral b => Rational -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor   (Rational -> Integer) -> Rational -> Integer
    forall a b. (a -> b) -> a -> b
    $ a -> Rational
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac a
    minV Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    / Rational
    s
        max' :: Integer
    max' = Rational -> Integer
    forall b. Integral b => Rational -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    ceiling (Rational -> Integer) -> Rational -> Integer
    forall a b. (a -> b) -> a -> b
    $ a -> Rational
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac a
    maxV Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    / Rational
    s

    chooseStep :: RealFloat a => a -> (a,a) -> Rational
    chooseStep :: forall a. RealFloat a => a -> (a, a) -> Rational
    chooseStep a
    nsteps (a
    x1,a
    x2) = (Rational -> Rational -> Ordering) -> [Rational] -> Rational
    forall (t :: * -> *) a.
    Foldable t =>
    (a -> a -> Ordering) -> t a -> a
    minimumBy ((Rational -> a) -> Rational -> Rational -> Ordering
    forall a b. Ord a => (b -> a) -> b -> b -> Ordering
    comparing Rational -> a
    forall {a}. Real a => a -> a
    proximity) [Rational]
    stepVals
      where
        delta :: a
    delta = a
    x2 a -> a -> a
    forall a. Num a => a -> a -> a
    - a
    x1
        mult :: Rational
    mult  | a
    delta a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    0 = Rational
    1  -- Otherwise the case below will use all of memory
              | Bool
    otherwise  = Rational
    10 Rational -> Integer -> Rational
    forall a b. (Fractional a, Integral b) => a -> b -> a
    ^^ ((a -> Integer
    forall b. Integral b => a -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor (a -> Integer) -> a -> Integer
    forall a b. (a -> b) -> a -> b
    $ a -> a
    forall a. Floating a => a -> a
    log10 (a -> a) -> a -> a
    forall a b. (a -> b) -> a -> b
    $ a
    delta a -> a -> a
    forall a. Fractional a => a -> a -> a
    / a
    nsteps)::Integer)
        stepVals :: [Rational]
    stepVals = (Rational -> Rational) -> [Rational] -> [Rational]
    forall a b. (a -> b) -> [a] -> [b]
    map (Rational
    multRational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    *) [Rational
    0.1,Rational
    0.2,Rational
    0.25,Rational
    0.5,Rational
    1.0,Rational
    2.0,Rational
    2.5,Rational
    5.0,Rational
    10,Rational
    20,Rational
    25,Rational
    50]
        proximity :: a -> a
    proximity a
    x = a -> a
    forall a. Num a => a -> a
    abs (a -> a) -> a -> a
    forall a b. (a -> b) -> a -> b
    $ a
    delta a -> a -> a
    forall a. Fractional a => a -> a -> a
    / a -> a
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac a
    x a -> a -> a
    forall a. Num a => a -> a -> a
    - a
    nsteps

    -- | Given a target number of values, and a list of input points,
    --   find evenly spaced values from the set {1*X, 2*X, 2.5*X, 5*X} (where
    --   X is some power of ten) that evenly cover the input points.
    autoSteps :: Int -> [Double] -> [Double]
    autoSteps :: Int -> [Double] -> [Double]
    autoSteps Int
    nSteps [Double]
    vs = (Rational -> Double) -> [Rational] -> [Double]
    forall a b. (a -> b) -> [a] -> [b]
    map Rational -> Double
    forall a. Fractional a => Rational -> a
    fromRational ([Rational] -> [Double]) -> [Rational] -> [Double]
    forall a b. (a -> b) -> a -> b
    $ Double -> (Double, Double) -> [Rational]
    forall a. RealFloat a => a -> (a, a) -> [Rational]
    steps (Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    nSteps) (Double, Double)
    r
      where
        range :: [a] -> (Double, Double)
    range []  = (Double
    0,Double
    1)
        range [a]
    _   | Double
    minV Double -> Double -> Bool
    forall a. Eq a => a -> a -> Bool
    == Double
    maxV = (Double
    minVDouble -> Double -> Double
    forall a. Num a => a -> a -> a
    -Double
    0.5,Double
    minVDouble -> Double -> Double
    forall a. Num a => a -> a -> a
    +Double
    0.5)
                  | Bool
    otherwise    = (Double, Double)
    rs
        rs :: (Double, Double)
    rs@(Double
    minV,Double
    maxV) = ([Double] -> Double
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    minimum [Double]
    ps,[Double] -> Double
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum [Double]
    ps)
        ps :: [Double]
    ps        = (Double -> Bool) -> [Double] -> [Double]
    forall a. (a -> Bool) -> [a] -> [a]
    filter Double -> Bool
    forall a. RealFloat a => a -> Bool
    isValidNumber [Double]
    vs
        r :: (Double, Double)
    r         = [Double] -> (Double, Double)
    forall {a}. [a] -> (Double, Double)
    range [Double]
    ps

    ----------------------------------------------------------------------

    instance (Show a, RealFloat a) => Default (LogAxisParams a) where
      def :: LogAxisParams a
    def = LogAxisParams
        { _loga_labelf :: [a] -> [String]
    _loga_labelf = [a] -> [String]
    forall d. RealFloat d => [d] -> [String]
    showDs
        }

    -- | Generate a log axis automatically, scaled appropriately for the
    -- input data.
    autoScaledLogAxis :: RealFloat a => LogAxisParams a -> AxisFn a
    autoScaledLogAxis :: forall a. RealFloat a => LogAxisParams a -> AxisFn a
    autoScaledLogAxis LogAxisParams a
    lap [a]
    ps0 =
        (a -> Double)
    -> (Double -> a)
    -> ([a] -> [String])
    -> ([a], [a], [a])
    -> AxisData a
    forall x.
    Ord x =>
    (x -> Double)
    -> (Double -> x)
    -> ([x] -> [String])
    -> ([x], [x], [x])
    -> AxisData x
    makeAxis' (a -> Double
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac (a -> Double) -> (a -> a) -> a -> Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> a
    forall a. Floating a => a -> a
    log) (Double -> a
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac (Double -> a) -> (Double -> Double) -> Double -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Double
    forall a. Floating a => a -> a
    exp)
                  (LogAxisParams a -> [a] -> [String]
    forall a. LogAxisParams a -> [a] -> [String]
    _loga_labelf LogAxisParams a
    lap) ([Rational] -> [a]
    wrap [Rational]
    rlabelvs, [Rational] -> [a]
    wrap [Rational]
    rtickvs, [Rational] -> [a]
    wrap [Rational]
    rlabelvs)
            where
              ps :: [a]
    ps        = (a -> Bool) -> [a] -> [a]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (\a
    x -> a -> Bool
    forall a. RealFloat a => a -> Bool
    isValidNumber a
    x Bool -> Bool -> Bool
    && a
    0 a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    x) [a]
    ps0
              (a
    minV,a
    maxV) = ([a] -> a
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    minimum [a]
    ps,[a] -> a
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum [a]
    ps)
              wrap :: [Rational] -> [a]
    wrap      = (Rational -> a) -> [Rational] -> [a]
    forall a b. (a -> b) -> [a] -> [b]
    map Rational -> a
    forall a. Fractional a => Rational -> a
    fromRational
              range :: [a] -> (a, b)
    range []  = (a
    3,b
    30)
              range [a]
    _   | a
    minV a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    maxV = (a -> a
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac (a -> a) -> a -> a
    forall a b. (a -> b) -> a -> b
    $ a
    minVa -> a -> a
    forall a. Fractional a => a -> a -> a
    /a
    3, a -> b
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac (a -> b) -> a -> b
    forall a b. (a -> b) -> a -> b
    $ a
    maxVa -> a -> a
    forall a. Num a => a -> a -> a
    *a
    3)
                        | Bool
    otherwise    = (a -> a
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac (a -> a) -> a -> a
    forall a b. (a -> b) -> a -> b
    $ a
    minV,   a -> b
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac (a -> b) -> a -> b
    forall a b. (a -> b) -> a -> b
    $ a
    maxV)
              ([Rational]
    rlabelvs, [Rational]
    rtickvs) = (Double, Double) -> ([Rational], [Rational])
    logTicks ([a] -> (Double, Double)
    forall {a} {b} {a}. (Fractional a, Fractional b) => [a] -> (a, b)
    range [a]
    ps)

    data LogAxisParams a = LogAxisParams {
        -- | The function used to show the axes labels.
        forall a. LogAxisParams a -> [a] -> [String]
    _loga_labelf :: [a] -> [String]
    }

    {-
     Rules: Do not subdivide between powers of 10 until all powers of 10
              get major ticks.
            Do not subdivide between powers of ten as [1,2,4,6,8,10] when
              5 gets a major tick
              (i.e. the major ticks need to be a subset of the minor ticks)
    -}
    logTicks :: Range -> ([Rational],[Rational])
    logTicks :: (Double, Double) -> ([Rational], [Rational])
    logTicks (Double
    low,Double
    high) = ([Rational] -> [Rational]
    forall a. Eq a => [a] -> [a]
    nub [Rational]
    major,[Rational] -> [Rational]
    forall a. Eq a => [a] -> [a]
    nub [Rational]
    minor)
     where
      pf :: RealFrac a => a -> (Integer, a)
      pf :: forall a. RealFrac a => a -> (Integer, a)
    pf = a -> (Integer, a)
    forall b. Integral b => a -> (b, a)
    forall a b. (RealFrac a, Integral b) => a -> (b, a)
    properFraction

      -- frac :: (RealFrac a, Integral b) => a -> (b, a)
      frac :: (RealFrac a) => a -> (Integer, a)
      frac :: forall a. RealFrac a => a -> (Integer, a)
    frac a
    x | a
    0 a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    <= a
    b    = (Integer
    a,a
    b)
             | Bool
    otherwise = (Integer
    aInteger -> Integer -> Integer
    forall a. Num a => a -> a -> a
    -Integer
    1,a
    ba -> a -> a
    forall a. Num a => a -> a -> a
    +a
    1)
        where
          (Integer
    a,a
    b) = a -> (Integer, a)
    forall b. Integral b => a -> (b, a)
    forall a b. (RealFrac a, Integral b) => a -> (b, a)
    properFraction a
    x

      ratio :: Double
    ratio      = Double
    highDouble -> Double -> Double
    forall a. Fractional a => a -> a -> a
    /Double
    low
      lower :: a -> [Rational] -> Rational
    lower a
    a [Rational]
    l  = let (Integer
    i,a
    r) = a -> (Integer, a)
    forall a. RealFrac a => a -> (Integer, a)
    frac (a -> a
    forall a. Floating a => a -> a
    log10 a
    a) in
                   [Rational] -> Rational
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum (Rational
    1Rational -> [Rational] -> [Rational]
    forall a. a -> [a] -> [a]
    :(Rational -> Bool) -> [Rational] -> [Rational]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (\Rational
    x -> a -> a
    forall a. Floating a => a -> a
    log10 (Rational -> a
    forall a. Fractional a => Rational -> a
    fromRational Rational
    x) a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    <= a
    r) [Rational]
    l)Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    *Rational
    10Rational -> Integer -> Rational
    forall a b. (Fractional a, Integral b) => a -> b -> a
    ^^Integer
    i
      upper :: a -> [Rational] -> Rational
    upper a
    a [Rational]
    l  = let (Integer
    i,a
    r) = a -> (Integer, a)
    forall a. RealFrac a => a -> (Integer, a)
    pf (a -> a
    forall a. Floating a => a -> a
    log10 a
    a) in
                   [Rational] -> Rational
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    minimum (Rational
    10Rational -> [Rational] -> [Rational]
    forall a. a -> [a] -> [a]
    :(Rational -> Bool) -> [Rational] -> [Rational]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (\Rational
    x -> a
    r a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    <= a -> a
    forall a. Floating a => a -> a
    log10 (Rational -> a
    forall a. Fractional a => Rational -> a
    fromRational Rational
    x)) [Rational]
    l)Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    *Rational
    10Rational -> Integer -> Rational
    forall a b. (Fractional a, Integral b) => a -> b -> a
    ^^Integer
    i

      powers           :: (Double,Double) -> [Rational] -> [Rational]
      powers :: (Double, Double) -> [Rational] -> [Rational]
    powers (Double
    x,Double
    y) [Rational]
    l    = [ Rational
    aRational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    *Rational
    10Rational -> Integer -> Rational
    forall a b. (Fractional a, Integral b) => a -> b -> a
    ^^Integer
    p | Integer
    p <- [(Double -> Integer
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor (Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    x))..(Double -> Integer
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    ceiling (Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    y))] :: [Integer]
                                    , Rational
    a <- [Rational]
    l ]
      midselection :: (Double, Double) -> [Rational] -> [Rational]
    midselection (Double, Double)
    r [Rational]
    l  = (Rational -> Bool) -> [Rational] -> [Rational]
    forall a. (a -> Bool) -> [a] -> [a]
    filter ((Double, Double) -> [Rational] -> Rational -> Bool
    forall {a} {a}.
    (RealFrac a, RealFrac a, Floating a, Floating a) =>
    (a, a) -> [Rational] -> Rational -> Bool
    inRange (Double, Double)
    r [Rational]
    l) ((Double, Double) -> [Rational] -> [Rational]
    powers (Double, Double)
    r [Rational]
    l)
      inRange :: (a, a) -> [Rational] -> Rational -> Bool
    inRange (a
    a,a
    b) [Rational]
    l Rational
    x = (a -> [Rational] -> Rational
    forall {a}. (RealFrac a, Floating a) => a -> [Rational] -> Rational
    lower a
    a [Rational]
    l Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Rational
    x) Bool -> Bool -> Bool
    && (Rational
    x Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    <= a -> [Rational] -> Rational
    forall {a}. (RealFrac a, Floating a) => a -> [Rational] -> Rational
    upper a
    b [Rational]
    l)

      logRange :: (Double, Double)
    logRange = (Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    low, Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    high)

      roundPow :: a -> a
    roundPow a
    x = a
    10a -> Integer -> a
    forall a b. (Fractional a, Integral b) => a -> b -> a
    ^^(a -> Integer
    forall b. Integral b => a -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round a
    x :: Integer)

      major :: [Rational]
    major | Double
    17.5 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    ratio = (Rational -> Rational) -> [Rational] -> [Rational]
    forall a b. (a -> b) -> [a] -> [b]
    map Rational -> Rational
    forall {a} {a}. (RealFrac a, Fractional a) => a -> a
    roundPow ([Rational] -> [Rational]) -> [Rational] -> [Rational]
    forall a b. (a -> b) -> a -> b
    $
                                   Double -> (Double, Double) -> [Rational]
    forall a. RealFloat a => a -> (a, a) -> [Rational]
    steps (Double -> Double -> Double
    forall a. Ord a => a -> a -> a
    min Double
    5 (Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    ratio)) (Double, Double)
    logRange
            | Double
    12 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    ratio   = (Rational -> Rational) -> [Rational] -> [Rational]
    forall a b. (a -> b) -> [a] -> [b]
    map Rational -> Rational
    forall {a} {a}. (RealFrac a, Fractional a) => a -> a
    roundPow ([Rational] -> [Rational]) -> [Rational] -> [Rational]
    forall a b. (a -> b) -> a -> b
    $
                                   Double -> (Double, Double) -> [Rational]
    forall a. RealFloat a => a -> (a, a) -> [Rational]
    steps (Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    ratio Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    5) (Double, Double)
    logRange
            | Double
    6 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    ratio    = (Rational -> Rational) -> [Rational] -> [Rational]
    forall a b. (a -> b) -> [a] -> [b]
    map Rational -> Rational
    forall {a} {a}. (RealFrac a, Fractional a) => a -> a
    roundPow ([Rational] -> [Rational]) -> [Rational] -> [Rational]
    forall a b. (a -> b) -> a -> b
    $
                                   Double -> (Double, Double) -> [Rational]
    forall a. RealFloat a => a -> (a, a) -> [Rational]
    steps (Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    ratio Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    2) (Double, Double)
    logRange
            | Double
    3 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    ratio    = (Double, Double) -> [Rational] -> [Rational]
    midselection (Double
    low,Double
    high) [Rational
    1,Rational
    10]
            | Double
    20 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double
    ratio         = (Double, Double) -> [Rational] -> [Rational]
    midselection (Double
    low,Double
    high) [Rational
    1,Rational
    5,Rational
    10]
            | Double
    6 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double
    ratio          = (Double, Double) -> [Rational] -> [Rational]
    midselection (Double
    low,Double
    high) [Rational
    1,Rational
    2,Rational
    4,Rational
    6,Rational
    8,Rational
    10]
            | Double
    3 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double
    ratio          = (Double, Double) -> [Rational] -> [Rational]
    midselection (Double
    low,Double
    high) [Rational
    1..Rational
    10]
            | Bool
    otherwise          = Double -> (Double, Double) -> [Rational]
    forall a. RealFloat a => a -> (a, a) -> [Rational]
    steps Double
    5 (Double
    low,Double
    high)

      (Rational
    l',Rational
    h')   = ([Rational] -> Rational
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    minimum [Rational]
    major, [Rational] -> Rational
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum [Rational]
    major)
      (Double
    dl',Double
    dh') = (Rational -> Double
    forall a. Fractional a => Rational -> a
    fromRational Rational
    l', Rational -> Double
    forall a. Fractional a => Rational -> a
    fromRational Rational
    h')
      ratio' :: Double
      ratio' :: Double
    ratio' = Rational -> Double
    forall a. Fractional a => Rational -> a
    fromRational (Rational
    h'Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    /Rational
    l')
      filterX :: [Rational] -> [Rational]
    filterX = (Rational -> Bool) -> [Rational] -> [Rational]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (\Rational
    x -> Rational
    l'Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    <=Rational
    x Bool -> Bool -> Bool
    && Rational
    x Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    <=Rational
    h') ([Rational] -> [Rational])
    -> ([Rational] -> [Rational]) -> [Rational] -> [Rational]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Double, Double) -> [Rational] -> [Rational]
    powers (Double
    dl',Double
    dh')

      minor :: [Rational]
    minor | Double
    50 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    ratio' = (Rational -> Rational) -> [Rational] -> [Rational]
    forall a b. (a -> b) -> [a] -> [b]
    map Rational -> Rational
    forall {a} {a}. (RealFrac a, Fractional a) => a -> a
    roundPow ([Rational] -> [Rational]) -> [Rational] -> [Rational]
    forall a b. (a -> b) -> a -> b
    $
                                  Double -> (Double, Double) -> [Rational]
    forall a. RealFloat a => a -> (a, a) -> [Rational]
    steps Double
    50 (Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    dl', Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    dh')
            | Double
    6 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    ratio'  = [Rational] -> [Rational]
    filterX [Rational
    1,Rational
    10]
            | Double
    4 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double -> Double
    forall a. Floating a => a -> a
    log10 Double
    ratio'  = [Rational] -> [Rational]
    filterX [Rational
    1,Rational
    5,Rational
    10]
            | Double
    6 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double
    ratio'        = [Rational] -> [Rational]
    filterX [Rational
    1..Rational
    10]
            | Double
    3 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double
    ratio'        = [Rational] -> [Rational]
    filterX [Rational
    1,Rational
    1.2..Rational
    10]
            | Bool
    otherwise         = Double -> (Double, Double) -> [Rational]
    forall a. RealFloat a => a -> (a, a) -> [Rational]
    steps Double
    50 (Double
    dl', Double
    dh')

    $( makeLenses ''LinearAxisParams )
    $( makeLenses ''LogAxisParams )