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

instance PlotValue PlotIndex where
    toValue :: PlotIndex -> Double
toValue (PlotIndex Int
i) = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i
    fromValue :: Double -> PlotIndex
fromValue             = Int -> PlotIndex
PlotIndex forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (RealFrac a, Integral b) => a -> b
round
    autoAxis :: AxisFn PlotIndex
autoAxis              = 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 = 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 = forall a. Default a => a
def { _axis_show_ticks :: Bool
_axis_show_ticks = Bool
False },
    _axis_viewport :: Range -> i -> Double
_axis_viewport = 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 forall a b. (a -> b) -> [a] -> [b]
map (, Double
5) forall a b. (a -> b) -> a -> b
$ forall a. Int -> [a] -> [a]
take (forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
labels) [i
0..] else [],
    _axis_labels :: [[(i, String)]]
_axis_labels   = [forall a. (a -> Bool) -> [a] -> [a]
filter (\(i
i,String
_) -> i
i forall a. Ord a => a -> a -> Bool
>= i
imin Bool -> Bool -> Bool
&& i
i forall a. Ord a => a -> a -> Bool
<= i
imax)
                             (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 = forall a. (a -> Double) -> (a, a) -> Range -> a -> Double
linMap forall a. a -> a
id ( forall a b. (Integral a, Num b) => a -> b
fromIntegral i
imin forall a. Num a => a -> a -> a
- Double
0.5
                          , forall a b. (Integral a, Num b) => a -> b
fromIntegral i
imax forall a. Num a => a -> a -> a
+ Double
0.5) Range
r (forall a b. (Integral a, Num b) => a -> b
fromIntegral a
i)
    invport :: Range -> Double -> i
invport = forall a.
(Double -> a) -> (a -> Double) -> (a, a) -> Range -> Double -> a
invLinMap forall a b. (RealFrac a, Integral b) => a -> b
round forall a b. (Integral a, Num b) => a -> b
fromIntegral (i
imin, i
imax)
    imin :: i
imin = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [i]
vs
    imax :: i
imax = 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 = forall i. Integral i => Bool -> [String] -> AxisFn i
autoIndexAxis' Bool
False