-----------------------------------------------------------------------------
-- |
-- 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 #-}

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

import Control.Arrow (first) 
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
/= :: PlotIndex -> PlotIndex -> Bool
$c/= :: PlotIndex -> PlotIndex -> Bool
== :: PlotIndex -> PlotIndex -> Bool
$c== :: 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
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
$cp1Ord :: Eq 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
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
(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
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
Num PlotIndex
-> Ord PlotIndex -> (PlotIndex -> Rational) -> Real PlotIndex
PlotIndex -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: PlotIndex -> Rational
$ctoRational :: PlotIndex -> Rational
$cp2Real :: Ord PlotIndex
$cp1Real :: Num PlotIndex
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
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
$cp2Integral :: Enum PlotIndex
$cp1Integral :: Real PlotIndex
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
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) = 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 a b. (RealFrac a, Integral b) => a -> b
round
    autoAxis :: AxisFn PlotIndex
autoAxis              = [String] -> AxisFn PlotIndex
forall i. Integral i => [String] -> [i] -> AxisData i
autoIndexAxis []

-- | Augment a list of values with index numbers for plotting.
addIndexes :: [a] -> [(PlotIndex,a)]
addIndexes :: [a] -> [(PlotIndex, a)]
addIndexes [a]
as = ((Int, a) -> (PlotIndex, a)) -> [(Int, a)] -> [(PlotIndex, a)]
forall a b. (a -> b) -> [a] -> [b]
map ((Int -> PlotIndex) -> (Int, a) -> (PlotIndex, a)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first Int -> PlotIndex
PlotIndex) ([Int] -> [a] -> [(Int, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] [a]
as)

-- | Create an axis for values indexed by position. The
--   list of strings are the labels to be used.
autoIndexAxis :: Integral i => [String] -> [i] -> AxisData i
autoIndexAxis :: [String] -> [i] -> AxisData i
autoIndexAxis [String]
labels [i]
vs = AxisData :: forall x.
AxisVisibility
-> (Range -> x -> Double)
-> (Range -> Double -> x)
-> [(x, Double)]
-> [[(x, String)]]
-> [x]
-> AxisData x
AxisData {
    _axis_visibility :: AxisVisibility
_axis_visibility = AxisVisibility
forall a. Default a => a
def { _axis_show_ticks :: Bool
_axis_show_ticks = Bool
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    = [],
    _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 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 (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [i]
vs
    imax :: i
imax = [i] -> i
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [i]
vs