    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Graphics.Rendering.Chart.Axis.Unit
    -- Copyright   :  (c) Tim Docker 2010, 2014
    -- License     :  BSD-style (see chart/COPYRIGHT)
    --
    -- Calculate and render indexed axes

    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE TupleSections #-}

    module Graphics.Rendering.Chart.Axis.Indexed(
        PlotIndex(..),
        autoIndexAxis',
        autoIndexAxis,
        addIndexes,
    ) where

    import Data.Default.Class

    import Graphics.Rendering.Chart.Axis.Types

    -- | Type for capturing values plotted by index number
    --   (ie position in a list) rather than a numerical value.
    newtype PlotIndex = PlotIndex { PlotIndex -> Int
    plotindex_i :: Int }
      deriving (PlotIndex -> PlotIndex -> Bool
    (PlotIndex -> PlotIndex -> Bool)
    -> (PlotIndex -> PlotIndex -> Bool) -> Eq PlotIndex
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PlotIndex -> PlotIndex -> Bool
    == :: PlotIndex -> PlotIndex -> Bool
    $c/= :: PlotIndex -> PlotIndex -> Bool
    /= :: PlotIndex -> PlotIndex -> Bool
    Eq,Eq PlotIndex
    Eq PlotIndex =>
    (PlotIndex -> PlotIndex -> Ordering)
    -> (PlotIndex -> PlotIndex -> Bool)
    -> (PlotIndex -> PlotIndex -> Bool)
    -> (PlotIndex -> PlotIndex -> Bool)
    -> (PlotIndex -> PlotIndex -> Bool)
    -> (PlotIndex -> PlotIndex -> PlotIndex)
    -> (PlotIndex -> PlotIndex -> PlotIndex)
    -> Ord PlotIndex
    PlotIndex -> PlotIndex -> Bool
    PlotIndex -> PlotIndex -> Ordering
    PlotIndex -> PlotIndex -> PlotIndex
    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 :: PlotIndex -> PlotIndex -> Ordering
    compare :: PlotIndex -> PlotIndex -> Ordering
    $c< :: PlotIndex -> PlotIndex -> Bool
    < :: PlotIndex -> PlotIndex -> Bool
    $c<= :: PlotIndex -> PlotIndex -> Bool
    <= :: PlotIndex -> PlotIndex -> Bool
    $c> :: PlotIndex -> PlotIndex -> Bool
    > :: PlotIndex -> PlotIndex -> Bool
    $c>= :: PlotIndex -> PlotIndex -> Bool
    >= :: PlotIndex -> PlotIndex -> Bool
    $cmax :: PlotIndex -> PlotIndex -> PlotIndex
    max :: PlotIndex -> PlotIndex -> PlotIndex
    $cmin :: PlotIndex -> PlotIndex -> PlotIndex
    min :: PlotIndex -> PlotIndex -> PlotIndex
    Ord,Int -> PlotIndex
    PlotIndex -> Int
    PlotIndex -> [PlotIndex]
    PlotIndex -> PlotIndex
    PlotIndex -> PlotIndex -> [PlotIndex]
    PlotIndex -> PlotIndex -> PlotIndex -> [PlotIndex]
    (PlotIndex -> PlotIndex)
    -> (PlotIndex -> PlotIndex)
    -> (Int -> PlotIndex)
    -> (PlotIndex -> Int)
    -> (PlotIndex -> [PlotIndex])
    -> (PlotIndex -> PlotIndex -> [PlotIndex])
    -> (PlotIndex -> PlotIndex -> [PlotIndex])
    -> (PlotIndex -> PlotIndex -> PlotIndex -> [PlotIndex])
    -> Enum PlotIndex
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: PlotIndex -> PlotIndex
    succ :: PlotIndex -> PlotIndex
    $cpred :: PlotIndex -> PlotIndex
    pred :: PlotIndex -> PlotIndex
    $ctoEnum :: Int -> PlotIndex
    toEnum :: Int -> PlotIndex
    $cfromEnum :: PlotIndex -> Int
    fromEnum :: PlotIndex -> Int
    $cenumFrom :: PlotIndex -> [PlotIndex]
    enumFrom :: PlotIndex -> [PlotIndex]
    $cenumFromThen :: PlotIndex -> PlotIndex -> [PlotIndex]
    enumFromThen :: PlotIndex -> PlotIndex -> [PlotIndex]
    $cenumFromTo :: PlotIndex -> PlotIndex -> [PlotIndex]
    enumFromTo :: PlotIndex -> PlotIndex -> [PlotIndex]
    $cenumFromThenTo :: PlotIndex -> PlotIndex -> PlotIndex -> [PlotIndex]
    enumFromThenTo :: PlotIndex -> PlotIndex -> PlotIndex -> [PlotIndex]
    Enum,Integer -> PlotIndex
    PlotIndex -> PlotIndex
    PlotIndex -> PlotIndex -> PlotIndex
    (PlotIndex -> PlotIndex -> PlotIndex)
    -> (PlotIndex -> PlotIndex -> PlotIndex)
    -> (PlotIndex -> PlotIndex -> PlotIndex)
    -> (PlotIndex -> PlotIndex)
    -> (PlotIndex -> PlotIndex)
    -> (PlotIndex -> PlotIndex)
    -> (Integer -> PlotIndex)
    -> Num PlotIndex
    forall a.
    (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (Integer -> a)
    -> Num a
    $c+ :: PlotIndex -> PlotIndex -> PlotIndex
    + :: PlotIndex -> PlotIndex -> PlotIndex
    $c- :: PlotIndex -> PlotIndex -> PlotIndex
    - :: PlotIndex -> PlotIndex -> PlotIndex
    $c* :: PlotIndex -> PlotIndex -> PlotIndex
    * :: PlotIndex -> PlotIndex -> PlotIndex
    $cnegate :: PlotIndex -> PlotIndex
    negate :: PlotIndex -> PlotIndex
    $cabs :: PlotIndex -> PlotIndex
    abs :: PlotIndex -> PlotIndex
    $csignum :: PlotIndex -> PlotIndex
    signum :: PlotIndex -> PlotIndex
    $cfromInteger :: Integer -> PlotIndex
    fromInteger :: Integer -> PlotIndex
    Num,Num PlotIndex
    Ord PlotIndex
    (Num PlotIndex, Ord PlotIndex) =>
    (PlotIndex -> Rational) -> Real PlotIndex
    PlotIndex -> Rational
    forall a. (Num a, Ord a) => (a -> Rational) -> Real a
    $ctoRational :: PlotIndex -> Rational
    toRational :: PlotIndex -> Rational
    Real,Enum PlotIndex
    Real PlotIndex
    (Real PlotIndex, Enum PlotIndex) =>
    (PlotIndex -> PlotIndex -> PlotIndex)
    -> (PlotIndex -> PlotIndex -> PlotIndex)
    -> (PlotIndex -> PlotIndex -> PlotIndex)
    -> (PlotIndex -> PlotIndex -> PlotIndex)
    -> (PlotIndex -> PlotIndex -> (PlotIndex, PlotIndex))
    -> (PlotIndex -> PlotIndex -> (PlotIndex, PlotIndex))
    -> (PlotIndex -> Integer)
    -> Integral PlotIndex
    PlotIndex -> Integer
    PlotIndex -> PlotIndex -> (PlotIndex, PlotIndex)
    PlotIndex -> PlotIndex -> PlotIndex
    forall a.
    (Real a, Enum a) =>
    (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> (a, a))
    -> (a -> a -> (a, a))
    -> (a -> Integer)
    -> Integral a
    $cquot :: PlotIndex -> PlotIndex -> PlotIndex
    quot :: PlotIndex -> PlotIndex -> PlotIndex
    $crem :: PlotIndex -> PlotIndex -> PlotIndex
    rem :: PlotIndex -> PlotIndex -> PlotIndex
    $cdiv :: PlotIndex -> PlotIndex -> PlotIndex
    div :: PlotIndex -> PlotIndex -> PlotIndex
    $cmod :: PlotIndex -> PlotIndex -> PlotIndex
    mod :: PlotIndex -> PlotIndex -> PlotIndex
    $cquotRem :: PlotIndex -> PlotIndex -> (PlotIndex, PlotIndex)
    quotRem :: PlotIndex -> PlotIndex -> (PlotIndex, PlotIndex)
    $cdivMod :: PlotIndex -> PlotIndex -> (PlotIndex, PlotIndex)
    divMod :: PlotIndex -> PlotIndex -> (PlotIndex, PlotIndex)
    $ctoInteger :: PlotIndex -> Integer
    toInteger :: PlotIndex -> Integer
    Integral,Int -> PlotIndex -> ShowS
    [PlotIndex] -> ShowS
    PlotIndex -> String
    (Int -> PlotIndex -> ShowS)
    -> (PlotIndex -> String)
    -> ([PlotIndex] -> ShowS)
    -> Show PlotIndex
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PlotIndex -> ShowS
    showsPrec :: Int -> PlotIndex -> ShowS
    $cshow :: PlotIndex -> String
    show :: PlotIndex -> String
    $cshowList :: [PlotIndex] -> ShowS
    showList :: [PlotIndex] -> ShowS
    Show)

    instance PlotValue PlotIndex where
        toValue :: PlotIndex -> Double
    toValue (PlotIndex Int
    i) = Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    i
        fromValue :: Double -> PlotIndex
    fromValue             = Int -> PlotIndex
    PlotIndex (Int -> PlotIndex) -> (Double -> Int) -> Double -> PlotIndex
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Int
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round
        autoAxis :: AxisFn PlotIndex
    autoAxis              = [String] -> AxisFn PlotIndex
    forall i. Integral i => [String] -> AxisFn i
    autoIndexAxis []

    -- | Augment a list of values with index numbers for plotting.
    addIndexes :: [a] -> [(PlotIndex,a)]
    addIndexes :: forall a. [a] -> [(PlotIndex, a)]
    addIndexes = (Int -> a -> (PlotIndex, a)) -> [Int] -> [a] -> [(PlotIndex, a)]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (\Int
    n a
    x -> (Int -> PlotIndex
    PlotIndex Int
    n, a
    x)) [Int
    0..]

    -- | Create an axis for values indexed by position. The
    --   list of strings are the labels to be used.
    autoIndexAxis' :: Integral i => Bool -> [String] -> AxisFn i
    autoIndexAxis' :: forall i. Integral i => Bool -> [String] -> AxisFn i
    autoIndexAxis' Bool
    tks [String]
    labels [i]
    vs = AxisData {
        _axis_visibility :: AxisVisibility
    _axis_visibility = AxisVisibility
    forall a. Default a => a
    def { _axis_show_ticks = False },
        _axis_viewport :: Range -> i -> Double
    _axis_viewport = Range -> i -> Double
    forall {a}. Integral a => Range -> a -> Double
    vport,
        _axis_tropweiv :: Range -> Double -> i
    _axis_tropweiv = Range -> Double -> i
    invport,
        _axis_ticks :: [(i, Double)]
    _axis_ticks    = if Bool
    tks then (i -> (i, Double)) -> [i] -> [(i, Double)]
    forall a b. (a -> b) -> [a] -> [b]
    map (, Double
    5) ([i] -> [(i, Double)]) -> [i] -> [(i, Double)]
    forall a b. (a -> b) -> a -> b
    $ Int -> [i] -> [i]
    forall a. Int -> [a] -> [a]
    take ([String] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [String]
    labels) [i
    0..] else [],
        _axis_labels :: [[(i, String)]]
    _axis_labels   = [((i, String) -> Bool) -> [(i, String)] -> [(i, String)]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (\(i
    i,String
    _) -> i
    i i -> i -> Bool
    forall a. Ord a => a -> a -> Bool
    >= i
    imin Bool -> Bool -> Bool
    && i
    i i -> i -> Bool
    forall a. Ord a => a -> a -> Bool
    <= i
    imax)
                                 ([i] -> [String] -> [(i, String)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [i
    0..] [String]
    labels)],
        _axis_grid :: [i]
    _axis_grid     = []
        }
      where
        vport :: Range -> a -> Double
    vport Range
    r a
    i = (Double -> Double) -> Range -> Range -> Double -> Double
    forall a. (a -> Double) -> (a, a) -> Range -> a -> Double
    linMap Double -> Double
    forall a. a -> a
    id ( i -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral i
    imin Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Double
    0.5
                              , i -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral i
    imax Double -> Double -> Double
    forall a. Num a => a -> a -> a
    + Double
    0.5) Range
    r (a -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    i)
        invport :: Range -> Double -> i
    invport = (Double -> i) -> (i -> Double) -> (i, i) -> Range -> Double -> i
    forall a.
    (Double -> a) -> (a -> Double) -> (a, a) -> Range -> Double -> a
    invLinMap Double -> i
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round i -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (i
    imin, i
    imax)
        imin :: i
    imin = [i] -> i
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    minimum [i]
    vs
        imax :: i
    imax = [i] -> i
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum [i]
    vs

    autoIndexAxis :: Integral i => [String] -> AxisFn i
    autoIndexAxis :: forall i. Integral i => [String] -> AxisFn i
    autoIndexAxis = Bool -> [String] -> AxisFn i
    forall i. Integral i => Bool -> [String] -> AxisFn i
    autoIndexAxis' Bool
    False