{-# LANGUAGE DeriveDataTypeable    #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes            #-}
{-# LANGUAGE TemplateHaskell       #-}
{-# LANGUAGE TypeFamilies          #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Plots.Axis.Ticks
-- Copyright   :  (C) 2015 Christopher Chalmers
-- License     :  BSD-style (see the file LICENSE)
-- Maintainer  :  Christopher Chalmers
-- Stability   :  experimental
-- Portability :  non-portable
--
-- Ticks for being placed on an axis or a 'ColourBar'.
--
----------------------------------------------------------------------------
module Plots.Axis.Ticks
  ( -- * Major ticks
    MajorTicks
  , HasMajorTicks (..)
  , majorTicksHelper
  , logMajorTicks

    -- * Minor ticks
  , MinorTicks
  , HasMinorTicks (..)
  , minorTicksHelper

    -- * Both major and minor ticks
  , Ticks
  , HasTicks (..)
  , ticksAlign
  , ticksStyle
  , ticksVisible

    -- * Tick alignment
  , TicksAlignment (..)
  , autoTicks
  , centreTicks
  , centerTicks
  , insideTicks
  , outsideTicks

    -- * Helper functions
  , hideTicks
  , majorTickPositions
  , minorTickPositions
  , linearMajorTicks
  ) where

import           Control.Lens     hiding (transform, ( # ))
import           Data.Data
import           Data.Default
import           Data.Foldable    as F
import           Data.Ord
import           Plots.Types
import           Plots.Util

import           Diagrams.Prelude

------------------------------------------------------------------------
-- Types
------------------------------------------------------------------------

-- Tick alignment ------------------------------------------------------

-- | Set the portion of the tick above and below the axis.
data TicksAlignment
  = TickSpec !Rational !Rational
  | AutoTick -- center tick for middle axis, outside tick otherwise
  deriving (Int -> TicksAlignment -> ShowS
[TicksAlignment] -> ShowS
TicksAlignment -> String
(Int -> TicksAlignment -> ShowS)
-> (TicksAlignment -> String)
-> ([TicksAlignment] -> ShowS)
-> Show TicksAlignment
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TicksAlignment -> ShowS
showsPrec :: Int -> TicksAlignment -> ShowS
$cshow :: TicksAlignment -> String
show :: TicksAlignment -> String
$cshowList :: [TicksAlignment] -> ShowS
showList :: [TicksAlignment] -> ShowS
Show, TicksAlignment -> TicksAlignment -> Bool
(TicksAlignment -> TicksAlignment -> Bool)
-> (TicksAlignment -> TicksAlignment -> Bool) -> Eq TicksAlignment
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TicksAlignment -> TicksAlignment -> Bool
== :: TicksAlignment -> TicksAlignment -> Bool
$c/= :: TicksAlignment -> TicksAlignment -> Bool
/= :: TicksAlignment -> TicksAlignment -> Bool
Eq)

-- | Set the tick type depending on the axis line position. 'centreTick'
--   for 'middleAxis', 'insideTick' for everything else.
autoTicks :: TicksAlignment
autoTicks :: TicksAlignment
autoTicks = TicksAlignment
AutoTick

-- | Set the tick to be in the centre of the axis with total length of
--   the corresponding tick length.
centreTicks :: TicksAlignment
centreTicks :: TicksAlignment
centreTicks  = Rational -> Rational -> TicksAlignment
TickSpec Rational
0.5 Rational
0.5

-- | Synonym for 'centreTicks'.
centerTicks :: TicksAlignment
centerTicks :: TicksAlignment
centerTicks  = TicksAlignment
centreTicks

-- | Align the ticks to be inside a box axis.
insideTicks :: TicksAlignment
insideTicks :: TicksAlignment
insideTicks  = Rational -> Rational -> TicksAlignment
TickSpec Rational
0 Rational
1

-- | Align the ticks to be outside a box axis.
outsideTicks :: TicksAlignment
outsideTicks :: TicksAlignment
outsideTicks = Rational -> Rational -> TicksAlignment
TickSpec Rational
1 Rational
0

-- -- | Do not show any ticks.
-- noTicks :: TicksAlignment
-- noTicks = NoTick

------------------------------------------------------------------------
-- Minor ticks
------------------------------------------------------------------------

-- | The big ticks on the axis line.
data MajorTicks v n = MajorTicks
  { forall (v :: * -> *) n. MajorTicks v n -> (n, n) -> [n]
matFunction :: (n,n) -> [n]
  , forall (v :: * -> *) n. MajorTicks v n -> TicksAlignment
matAlign    :: TicksAlignment
  , forall (v :: * -> *) n. MajorTicks v n -> n
matLength   :: n
  , forall (v :: * -> *) n. MajorTicks v n -> Style v n
matStyle    :: Style v n
  , forall (v :: * -> *) n. MajorTicks v n -> Bool
matVisible  :: Bool
  }

instance TypeableFloat n => Default (MajorTicks v n) where
  def :: MajorTicks v n
def = MajorTicks
    { matFunction :: (n, n) -> [n]
matFunction = n -> (n, n) -> [n]
forall n. (RealFrac n, Floating n) => n -> (n, n) -> [n]
linearMajorTicks n
5
    , matAlign :: TicksAlignment
matAlign    = TicksAlignment
autoTicks
    , matLength :: n
matLength   = n
5
    , matStyle :: Style v n
matStyle    = Style v n
forall a. Monoid a => a
mempty Style v n -> (Style v n -> Style v n) -> Style v n
forall a b. a -> (a -> b) -> b
# n -> Style v n -> Style v n
forall a n. (N a ~ n, HasStyle a, Typeable n) => n -> a -> a
lwO n
0.4
    , matVisible :: Bool
matVisible  = Bool
True
    }

type instance V (MajorTicks v n) = v
type instance N (MajorTicks v n) = n

-- | Class of things that have a 'MajorTicks'.
class HasMajorTicks f a where
  -- | Lens onto the 'MajorTicks' of something.
  majorTicks :: LensLike' f a (MajorTicks (V a) (N a))

  -- | The function used to place ticks for this axis, given the bounds
  --   of the axis. The result of these major ticks are also used as
  --   guides for 'MinorTicks', 'MajorGridLines' and 'MinorGridLines'.
  --
  --   Default is @'linearMinorTicks' 5@.
  majorTicksFunction :: Functor f => LensLike' f a ((N a, N a) -> [N a])
  majorTicksFunction = LensLike' f a (MajorTicks (V a) (N a))
forall (f :: * -> *) a.
HasMajorTicks f a =>
LensLike' f a (MajorTicks (V a) (N a))
majorTicks LensLike' f a (MajorTicks (V a) (N a))
-> ((((N a, N a) -> [N a]) -> f ((N a, N a) -> [N a]))
    -> MajorTicks (V a) (N a) -> f (MajorTicks (V a) (N a)))
-> LensLike' f a ((N a, N a) -> [N a])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MajorTicks (V a) (N a) -> (N a, N a) -> [N a])
-> (MajorTicks (V a) (N a)
    -> ((N a, N a) -> [N a]) -> MajorTicks (V a) (N a))
-> Lens
     (MajorTicks (V a) (N a))
     (MajorTicks (V a) (N a))
     ((N a, N a) -> [N a])
     ((N a, N a) -> [N a])
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens MajorTicks (V a) (N a) -> (N a, N a) -> [N a]
forall (v :: * -> *) n. MajorTicks v n -> (n, n) -> [n]
matFunction (\MajorTicks (V a) (N a)
mat (N a, N a) -> [N a]
a -> MajorTicks (V a) (N a)
mat {matFunction = a})

  -- | Alignment of the major ticks. Choose between 'autoTicks'
  --   (default), 'centreTicks', 'insideTicks' or 'outsideTicks'.
  majorTicksAlignment :: Functor f => LensLike' f a TicksAlignment
  majorTicksAlignment = LensLike' f a (MajorTicks (V a) (N a))
forall (f :: * -> *) a.
HasMajorTicks f a =>
LensLike' f a (MajorTicks (V a) (N a))
majorTicks LensLike' f a (MajorTicks (V a) (N a))
-> ((TicksAlignment -> f TicksAlignment)
    -> MajorTicks (V a) (N a) -> f (MajorTicks (V a) (N a)))
-> LensLike' f a TicksAlignment
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MajorTicks (V a) (N a) -> TicksAlignment)
-> (MajorTicks (V a) (N a)
    -> TicksAlignment -> MajorTicks (V a) (N a))
-> Lens
     (MajorTicks (V a) (N a))
     (MajorTicks (V a) (N a))
     TicksAlignment
     TicksAlignment
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens MajorTicks (V a) (N a) -> TicksAlignment
forall (v :: * -> *) n. MajorTicks v n -> TicksAlignment
matAlign (\MajorTicks (V a) (N a)
mat TicksAlignment
a -> MajorTicks (V a) (N a)
mat {matAlign = a})

  -- | The total length the major ticks.
  --
  --   Default is @7@.
  majorTicksLength :: Functor f => LensLike' f a (N a)
  majorTicksLength = LensLike' f a (MajorTicks (V a) (N a))
forall (f :: * -> *) a.
HasMajorTicks f a =>
LensLike' f a (MajorTicks (V a) (N a))
majorTicks LensLike' f a (MajorTicks (V a) (N a))
-> ((N a -> f (N a))
    -> MajorTicks (V a) (N a) -> f (MajorTicks (V a) (N a)))
-> LensLike' f a (N a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MajorTicks (V a) (N a) -> N a)
-> (MajorTicks (V a) (N a) -> N a -> MajorTicks (V a) (N a))
-> Lens
     (MajorTicks (V a) (N a)) (MajorTicks (V a) (N a)) (N a) (N a)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens MajorTicks (V a) (N a) -> N a
forall (v :: * -> *) n. MajorTicks v n -> n
matLength (\MajorTicks (V a) (N a)
mat N a
a -> MajorTicks (V a) (N a)
mat {matLength = a})

  -- | The style used to render the major ticks.
  --
  --   Default is @'lwO' 0.6 'mempty'@ (subject to change).
  majorTicksStyle :: Functor f => LensLike' f a (Style (V a) (N a))
  majorTicksStyle = LensLike' f a (MajorTicks (V a) (N a))
forall (f :: * -> *) a.
HasMajorTicks f a =>
LensLike' f a (MajorTicks (V a) (N a))
majorTicks LensLike' f a (MajorTicks (V a) (N a))
-> ((Style (V a) (N a) -> f (Style (V a) (N a)))
    -> MajorTicks (V a) (N a) -> f (MajorTicks (V a) (N a)))
-> LensLike' f a (Style (V a) (N a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MajorTicks (V a) (N a) -> Style (V a) (N a))
-> (MajorTicks (V a) (N a)
    -> Style (V a) (N a) -> MajorTicks (V a) (N a))
-> Lens
     (MajorTicks (V a) (N a))
     (MajorTicks (V a) (N a))
     (Style (V a) (N a))
     (Style (V a) (N a))
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens MajorTicks (V a) (N a) -> Style (V a) (N a)
forall (v :: * -> *) n. MajorTicks v n -> Style v n
matStyle (\MajorTicks (V a) (N a)
mat Style (V a) (N a)
sty -> MajorTicks (V a) (N a)
mat {matStyle = sty})

instance HasMajorTicks f (MajorTicks v n) where
  majorTicks :: LensLike'
  f
  (MajorTicks v n)
  (MajorTicks (V (MajorTicks v n)) (N (MajorTicks v n)))
majorTicks = (MajorTicks v n -> f (MajorTicks v n))
-> MajorTicks v n -> f (MajorTicks v n)
LensLike'
  f
  (MajorTicks v n)
  (MajorTicks (V (MajorTicks v n)) (N (MajorTicks v n)))
forall a. a -> a
id

instance HasVisibility (MajorTicks v n) where
  visible :: Lens' (MajorTicks v n) Bool
visible = (MajorTicks v n -> Bool)
-> (MajorTicks v n -> Bool -> MajorTicks v n)
-> Lens' (MajorTicks v n) Bool
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens MajorTicks v n -> Bool
forall (v :: * -> *) n. MajorTicks v n -> Bool
matVisible (\MajorTicks v n
mat Bool
b -> MajorTicks v n
mat {matVisible = b})

------------------------------------------------------------------------
-- Minor ticks
------------------------------------------------------------------------

-- | The small ticks on the axis line.
data MinorTicks v n = MinorTicks
  { forall (v :: * -> *) n. MinorTicks v n -> [n] -> (n, n) -> [n]
mitFunction :: [n] -> (n,n) -> [n]
  , forall (v :: * -> *) n. MinorTicks v n -> TicksAlignment
mitAlign    :: TicksAlignment
  , forall (v :: * -> *) n. MinorTicks v n -> n
mitLength   :: n
  , forall (v :: * -> *) n. MinorTicks v n -> Style v n
mitStyle    :: Style v n
  , forall (v :: * -> *) n. MinorTicks v n -> Bool
mitVisible  :: Bool
  }

type instance V (MinorTicks v n) = v
type instance N (MinorTicks v n) = n

instance TypeableFloat n => Default (MinorTicks v n) where
  def :: MinorTicks v n
def = MinorTicks
    { mitFunction :: [n] -> (n, n) -> [n]
mitFunction = Int -> [n] -> (n, n) -> [n]
forall n. Fractional n => Int -> [n] -> (n, n) -> [n]
minorTicksHelper Int
4
    , mitAlign :: TicksAlignment
mitAlign    = TicksAlignment
autoTicks
    , mitLength :: n
mitLength   = n
3
    , mitStyle :: Style v n
mitStyle    = Style v n
forall a. Monoid a => a
mempty Style v n -> (Style v n -> Style v n) -> Style v n
forall a b. a -> (a -> b) -> b
# n -> Style v n -> Style v n
forall a n. (N a ~ n, HasStyle a, Typeable n) => n -> a -> a
lwO n
0.4
    , mitVisible :: Bool
mitVisible  = Bool
True
    }

-- | Class of things that have a single 'MinorTicks'.
class HasMinorTicks f a where
  -- | Lens onto the 'MinorTicks' of something.
  minorTicks :: LensLike' f a (MinorTicks (V a) (N a))

  -- | The function used to place ticks for this axis, given the result
  --   of 'majorTicksFunction' and the bounds of the axis.
  --
  --   Default is @'linearMinorTicks' 3@.
  minorTicksFunction :: Functor f => LensLike' f a ([N a] -> (N a, N a) -> [N a])
  minorTicksFunction = LensLike' f a (MinorTicks (V a) (N a))
forall (f :: * -> *) a.
HasMinorTicks f a =>
LensLike' f a (MinorTicks (V a) (N a))
minorTicks LensLike' f a (MinorTicks (V a) (N a))
-> ((([N a] -> (N a, N a) -> [N a])
     -> f ([N a] -> (N a, N a) -> [N a]))
    -> MinorTicks (V a) (N a) -> f (MinorTicks (V a) (N a)))
-> LensLike' f a ([N a] -> (N a, N a) -> [N a])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MinorTicks (V a) (N a) -> [N a] -> (N a, N a) -> [N a])
-> (MinorTicks (V a) (N a)
    -> ([N a] -> (N a, N a) -> [N a]) -> MinorTicks (V a) (N a))
-> Lens
     (MinorTicks (V a) (N a))
     (MinorTicks (V a) (N a))
     ([N a] -> (N a, N a) -> [N a])
     ([N a] -> (N a, N a) -> [N a])
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens MinorTicks (V a) (N a) -> [N a] -> (N a, N a) -> [N a]
forall (v :: * -> *) n. MinorTicks v n -> [n] -> (n, n) -> [n]
mitFunction (\MinorTicks (V a) (N a)
mit [N a] -> (N a, N a) -> [N a]
a -> MinorTicks (V a) (N a)
mit {mitFunction = a})

  -- | Alignment of the minor ticks. Choose between 'autoTicks'
  --   (default), 'centreTicks', 'insideTicks' or 'outsideTicks'.
  minorTicksAlignment :: Functor f => LensLike' f a TicksAlignment
  minorTicksAlignment = LensLike' f a (MinorTicks (V a) (N a))
forall (f :: * -> *) a.
HasMinorTicks f a =>
LensLike' f a (MinorTicks (V a) (N a))
minorTicks LensLike' f a (MinorTicks (V a) (N a))
-> ((TicksAlignment -> f TicksAlignment)
    -> MinorTicks (V a) (N a) -> f (MinorTicks (V a) (N a)))
-> LensLike' f a TicksAlignment
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MinorTicks (V a) (N a) -> TicksAlignment)
-> (MinorTicks (V a) (N a)
    -> TicksAlignment -> MinorTicks (V a) (N a))
-> Lens
     (MinorTicks (V a) (N a))
     (MinorTicks (V a) (N a))
     TicksAlignment
     TicksAlignment
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens MinorTicks (V a) (N a) -> TicksAlignment
forall (v :: * -> *) n. MinorTicks v n -> TicksAlignment
mitAlign (\MinorTicks (V a) (N a)
mit TicksAlignment
a -> MinorTicks (V a) (N a)
mit {mitAlign = a})

  -- | The total length the minor ticks.
  --
  --   Default is @3@.
  minorTicksLength :: Functor f => LensLike' f a (N a)
  minorTicksLength = LensLike' f a (MinorTicks (V a) (N a))
forall (f :: * -> *) a.
HasMinorTicks f a =>
LensLike' f a (MinorTicks (V a) (N a))
minorTicks LensLike' f a (MinorTicks (V a) (N a))
-> ((N a -> f (N a))
    -> MinorTicks (V a) (N a) -> f (MinorTicks (V a) (N a)))
-> LensLike' f a (N a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MinorTicks (V a) (N a) -> N a)
-> (MinorTicks (V a) (N a) -> N a -> MinorTicks (V a) (N a))
-> Lens
     (MinorTicks (V a) (N a)) (MinorTicks (V a) (N a)) (N a) (N a)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens MinorTicks (V a) (N a) -> N a
forall (v :: * -> *) n. MinorTicks v n -> n
mitLength (\MinorTicks (V a) (N a)
mit N a
a -> MinorTicks (V a) (N a)
mit {mitLength = a})

  -- | The style used to render the minor ticks.
  --
  --   Default is @'lwO' 0.4 'mempty'@ (subject to change).
  minorTicksStyle :: Functor f => LensLike' f a (Style (V a) (N a))
  minorTicksStyle = LensLike' f a (MinorTicks (V a) (N a))
forall (f :: * -> *) a.
HasMinorTicks f a =>
LensLike' f a (MinorTicks (V a) (N a))
minorTicks LensLike' f a (MinorTicks (V a) (N a))
-> ((Style (V a) (N a) -> f (Style (V a) (N a)))
    -> MinorTicks (V a) (N a) -> f (MinorTicks (V a) (N a)))
-> LensLike' f a (Style (V a) (N a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MinorTicks (V a) (N a) -> Style (V a) (N a))
-> (MinorTicks (V a) (N a)
    -> Style (V a) (N a) -> MinorTicks (V a) (N a))
-> Lens
     (MinorTicks (V a) (N a))
     (MinorTicks (V a) (N a))
     (Style (V a) (N a))
     (Style (V a) (N a))
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens MinorTicks (V a) (N a) -> Style (V a) (N a)
forall (v :: * -> *) n. MinorTicks v n -> Style v n
mitStyle (\MinorTicks (V a) (N a)
mit Style (V a) (N a)
sty -> MinorTicks (V a) (N a)
mit {mitStyle = sty})

instance HasMinorTicks f (MinorTicks v n) where
  minorTicks :: LensLike'
  f
  (MinorTicks v n)
  (MinorTicks (V (MinorTicks v n)) (N (MinorTicks v n)))
minorTicks = (MinorTicks v n -> f (MinorTicks v n))
-> MinorTicks v n -> f (MinorTicks v n)
LensLike'
  f
  (MinorTicks v n)
  (MinorTicks (V (MinorTicks v n)) (N (MinorTicks v n)))
forall a. a -> a
id

instance HasVisibility (MinorTicks v n) where
  visible :: Lens' (MinorTicks v n) Bool
visible = (MinorTicks v n -> Bool)
-> (MinorTicks v n -> Bool -> MinorTicks v n)
-> Lens' (MinorTicks v n) Bool
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens MinorTicks v n -> Bool
forall (v :: * -> *) n. MinorTicks v n -> Bool
mitVisible (\MinorTicks v n
mit Bool
sty -> MinorTicks v n
mit {mitVisible = sty})

------------------------------------------------------------------------
-- Both ticks
------------------------------------------------------------------------

-- | Both 'MajorTicks' and 'MinorTicks' together.
data Ticks v n = Ticks (MajorTicks v n) (MinorTicks v n)
-- Ticks are originally split up into major and minor so we can reuse
-- major for the colour bar. I'm still undecided whether it's worth all
-- the extra boilerplate here.

type instance V (Ticks v n) = v
type instance N (Ticks v n) = n

-- | Class of things with both 'MajorTicks' and 'MinorTicks'.
class (HasMinorTicks f a, HasMajorTicks f a) => HasTicks f a where
  bothTicks :: LensLike' f a (Ticks (V a) (N a))

instance Functor f => HasTicks f (Ticks v n) where
  bothTicks :: LensLike' f (Ticks v n) (Ticks (V (Ticks v n)) (N (Ticks v n)))
bothTicks = (Ticks v n -> f (Ticks v n)) -> Ticks v n -> f (Ticks v n)
LensLike' f (Ticks v n) (Ticks (V (Ticks v n)) (N (Ticks v n)))
forall a. a -> a
id

instance Functor f => HasMajorTicks f (Ticks v n) where
  majorTicks :: LensLike'
  f (Ticks v n) (MajorTicks (V (Ticks v n)) (N (Ticks v n)))
majorTicks MajorTicks (V (Ticks v n)) (N (Ticks v n))
-> f (MajorTicks (V (Ticks v n)) (N (Ticks v n)))
f (Ticks MajorTicks v n
ma MinorTicks v n
mi) = MajorTicks (V (Ticks v n)) (N (Ticks v n))
-> f (MajorTicks (V (Ticks v n)) (N (Ticks v n)))
f MajorTicks v n
MajorTicks (V (Ticks v n)) (N (Ticks v n))
ma f (MajorTicks v n)
-> (MajorTicks v n -> Ticks v n) -> f (Ticks v n)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \MajorTicks v n
ma' -> MajorTicks v n -> MinorTicks v n -> Ticks v n
forall (v :: * -> *) n.
MajorTicks v n -> MinorTicks v n -> Ticks v n
Ticks MajorTicks v n
ma' MinorTicks v n
mi

instance Functor f => HasMinorTicks f (Ticks v n) where
  minorTicks :: LensLike'
  f (Ticks v n) (MinorTicks (V (Ticks v n)) (N (Ticks v n)))
minorTicks MinorTicks (V (Ticks v n)) (N (Ticks v n))
-> f (MinorTicks (V (Ticks v n)) (N (Ticks v n)))
f (Ticks MajorTicks v n
ma MinorTicks v n
mi) = MinorTicks (V (Ticks v n)) (N (Ticks v n))
-> f (MinorTicks (V (Ticks v n)) (N (Ticks v n)))
f MinorTicks v n
MinorTicks (V (Ticks v n)) (N (Ticks v n))
mi f (MinorTicks v n)
-> (MinorTicks v n -> Ticks v n) -> f (Ticks v n)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \MinorTicks v n
mi' -> MajorTicks v n -> MinorTicks v n -> Ticks v n
forall (v :: * -> *) n.
MajorTicks v n -> MinorTicks v n -> Ticks v n
Ticks MajorTicks v n
ma MinorTicks v n
mi'

instance TypeableFloat n => Default (Ticks v n) where
  def :: Ticks v n
def = MajorTicks v n -> MinorTicks v n -> Ticks v n
forall (v :: * -> *) n.
MajorTicks v n -> MinorTicks v n -> Ticks v n
Ticks MajorTicks v n
forall a. Default a => a
def MinorTicks v n
forall a. Default a => a
def

instance Typeable n => HasStyle (Ticks v n) where
  applyStyle :: Style (V (Ticks v n)) (N (Ticks v n)) -> Ticks v n -> Ticks v n
applyStyle Style (V (Ticks v n)) (N (Ticks v n))
s = ASetter (Ticks v n) (Ticks v n) (Style v n) (Style v n)
-> (Style v n -> Style v n) -> Ticks v n -> Ticks v n
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter (Ticks v n) (Ticks v n) (Style v n) (Style v n)
LensLike'
  Identity (Ticks v n) (Style (V (Ticks v n)) (N (Ticks v n)))
forall (f :: * -> *) a.
(HasTicks f a, Applicative f) =>
LensLike' f a (Style (V a) (N a))
ticksStyle (Style (V (Style v n)) (N (Style v n)) -> Style v n -> Style v n
forall a. HasStyle a => Style (V a) (N a) -> a -> a
applyStyle Style (V (Style v n)) (N (Style v n))
Style (V (Ticks v n)) (N (Ticks v n))
s)

-- | Traversal over both major and minor tick alignment.
ticksAlign :: (HasTicks f a, Applicative f) => LensLike' f a TicksAlignment
ticksAlign :: forall (f :: * -> *) a.
(HasTicks f a, Applicative f) =>
LensLike' f a TicksAlignment
ticksAlign = LensLike' f a (Ticks (V a) (N a))
forall (f :: * -> *) a.
HasTicks f a =>
LensLike' f a (Ticks (V a) (N a))
bothTicks LensLike' f a (Ticks (V a) (N a))
-> ((TicksAlignment -> f TicksAlignment)
    -> Ticks (V a) (N a) -> f (Ticks (V a) (N a)))
-> (TicksAlignment -> f TicksAlignment)
-> a
-> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TicksAlignment -> f TicksAlignment)
-> Ticks (V a) (N a) -> f (Ticks (V a) (N a))
forall {f :: * -> *} {s}.
(Applicative f, HasMajorTicks (Const TicksAlignment) s,
 HasMajorTicks Identity s, HasMinorTicks (Const TicksAlignment) s,
 HasMinorTicks Identity s) =>
(TicksAlignment -> f TicksAlignment) -> s -> f s
aligns
  where
    aligns :: (TicksAlignment -> f TicksAlignment) -> s -> f s
aligns TicksAlignment -> f TicksAlignment
f s
a = (\TicksAlignment
m TicksAlignment
mn -> s
a s -> (s -> s) -> s
forall a b. a -> (a -> b) -> b
& LensLike' Identity s TicksAlignment
forall (f :: * -> *) a.
(HasMajorTicks f a, Functor f) =>
LensLike' f a TicksAlignment
majorTicksAlignment LensLike' Identity s TicksAlignment -> TicksAlignment -> s -> s
forall s t a b. ASetter s t a b -> b -> s -> t
.~ TicksAlignment
m s -> (s -> s) -> s
forall a b. a -> (a -> b) -> b
& LensLike' Identity s TicksAlignment
forall (f :: * -> *) a.
(HasMinorTicks f a, Functor f) =>
LensLike' f a TicksAlignment
minorTicksAlignment LensLike' Identity s TicksAlignment -> TicksAlignment -> s -> s
forall s t a b. ASetter s t a b -> b -> s -> t
.~ TicksAlignment
mn)
                  (TicksAlignment -> TicksAlignment -> s)
-> f TicksAlignment -> f (TicksAlignment -> s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TicksAlignment -> f TicksAlignment
f (s
a s -> Getting TicksAlignment s TicksAlignment -> TicksAlignment
forall s a. s -> Getting a s a -> a
^. Getting TicksAlignment s TicksAlignment
forall (f :: * -> *) a.
(HasMajorTicks f a, Functor f) =>
LensLike' f a TicksAlignment
majorTicksAlignment) f (TicksAlignment -> s) -> f TicksAlignment -> f s
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> TicksAlignment -> f TicksAlignment
f (s
a s -> Getting TicksAlignment s TicksAlignment -> TicksAlignment
forall s a. s -> Getting a s a -> a
^. Getting TicksAlignment s TicksAlignment
forall (f :: * -> *) a.
(HasMinorTicks f a, Functor f) =>
LensLike' f a TicksAlignment
minorTicksAlignment)

-- | Traversal over both major and minor tick styles.
ticksStyle :: (HasTicks f a, Applicative f) => LensLike' f a (Style (V a) (N a))
ticksStyle :: forall (f :: * -> *) a.
(HasTicks f a, Applicative f) =>
LensLike' f a (Style (V a) (N a))
ticksStyle = LensLike' f a (Ticks (V a) (N a))
forall (f :: * -> *) a.
HasTicks f a =>
LensLike' f a (Ticks (V a) (N a))
bothTicks LensLike' f a (Ticks (V a) (N a))
-> ((Style (V a) (N a) -> f (Style (V a) (N a)))
    -> Ticks (V a) (N a) -> f (Ticks (V a) (N a)))
-> (Style (V a) (N a) -> f (Style (V a) (N a)))
-> a
-> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Style (V a) (N a) -> f (Style (V a) (N a)))
-> Ticks (V a) (N a) -> f (Ticks (V a) (N a))
(Style (V (Ticks (V a) (N a))) (N (Ticks (V a) (N a)))
 -> f (Style (V (Ticks (V a) (N a))) (N (Ticks (V a) (N a)))))
-> Ticks (V a) (N a) -> f (Ticks (V a) (N a))
forall {f :: * -> *} {s}.
(Applicative f, HasMajorTicks (Const (Style (V s) (N s))) s,
 HasMajorTicks Identity s,
 HasMinorTicks (Const (Style (V s) (N s))) s,
 HasMinorTicks Identity s) =>
(Style (V s) (N s) -> f (Style (V s) (N s))) -> s -> f s
styles
  where
    styles :: (Style (V s) (N s) -> f (Style (V s) (N s))) -> s -> f s
styles Style (V s) (N s) -> f (Style (V s) (N s))
f s
a = (\Style (V s) (N s)
m Style (V s) (N s)
mn -> s
a s -> (s -> s) -> s
forall a b. a -> (a -> b) -> b
& LensLike' Identity s (Style (V s) (N s))
forall (f :: * -> *) a.
(HasMajorTicks f a, Functor f) =>
LensLike' f a (Style (V a) (N a))
majorTicksStyle LensLike' Identity s (Style (V s) (N s))
-> Style (V s) (N s) -> s -> s
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Style (V s) (N s)
m s -> (s -> s) -> s
forall a b. a -> (a -> b) -> b
& LensLike' Identity s (Style (V s) (N s))
forall (f :: * -> *) a.
(HasMinorTicks f a, Functor f) =>
LensLike' f a (Style (V a) (N a))
minorTicksStyle LensLike' Identity s (Style (V s) (N s))
-> Style (V s) (N s) -> s -> s
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Style (V s) (N s)
mn)
              (Style (V s) (N s) -> Style (V s) (N s) -> s)
-> f (Style (V s) (N s)) -> f (Style (V s) (N s) -> s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Style (V s) (N s) -> f (Style (V s) (N s))
f (s
a s
-> Getting (Style (V s) (N s)) s (Style (V s) (N s))
-> Style (V s) (N s)
forall s a. s -> Getting a s a -> a
^. Getting (Style (V s) (N s)) s (Style (V s) (N s))
forall (f :: * -> *) a.
(HasMajorTicks f a, Functor f) =>
LensLike' f a (Style (V a) (N a))
majorTicksStyle) f (Style (V s) (N s) -> s) -> f (Style (V s) (N s)) -> f s
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Style (V s) (N s) -> f (Style (V s) (N s))
f (s
a s
-> Getting (Style (V s) (N s)) s (Style (V s) (N s))
-> Style (V s) (N s)
forall s a. s -> Getting a s a -> a
^. Getting (Style (V s) (N s)) s (Style (V s) (N s))
forall (f :: * -> *) a.
(HasMinorTicks f a, Functor f) =>
LensLike' f a (Style (V a) (N a))
minorTicksStyle)

-- | Traversal over the visibility of both major and minor ticks.
ticksVisible :: (HasTicks f a, Applicative f) => LensLike' f a Bool
ticksVisible :: forall (f :: * -> *) a.
(HasTicks f a, Applicative f) =>
LensLike' f a Bool
ticksVisible = LensLike' f a (Ticks (V a) (N a))
forall (f :: * -> *) a.
HasTicks f a =>
LensLike' f a (Ticks (V a) (N a))
bothTicks LensLike' f a (Ticks (V a) (N a))
-> ((Bool -> f Bool) -> Ticks (V a) (N a) -> f (Ticks (V a) (N a)))
-> (Bool -> f Bool)
-> a
-> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> f Bool) -> Ticks (V a) (N a) -> f (Ticks (V a) (N a))
forall {f :: * -> *} {s}.
(Applicative f, HasMajorTicks (Const Bool) s,
 HasMajorTicks Identity s, HasMinorTicks (Const Bool) s,
 HasMinorTicks Identity s) =>
(Bool -> f Bool) -> s -> f s
visibles
  where
    visibles :: (Bool -> f Bool) -> s -> f s
visibles Bool -> f Bool
f s
a = (\Bool
m Bool
mn -> s
a s -> (s -> s) -> s
forall a b. a -> (a -> b) -> b
& LensLike' Identity s (MajorTicks (V s) (N s))
forall (f :: * -> *) a.
HasMajorTicks f a =>
LensLike' f a (MajorTicks (V a) (N a))
majorTicks LensLike' Identity s (MajorTicks (V s) (N s))
-> ((Bool -> Identity Bool)
    -> MajorTicks (V s) (N s) -> Identity (MajorTicks (V s) (N s)))
-> (Bool -> Identity Bool)
-> s
-> Identity s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Identity Bool)
-> MajorTicks (V s) (N s) -> Identity (MajorTicks (V s) (N s))
forall a. HasVisibility a => Lens' a Bool
Lens' (MajorTicks (V s) (N s)) Bool
visible ((Bool -> Identity Bool) -> s -> Identity s) -> Bool -> s -> s
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Bool
m s -> (s -> s) -> s
forall a b. a -> (a -> b) -> b
& LensLike' Identity s (MinorTicks (V s) (N s))
forall (f :: * -> *) a.
HasMinorTicks f a =>
LensLike' f a (MinorTicks (V a) (N a))
minorTicksLensLike' Identity s (MinorTicks (V s) (N s))
-> ((Bool -> Identity Bool)
    -> MinorTicks (V s) (N s) -> Identity (MinorTicks (V s) (N s)))
-> (Bool -> Identity Bool)
-> s
-> Identity s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Identity Bool)
-> MinorTicks (V s) (N s) -> Identity (MinorTicks (V s) (N s))
forall a. HasVisibility a => Lens' a Bool
Lens' (MinorTicks (V s) (N s)) Bool
visible ((Bool -> Identity Bool) -> s -> Identity s) -> Bool -> s -> s
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Bool
mn)
              (Bool -> Bool -> s) -> f Bool -> f (Bool -> s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool -> f Bool
f (s
a s -> Getting Bool s Bool -> Bool
forall s a. s -> Getting a s a -> a
^. LensLike' (Const Bool) s (MajorTicks (V s) (N s))
forall (f :: * -> *) a.
HasMajorTicks f a =>
LensLike' f a (MajorTicks (V a) (N a))
majorTicks LensLike' (Const Bool) s (MajorTicks (V s) (N s))
-> ((Bool -> Const Bool Bool)
    -> MajorTicks (V s) (N s) -> Const Bool (MajorTicks (V s) (N s)))
-> Getting Bool s Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Const Bool Bool)
-> MajorTicks (V s) (N s) -> Const Bool (MajorTicks (V s) (N s))
forall a. HasVisibility a => Lens' a Bool
Lens' (MajorTicks (V s) (N s)) Bool
visible) f (Bool -> s) -> f Bool -> f s
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Bool -> f Bool
f (s
a s -> Getting Bool s Bool -> Bool
forall s a. s -> Getting a s a -> a
^. LensLike' (Const Bool) s (MinorTicks (V s) (N s))
forall (f :: * -> *) a.
HasMinorTicks f a =>
LensLike' f a (MinorTicks (V a) (N a))
minorTicks LensLike' (Const Bool) s (MinorTicks (V s) (N s))
-> ((Bool -> Const Bool Bool)
    -> MinorTicks (V s) (N s) -> Const Bool (MinorTicks (V s) (N s)))
-> Getting Bool s Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Const Bool Bool)
-> MinorTicks (V s) (N s) -> Const Bool (MinorTicks (V s) (N s))
forall a. HasVisibility a => Lens' a Bool
Lens' (MinorTicks (V s) (N s)) Bool
visible)

-- | Hides the 'Minor' ticks when trying to render something. This can
--   be used on multiple types:
--
-- @
-- 'hideTicks' :: 'Axis' b c n       -> 'Axis' b c n
-- 'hideTicks' :: 'SingleAxis' b v n -> 'SingleAxis' b v n
-- 'hideTicks' :: 'Ticks' v n        -> 'Ticks' v n
-- 'hideTicks' :: 'MinorTicks' v n   -> 'MinorTicks' v n
-- @
hideTicks :: HasTicks Identity a => a -> a
hideTicks :: forall a. HasTicks Identity a => a -> a
hideTicks = LensLike' Identity a Bool
forall (f :: * -> *) a.
(HasTicks f a, Applicative f) =>
LensLike' f a Bool
ticksVisible LensLike' Identity a Bool -> Bool -> a -> a
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Bool
False

-- | Setter over the final positions the major ticks. This is not as
--   general as 'majorTicksFunction' because you don't have access to
--   the bounds but it can be useful when you know exactly what ticks
--   you want to add or modify existing tick positions.
majorTickPositions
  :: (HasMajorTicks f a, Settable f)
  => LensLike' f a [N a]
majorTickPositions :: forall (f :: * -> *) a.
(HasMajorTicks f a, Settable f) =>
LensLike' f a [N a]
majorTickPositions = LensLike' f a ((N a, N a) -> [N a])
forall (f :: * -> *) a.
(HasMajorTicks f a, Functor f) =>
LensLike' f a ((N a, N a) -> [N a])
majorTicksFunction LensLike' f a ((N a, N a) -> [N a])
-> (([N a] -> f [N a])
    -> ((N a, N a) -> [N a]) -> f ((N a, N a) -> [N a]))
-> ([N a] -> f [N a])
-> a
-> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([N a] -> f [N a])
-> ((N a, N a) -> [N a]) -> f ((N a, N a) -> [N a])
Setter ((N a, N a) -> [N a]) ((N a, N a) -> [N a]) [N a] [N a]
forall (f :: * -> *) a b. Functor f => Setter (f a) (f b) a b
mapped

-- | Setter over the final positions the major ticks. This is not as
--   general as 'minorTicksFunction' because you don't have access to
--   the bounds but it can be useful when you know exactly what ticks
--   you want to add or modify existing tick positions.
minorTickPositions
  :: (HasMinorTicks f a, Settable f)
  => LensLike' f a [N a]
minorTickPositions :: forall (f :: * -> *) a.
(HasMinorTicks f a, Settable f) =>
LensLike' f a [N a]
minorTickPositions = LensLike' f a ([N a] -> (N a, N a) -> [N a])
forall (f :: * -> *) a.
(HasMinorTicks f a, Functor f) =>
LensLike' f a ([N a] -> (N a, N a) -> [N a])
minorTicksFunction LensLike' f a ([N a] -> (N a, N a) -> [N a])
-> (([N a] -> f [N a])
    -> ([N a] -> (N a, N a) -> [N a])
    -> f ([N a] -> (N a, N a) -> [N a]))
-> ([N a] -> f [N a])
-> a
-> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((N a, N a) -> [N a]) -> f ((N a, N a) -> [N a]))
-> ([N a] -> (N a, N a) -> [N a])
-> f ([N a] -> (N a, N a) -> [N a])
Setter
  ([N a] -> (N a, N a) -> [N a])
  ([N a] -> (N a, N a) -> [N a])
  ((N a, N a) -> [N a])
  ((N a, N a) -> [N a])
forall (f :: * -> *) a b. Functor f => Setter (f a) (f b) a b
mapped ((((N a, N a) -> [N a]) -> f ((N a, N a) -> [N a]))
 -> ([N a] -> (N a, N a) -> [N a])
 -> f ([N a] -> (N a, N a) -> [N a]))
-> (([N a] -> f [N a])
    -> ((N a, N a) -> [N a]) -> f ((N a, N a) -> [N a]))
-> ([N a] -> f [N a])
-> ([N a] -> (N a, N a) -> [N a])
-> f ([N a] -> (N a, N a) -> [N a])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([N a] -> f [N a])
-> ((N a, N a) -> [N a]) -> f ((N a, N a) -> [N a])
Setter ((N a, N a) -> [N a]) ((N a, N a) -> [N a]) [N a] [N a]
forall (f :: * -> *) a b. Functor f => Setter (f a) (f b) a b
mapped

------------------------------------------------------------------------
-- Calculating ticks
------------------------------------------------------------------------

-- Linear ticks --------------------------------------------------------

-- | Ticks whose value ends in 1, 0.5, 0.25, 0.2 (*10^n).
linearMajorTicks :: (RealFrac n, Floating n) => n -> (n, n) -> [n]
linearMajorTicks :: forall n. (RealFrac n, Floating n) => n -> (n, n) -> [n]
linearMajorTicks = [n] -> n -> (n, n) -> [n]
forall n. (RealFrac n, Floating n) => [n] -> n -> (n, n) -> [n]
majorTicksHelper [n
1, n
0.5, n
0.25, n
0.2, n
0.3]

-- Logarithmic ticks ---------------------------------------------------

-- | Place n ticks at powers of 10 on the axis.
logMajorTicks :: (RealFrac n, Floating n) => n -> (n, n) -> [n]
logMajorTicks :: forall n. (RealFrac n, Floating n) => n -> (n, n) -> [n]
logMajorTicks n
n (n
a,n
b) =
  -- Logarithmic ticks are just like linear ticks but in a different domain.
  (n -> n) -> [n] -> [n]
forall a b. (a -> b) -> [a] -> [b]
map (n
10n -> n -> n
forall a. Floating a => a -> a -> a
**) ([n] -> [n]) -> [n] -> [n]
forall a b. (a -> b) -> a -> b
$ [n] -> n -> (n, n) -> [n]
forall n. (RealFrac n, Floating n) => [n] -> n -> (n, n) -> [n]
majorTicksHelper [n]
ts n
n (n -> n
forall a. Floating a => a -> a
log10 (n -> n -> n
forall a. Ord a => a -> a -> a
max n
2 n
a), n -> n
forall a. Floating a => a -> a
log10 n
b)
    where ts :: [n]
ts = [n
1,n
2,n
3,n
4,n
5,n
6,n
7,n
8,n
9]

-- Ticks helpers -------------------------------------------------------

-- | Place n linear spaced ticks between each major tick.
minorTicksHelper
  :: Fractional n
  => Int    -- ^ Number of minor ticks between each major tick
  -> [n]    -- ^ Positions of major ticks
  -> (n, n) -- ^ Bounds
  -> [n]    -- ^ Minor tick positions
minorTicksHelper :: forall n. Fractional n => Int -> [n] -> (n, n) -> [n]
minorTicksHelper Int
n [n]
ts (n, n)
_ = [[n]] -> [n]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
F.concat ([[n]] -> [n]) -> [[n]] -> [n]
forall a b. (a -> b) -> a -> b
$ [n] -> [[n]]
go [n]
ts where
  -- we won't want x1 and x2 to be minor ticks too we init/tail them.
  go :: [n] -> [[n]]
go (n
x1:n
x2:[n]
xs) = ([n] -> [n]
forall a. HasCallStack => [a] -> [a]
init ([n] -> [n]) -> ([n] -> [n]) -> [n] -> [n]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [n] -> [n]
forall a. HasCallStack => [a] -> [a]
tail) (n -> n -> Int -> [n]
forall n. Fractional n => n -> n -> Int -> [n]
enumFromToN n
x1 n
x2 (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
2)) [n] -> [[n]] -> [[n]]
forall a. a -> [a] -> [a]
: [n] -> [[n]]
go (n
x2n -> [n] -> [n]
forall a. a -> [a] -> [a]
:[n]
xs)
  go [n]
_          = []

-- | Choose ticks whose step size is a multiple of 10 of the allowed
--   numbers and tries to match the number of desired ticks.
--
--   Note that the resulting tick positions may go out of the range of
--   the bounds. This is so the minor ticks can be chosen correctly if a
--   tick doesn't end exactly on a bound. When we render, we ignore all
--   ticks outside the bounds.
majorTicksHelper
  :: (RealFrac n, Floating n)
  => [n]    -- ^ Allowed numbers (up to powers of 10)
  -> n      -- ^ desired number of ticks
  -> (n, n) -- ^ bounds
  -> [n]    -- ^ tick positions
majorTicksHelper :: forall n. (RealFrac n, Floating n) => [n] -> n -> (n, n) -> [n]
majorTicksHelper [n]
ts0 n
n (n
a,n
b) = Int -> (n -> n) -> n -> [n]
forall a. Int -> (a -> a) -> a -> [a]
iterateN Int
n' (n -> n -> n
forall a. Num a => a -> a -> a
+n
h) n
a'
  where
  i :: n
i  = Int -> n
forall a b. (Integral a, Num b) => a -> b
fromIntegral (n -> Int
forall b. Integral b => n -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor ( n
a n -> n -> n
forall a. Fractional a => a -> a -> a
/ n
h ) :: Int)

  a' :: n
a' = n
in -> n -> n
forall a. Num a => a -> a -> a
*n
h
  n' :: Int
n' = n -> Int
forall b. Integral b => n -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling ((n
b n -> n -> n
forall a. Num a => a -> a -> a
- n
a')n -> n -> n
forall a. Fractional a => a -> a -> a
/n
h) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1

  -- Find the a value from our potential ticks that's closest to our
  -- ideal height.
  h :: n
h  = (n -> n -> Ordering) -> [n] -> n
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
minimumBy ((n -> n) -> n -> n -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing ((n -> n) -> n -> n -> Ordering) -> (n -> n) -> n -> n -> Ordering
forall a b. (a -> b) -> a -> b
$ n -> n
forall a. Num a => a -> a
abs (n -> n) -> (n -> n) -> n -> n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (n
h' n -> n -> n
forall a. Num a => a -> a -> a
-)) [n]
ts'

  -- Ideal height for the desired number of ticks.
  h' :: n
h' = n
d n -> n -> n
forall a. Fractional a => a -> a -> a
/ n
n

  -- Potential step heights that look nice and are in a suitable range
  -- for the axis bounds.
  ts' :: [n]
ts' = (n -> n) -> [n] -> [n]
forall a b. (a -> b) -> [a] -> [b]
map (n -> n -> n
forall a. Num a => a -> a -> a
* n
10 n -> Int -> n
forall a b. (Fractional a, Integral b) => a -> b -> a
^^ (n -> Int
forall b. Integral b => n -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (n -> Int) -> n -> Int
forall a b. (a -> b) -> a -> b
$ n -> n
forall a. Floating a => a -> a
log10 n
d :: Int)) ([n]
ts0 [n] -> [n] -> [n]
forall a. [a] -> [a] -> [a]
++ (n -> n) -> [n] -> [n]
forall a b. (a -> b) -> [a] -> [b]
map (n -> n -> n
forall a. Num a => a -> a -> a
*n
10) [n]
ts0)
  d :: n
d   = n -> n
forall a. Num a => a -> a
abs (n -> n) -> n -> n
forall a b. (a -> b) -> a -> b
$ n
b n -> n -> n
forall a. Num a => a -> a -> a
- n
a

-- logged :: Floating a => Iso' a a
-- logged = iso log10 (10**)

log10 :: Floating a => a -> a
log10 :: forall a. Floating a => a -> a
log10 = a -> a -> a
forall a. Floating a => a -> a -> a
logBase a
10