{-# LANGUAGE CPP                    #-}
{-# LANGUAGE DeriveDataTypeable     #-}
{-# LANGUAGE FlexibleContexts       #-}
{-# LANGUAGE FlexibleInstances      #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs                  #-}
{-# LANGUAGE MultiParamTypeClasses  #-}
{-# LANGUAGE RankNTypes             #-}
{-# LANGUAGE ScopedTypeVariables    #-}
{-# LANGUAGE TemplateHaskell        #-}
{-# LANGUAGE TypeFamilies           #-}
{-# LANGUAGE TypeOperators          #-}
{-# LANGUAGE UndecidableInstances   #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Plots.Types
-- Copyright   :  (C) 2015 Christopher Chalmers
-- License     :  BSD-style (see the file LICENSE)
-- Maintainer  :  Christopher Chalmers
-- Stability   :  experimental
-- Portability :  non-portable
--
-- This module defines the various types for holding plots:
--
-- [@'PlotOptions' b v n@]
-- Generic options all plots have.
--
-- [@'PlotMods' b v n@]
-- Includes 'PlotOptions' along with modifications to the 'PlotStyle'.
--
-- [@'Plot' p b@]
-- A 'rawPlot' @p@ grouped with a 'PlotMods'.
--
-- [@'DynamicPlot' b v n@]
-- A wrapped up 'Plot' so it can be stored in an 'Axis'.
--
-- [@'StyledPlot' b v n@]
-- A 'DynamicPlot' with a concrete 'PlotStyle', ready to be rendered.
--
-- As well as other things like the 'Plotable' class, 'LegendEntries',
-- 'HasOrientation' and 'HasVisibility'.
--
----------------------------------------------------------------------------
module Plots.Types
  (

    -- * Plot options
    PlotOptions
  , HasPlotOptions (..)
  , key
  , addLegendEntry

    -- ** Plot modifications
  , PlotMods
  , plotMods

    -- * Plotable class
  , Plotable (..)

    -- * Plot types
    -- ** Parameterised plot
  , Plot
  , mkPlot
  , rawPlot

    -- ** Dynamic plot
  , DynamicPlot (..)
  , _DynamicPlot
  , dynamicPlot
  , dynamicPlotMods

    -- ** Styled plot
  , StyledPlot
  , styledPlot
  , styleDynamic
  , renderStyledPlot
  , singleStyledPlotLegend
  , styledPlotLegends

  -- * Miscellaneous
  -- ** Visibility
  , HasVisibility (..)
  , hide
  , display

  -- ** Orientation
  , Orientation (..)
  , HasOrientation (..)
  , orient
  , horizontal
  , vertical

  -- ** Legend entries
  , LegendEntry
  , LegendPic (..)
  , mkLegendEntry
  , legendPicture
  , legendText
  , legendPrecedence

    -- ** Axis spec
  , AxisSpec (..)
  , specTrans
  , specBounds
  , specScale
  , scaleNum
  , specPoint
  , specColourMap

  -- ** Positioning
  , Placement (..)
  , HasPlacement (..)
  , HasGap (..)
  , placeAgainst

  -- *** Common positions
  -- **** Inside positions
  , topLeft, top, topRight, left, right, bottomLeft, bottom
  , bottomRight

  -- **** Outside positions
  , leftAbove, leftTop, leftMid, leftBottom, leftBelow, midAbove, midBelow
  , rightAbove, rightTop, rightMid, rightBottom, rightBelow

  ) where

import           Control.Monad.State
import           Data.Bool
import           Data.List           (sortBy)
import           Data.Maybe          (fromMaybe)
import           Data.Ord            (comparing)
import           Data.Orphans        ()
import           Data.Typeable
import           Diagrams.Prelude    as D

import           Plots.Axis.Scale
import           Plots.Style
import           Plots.Util

-- Orientation ---------------------------------------------------------

data Orientation = Horizontal | Vertical
  deriving (Int -> Orientation -> ShowS
[Orientation] -> ShowS
Orientation -> String
(Int -> Orientation -> ShowS)
-> (Orientation -> String)
-> ([Orientation] -> ShowS)
-> Show Orientation
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Orientation] -> ShowS
$cshowList :: [Orientation] -> ShowS
show :: Orientation -> String
$cshow :: Orientation -> String
showsPrec :: Int -> Orientation -> ShowS
$cshowsPrec :: Int -> Orientation -> ShowS
Show, Orientation -> Orientation -> Bool
(Orientation -> Orientation -> Bool)
-> (Orientation -> Orientation -> Bool) -> Eq Orientation
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Orientation -> Orientation -> Bool
$c/= :: Orientation -> Orientation -> Bool
== :: Orientation -> Orientation -> Bool
$c== :: Orientation -> Orientation -> Bool
Eq, Eq Orientation
Eq Orientation
-> (Orientation -> Orientation -> Ordering)
-> (Orientation -> Orientation -> Bool)
-> (Orientation -> Orientation -> Bool)
-> (Orientation -> Orientation -> Bool)
-> (Orientation -> Orientation -> Bool)
-> (Orientation -> Orientation -> Orientation)
-> (Orientation -> Orientation -> Orientation)
-> Ord Orientation
Orientation -> Orientation -> Bool
Orientation -> Orientation -> Ordering
Orientation -> Orientation -> Orientation
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 :: Orientation -> Orientation -> Orientation
$cmin :: Orientation -> Orientation -> Orientation
max :: Orientation -> Orientation -> Orientation
$cmax :: Orientation -> Orientation -> Orientation
>= :: Orientation -> Orientation -> Bool
$c>= :: Orientation -> Orientation -> Bool
> :: Orientation -> Orientation -> Bool
$c> :: Orientation -> Orientation -> Bool
<= :: Orientation -> Orientation -> Bool
$c<= :: Orientation -> Orientation -> Bool
< :: Orientation -> Orientation -> Bool
$c< :: Orientation -> Orientation -> Bool
compare :: Orientation -> Orientation -> Ordering
$ccompare :: Orientation -> Orientation -> Ordering
Ord, Typeable)

-- | Pick the first @a@ if the object has 'Horizontal' orientation and
--   the second @a@ if the object has a 'Vertical' orientation.
orient :: HasOrientation o => o -> a -> a -> a
orient :: forall o a. HasOrientation o => o -> a -> a -> a
orient o
o a
h a
v =
  case Getting Orientation o Orientation -> o -> Orientation
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Orientation o Orientation
forall a. HasOrientation a => Lens' a Orientation
orientation o
o of
    Orientation
Horizontal -> a
h
    Orientation
Vertical   -> a
v

-- | Class of things that have an orientation.
class HasOrientation a where
  -- | Lens onto the orientation of an object.
  orientation :: Lens' a Orientation

instance HasOrientation Orientation where
  orientation :: Lens' Orientation Orientation
orientation = (Orientation -> f Orientation) -> Orientation -> f Orientation
forall a. a -> a
id

-- | Lens onto whether an object's orientation is horizontal.
horizontal :: HasOrientation a => Lens' a Bool
horizontal :: forall a. HasOrientation a => Lens' a Bool
horizontal = (Orientation -> f Orientation) -> a -> f a
forall a. HasOrientation a => Lens' a Orientation
orientation ((Orientation -> f Orientation) -> a -> f a)
-> ((Bool -> f Bool) -> Orientation -> f Orientation)
-> (Bool -> f Bool)
-> a
-> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Orientation -> Bool)
-> (Bool -> Orientation) -> Iso Orientation Orientation Bool Bool
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso (Orientation -> Orientation -> Bool
forall a. Eq a => a -> a -> Bool
==Orientation
Horizontal) (Orientation -> Orientation -> Bool -> Orientation
forall a. a -> a -> Bool -> a
bool Orientation
Vertical Orientation
Horizontal)

-- | Lens onto whether an object's orientation is vertical.
vertical :: HasOrientation a => Lens' a Bool
vertical :: forall a. HasOrientation a => Lens' a Bool
vertical = (Bool -> f Bool) -> a -> f a
forall a. HasOrientation a => Lens' a Bool
horizontal ((Bool -> f Bool) -> a -> f a)
-> ((Bool -> f Bool) -> Bool -> f Bool)
-> (Bool -> f Bool)
-> a
-> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Bool) -> Iso' Bool Bool
forall a. (a -> a) -> Iso' a a
involuted Bool -> Bool
not

------------------------------------------------------------------------
-- Placement
------------------------------------------------------------------------

class HasGap a where
  -- | The value of the gap when rendering.
  gap :: Lens' a (N a)

-- | A 'Position' is a point on an axis together with an anchor and a
--   direction for the gap.
data Placement = Placement
  { Placement -> V2 Rational
pAt     :: V2 Rational
  , Placement -> V2 Rational
pAnchor :: V2 Rational
  , Placement -> Direction V2 Rational
pGapDir :: Direction V2 Rational
  }
  deriving (Int -> Placement -> ShowS
[Placement] -> ShowS
Placement -> String
(Int -> Placement -> ShowS)
-> (Placement -> String)
-> ([Placement] -> ShowS)
-> Show Placement
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Placement] -> ShowS
$cshowList :: [Placement] -> ShowS
show :: Placement -> String
$cshow :: Placement -> String
showsPrec :: Int -> Placement -> ShowS
$cshowsPrec :: Int -> Placement -> ShowS
Show, ReadPrec [Placement]
ReadPrec Placement
Int -> ReadS Placement
ReadS [Placement]
(Int -> ReadS Placement)
-> ReadS [Placement]
-> ReadPrec Placement
-> ReadPrec [Placement]
-> Read Placement
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Placement]
$creadListPrec :: ReadPrec [Placement]
readPrec :: ReadPrec Placement
$creadPrec :: ReadPrec Placement
readList :: ReadS [Placement]
$creadList :: ReadS [Placement]
readsPrec :: Int -> ReadS Placement
$creadsPrec :: Int -> ReadS Placement
Read, Placement -> Placement -> Bool
(Placement -> Placement -> Bool)
-> (Placement -> Placement -> Bool) -> Eq Placement
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Placement -> Placement -> Bool
$c/= :: Placement -> Placement -> Bool
== :: Placement -> Placement -> Bool
$c== :: Placement -> Placement -> Bool
Eq, Eq Placement
Eq Placement
-> (Placement -> Placement -> Ordering)
-> (Placement -> Placement -> Bool)
-> (Placement -> Placement -> Bool)
-> (Placement -> Placement -> Bool)
-> (Placement -> Placement -> Bool)
-> (Placement -> Placement -> Placement)
-> (Placement -> Placement -> Placement)
-> Ord Placement
Placement -> Placement -> Bool
Placement -> Placement -> Ordering
Placement -> Placement -> Placement
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 :: Placement -> Placement -> Placement
$cmin :: Placement -> Placement -> Placement
max :: Placement -> Placement -> Placement
$cmax :: Placement -> Placement -> Placement
>= :: Placement -> Placement -> Bool
$c>= :: Placement -> Placement -> Bool
> :: Placement -> Placement -> Bool
$c> :: Placement -> Placement -> Bool
<= :: Placement -> Placement -> Bool
$c<= :: Placement -> Placement -> Bool
< :: Placement -> Placement -> Bool
$c< :: Placement -> Placement -> Bool
compare :: Placement -> Placement -> Ordering
$ccompare :: Placement -> Placement -> Ordering
Ord)
  -- In the future the axis position may be replaced by a reader-like
  -- anchor system where you can choose parts of the rendered axis as a
  -- position.
  -- we keep posGap and posGapDir as separate values to keep lens laws
  -- for 0 gaps
  -- I'm not sure this should work for a 3D axis

class HasPlacement a where
  placement :: Lens' a Placement

  -- | The position relative to the axis. @V2 0 0@ corresponds to the
  --   bottom left corner, @V2 1 1@ is the top right corner.
  placementAt :: Lens' a (V2 Rational)
  placementAt = (Placement -> f Placement) -> a -> f a
forall a. HasPlacement a => Lens' a Placement
placement ((Placement -> f Placement) -> a -> f a)
-> ((V2 Rational -> f (V2 Rational)) -> Placement -> f Placement)
-> (V2 Rational -> f (V2 Rational))
-> a
-> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Placement -> V2 Rational)
-> (Placement -> V2 Rational -> Placement)
-> Lens Placement Placement (V2 Rational) (V2 Rational)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Placement -> V2 Rational
pAt (\Placement
p V2 Rational
a -> Placement
p {pAt :: V2 Rational
pAt = V2 Rational
a})

  -- | The anchor used for the object being positioned. @V2 0 0@
  --   corresponds to the bottom left corner, @V2 1 1@ is the top right
  --   corner.
  placementAnchor :: Lens' a (V2 Rational)
  placementAnchor = (Placement -> f Placement) -> a -> f a
forall a. HasPlacement a => Lens' a Placement
placement ((Placement -> f Placement) -> a -> f a)
-> ((V2 Rational -> f (V2 Rational)) -> Placement -> f Placement)
-> (V2 Rational -> f (V2 Rational))
-> a
-> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Placement -> V2 Rational)
-> (Placement -> V2 Rational -> Placement)
-> Lens Placement Placement (V2 Rational) (V2 Rational)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Placement -> V2 Rational
pAnchor (\Placement
p V2 Rational
a -> Placement
p {pAnchor :: V2 Rational
pAnchor = V2 Rational
a})

  -- | The direction to extend the 'gap' when positioning.
  gapDirection :: Lens' a (Direction V2 Rational)
  gapDirection = (Placement -> f Placement) -> a -> f a
forall a. HasPlacement a => Lens' a Placement
placement ((Placement -> f Placement) -> a -> f a)
-> ((Direction V2 Rational -> f (Direction V2 Rational))
    -> Placement -> f Placement)
-> (Direction V2 Rational -> f (Direction V2 Rational))
-> a
-> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Placement -> Direction V2 Rational)
-> (Placement -> Direction V2 Rational -> Placement)
-> Lens
     Placement Placement (Direction V2 Rational) (Direction V2 Rational)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Placement -> Direction V2 Rational
pGapDir (\Placement
p Direction V2 Rational
a -> Placement
p {pGapDir :: Direction V2 Rational
pGapDir = Direction V2 Rational
a})

instance HasPlacement Placement where
  placement :: Lens' Placement Placement
placement = (Placement -> f Placement) -> Placement -> f Placement
forall a. a -> a
id

-- Inside positions ----------------------------------------------------

-- Internal helper for all inside placements
pInside :: V2 Rational -> Placement
pInside :: V2 Rational -> Placement
pInside V2 Rational
v = Placement
  { pAt :: V2 Rational
pAt     = V2 Rational
v
  , pAnchor :: V2 Rational
pAnchor = V2 Rational
v
  , pGapDir :: Direction V2 Rational
pGapDir = Point V2 Rational -> Point V2 Rational -> Direction V2 Rational
forall (v :: * -> *) n.
(Additive v, Num n) =>
Point v n -> Point v n -> Direction v n
dirBetween' (V2 Rational -> Point V2 Rational
forall (f :: * -> *) a. f a -> Point f a
P V2 Rational
v) Point V2 Rational
forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin
  }

-- | @dirBetween p q@ returns the directions from @p@ to @q@
dirBetween' :: (Additive v, Num n) => Point v n -> Point v n -> Direction v n
dirBetween' :: forall (v :: * -> *) n.
(Additive v, Num n) =>
Point v n -> Point v n -> Direction v n
dirBetween' Point v n
p Point v n
q = v n -> Direction v n
forall (v :: * -> *) n. v n -> Direction v n
direction (v n -> Direction v n) -> v n -> Direction v n
forall a b. (a -> b) -> a -> b
$ Point v n
q Point v n -> Point v n -> Diff (Point v) n
forall (p :: * -> *) a. (Affine p, Num a) => p a -> p a -> Diff p a
.-. Point v n
p


topLeft, top, topRight, left, right, bottomLeft, bottom, bottomRight :: Placement
topLeft :: Placement
topLeft     = V2 Rational -> Placement
pInside (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1)   Rational
1 )
top :: Placement
top         = V2 Rational -> Placement
pInside (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
0    Rational
1 )
topRight :: Placement
topRight    = V2 Rational -> Placement
pInside (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
1    Rational
1 )
left :: Placement
left        = V2 Rational -> Placement
pInside (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1)   Rational
0 )
right :: Placement
right       = V2 Rational -> Placement
pInside (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1)   Rational
0 )
bottomLeft :: Placement
bottomLeft  = V2 Rational -> Placement
pInside (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1) (-Rational
1))
bottom :: Placement
bottom      = V2 Rational -> Placement
pInside (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
0  (-Rational
1))
bottomRight :: Placement
bottomRight = V2 Rational -> Placement
pInside (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
1  (-Rational
1))

-- Outside positions ---------------------------------------------------

leftAbove, leftTop, leftMid, leftBottom, leftBelow, midAbove, midBelow,
  rightAbove, rightTop, rightMid, rightBottom, rightBelow :: Placement

leftAbove :: Placement
leftAbove   = V2 Rational -> V2 Rational -> Direction V2 Rational -> Placement
Placement (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1)   Rational
1 ) (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1) (-Rational
1)) (V2 Rational -> Direction V2 Rational
forall (v :: * -> *) n. v n -> Direction v n
direction (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
0    Rational
1 ))
leftTop :: Placement
leftTop     = V2 Rational -> V2 Rational -> Direction V2 Rational -> Placement
Placement (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1)   Rational
1 ) (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
1    Rational
1 ) (V2 Rational -> Direction V2 Rational
forall (v :: * -> *) n. v n -> Direction v n
direction (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1)   Rational
0 ))
leftMid :: Placement
leftMid     = V2 Rational -> V2 Rational -> Direction V2 Rational -> Placement
Placement (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1)   Rational
0 ) (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
1    Rational
0 ) (V2 Rational -> Direction V2 Rational
forall (v :: * -> *) n. v n -> Direction v n
direction (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1)   Rational
0 ))
leftBottom :: Placement
leftBottom  = V2 Rational -> V2 Rational -> Direction V2 Rational -> Placement
Placement (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1) (-Rational
1)) (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
1  (-Rational
1)) (V2 Rational -> Direction V2 Rational
forall (v :: * -> *) n. v n -> Direction v n
direction (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1)   Rational
0 ))
leftBelow :: Placement
leftBelow   = V2 Rational -> V2 Rational -> Direction V2 Rational -> Placement
Placement (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1) (-Rational
1)) (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1)   Rational
1 ) (V2 Rational -> Direction V2 Rational
forall (v :: * -> *) n. v n -> Direction v n
direction (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
0  (-Rational
1)))

midAbove :: Placement
midAbove    = V2 Rational -> V2 Rational -> Direction V2 Rational -> Placement
Placement (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
0    Rational
1 ) (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
0  (-Rational
1)) (V2 Rational -> Direction V2 Rational
forall (v :: * -> *) n. v n -> Direction v n
direction (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
0    Rational
1 ))
midBelow :: Placement
midBelow    = V2 Rational -> V2 Rational -> Direction V2 Rational -> Placement
Placement (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
0  (-Rational
1)) (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
0    Rational
1 ) (V2 Rational -> Direction V2 Rational
forall (v :: * -> *) n. v n -> Direction v n
direction (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
0  (-Rational
1)))

rightAbove :: Placement
rightAbove  = V2 Rational -> V2 Rational -> Direction V2 Rational -> Placement
Placement (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
1    Rational
1 ) (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
1  (-Rational
1)) (V2 Rational -> Direction V2 Rational
forall (v :: * -> *) n. v n -> Direction v n
direction (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
0    Rational
1 ))
rightTop :: Placement
rightTop    = V2 Rational -> V2 Rational -> Direction V2 Rational -> Placement
Placement (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
1    Rational
1 ) (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1)   Rational
1 ) (V2 Rational -> Direction V2 Rational
forall (v :: * -> *) n. v n -> Direction v n
direction (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
1    Rational
0 ))
rightMid :: Placement
rightMid    = V2 Rational -> V2 Rational -> Direction V2 Rational -> Placement
Placement (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
1    Rational
0 ) (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1)   Rational
0 ) (V2 Rational -> Direction V2 Rational
forall (v :: * -> *) n. v n -> Direction v n
direction (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
1    Rational
0 ))
rightBottom :: Placement
rightBottom = V2 Rational -> V2 Rational -> Direction V2 Rational -> Placement
Placement (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
1  (-Rational
1)) (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2 (-Rational
1) (-Rational
1)) (V2 Rational -> Direction V2 Rational
forall (v :: * -> *) n. v n -> Direction v n
direction (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
1    Rational
0 ))
rightBelow :: Placement
rightBelow  = V2 Rational -> V2 Rational -> Direction V2 Rational -> Placement
Placement (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
1  (-Rational
1)) (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
1    Rational
1 ) (V2 Rational -> Direction V2 Rational
forall (v :: * -> *) n. v n -> Direction v n
direction (Rational -> Rational -> V2 Rational
forall a. a -> a -> V2 a
V2   Rational
0  (-Rational
1)))

-- Using positions -----------------------------------------------------

-- | A tool for aligned one object to another. Positions @b@ around the
--   bounding box of @a@ by translating @b@.
placeAgainst
  :: (InSpace V2 n a, SameSpace a b, Enveloped a,
      HasOrigin b, Alignable b)
  => a -> Placement -> n -> b -> b
placeAgainst :: forall n a b.
(InSpace V2 n a, SameSpace a b, Enveloped a, HasOrigin b,
 Alignable b) =>
a -> Placement -> n -> b -> b
placeAgainst a
a (Placement (V2 Rational
px Rational
py) (V2 Rational
ax Rational
ay) Direction V2 Rational
d) n
n b
b
  = b
b b -> (b -> b) -> b
forall a b. a -> (a -> b) -> b
# b -> b
anchor
      # moveTo (pos .+^ n *^ fromDirection (fmap fromRational d))
  where
    pos :: Point V2 n
pos    = n -> n -> Point V2 n
forall n. n -> n -> P2 n
mkP2 (Rational -> n -> n -> n
forall {a}. Fractional a => Rational -> a -> a -> a
lerp' Rational
px n
xu n
xl) (Rational -> n -> n -> n
forall {a}. Fractional a => Rational -> a -> a -> a
lerp' Rational
py n
yu n
yl)
    anchor :: b -> b
anchor = V2 n -> n -> b -> b
forall a (v :: * -> *) n.
(Alignable a, InSpace v n a, Fractional n, HasOrigin a) =>
v n -> n -> a -> a
alignBy V2 n
forall (v :: * -> *) n. (R1 v, Additive v, Num n) => v n
unitX (Rational -> n
forall a. Fractional a => Rational -> a
fromRational Rational
ax) (b -> b) -> (b -> b) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. V2 n -> n -> b -> b
forall a (v :: * -> *) n.
(Alignable a, InSpace v n a, Fractional n, HasOrigin a) =>
v n -> n -> a -> a
alignBy V2 n
forall (v :: * -> *) n. (R2 v, Additive v, Num n) => v n
unitY (Rational -> n
forall a. Fractional a => Rational -> a
fromRational Rational
ay)
    (P (V2 n
xl n
yl), P (V2 n
xu n
yu)) = (Point V2 n, Point V2 n)
-> Maybe (Point V2 n, Point V2 n) -> (Point V2 n, Point V2 n)
forall a. a -> Maybe a -> a
fromMaybe (Point V2 n
forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin, Point V2 n
forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin) (BoundingBox V2 n -> Maybe (Point V2 n, Point V2 n)
forall (v :: * -> *) n.
BoundingBox v n -> Maybe (Point v n, Point v n)
getCorners (BoundingBox V2 n -> Maybe (Point V2 n, Point V2 n))
-> BoundingBox V2 n -> Maybe (Point V2 n, Point V2 n)
forall a b. (a -> b) -> a -> b
$ a -> BoundingBox V2 n
forall (v :: * -> *) n a.
(InSpace v n a, HasBasis v, Enveloped a) =>
a -> BoundingBox v n
boundingBox a
a)

    lerp' :: Rational -> a -> a -> a
lerp' Rational
z a
u a
v = Rational -> a
forall a. Fractional a => Rational -> a
fromRational Rational
alpha a -> a -> a
forall a. Num a => a -> a -> a
* a
u a -> a -> a
forall a. Num a => a -> a -> a
+ (a
1 a -> a -> a
forall a. Num a => a -> a -> a
- Rational -> a
forall a. Fractional a => Rational -> a
fromRational Rational
alpha) a -> a -> a
forall a. Num a => a -> a -> a
* a
v
      where alpha :: Rational
alpha = (Rational
z Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
+ Rational
1) Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
2

------------------------------------------------------------------------
-- Legend entries
------------------------------------------------------------------------

-- | Type allowing use of the default legend picture (depending on the
--   plot) or a custom legend picture with access to the 'PlotStyle'.
data LegendPic b v n
  = DefaultLegendPic
  | CustomLegendPic (PlotStyle b v n -> QDiagram b v n Any)

instance Default (LegendPic b v n) where
  def :: LegendPic b v n
def = LegendPic b v n
forall b (v :: * -> *) n. LegendPic b v n
DefaultLegendPic

-- | Data type for holding a legend entry.
data LegendEntry b v n = LegendEntry
  { forall b (v :: * -> *) n. LegendEntry b v n -> LegendPic b v n
lPic        :: LegendPic b v n
  , forall b (v :: * -> *) n. LegendEntry b v n -> String
lText       :: String
  , forall b (v :: * -> *) n. LegendEntry b v n -> n
lPrecedence :: n
  } deriving Typeable

-- | The picture used in the legend entry.
legendPicture :: Lens' (LegendEntry b v n) (LegendPic b v n)
legendPicture :: forall b (v :: * -> *) n.
Lens' (LegendEntry b v n) (LegendPic b v n)
legendPicture = (LegendEntry b v n -> LegendPic b v n)
-> (LegendEntry b v n -> LegendPic b v n -> LegendEntry b v n)
-> Lens
     (LegendEntry b v n)
     (LegendEntry b v n)
     (LegendPic b v n)
     (LegendPic b v n)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens LegendEntry b v n -> LegendPic b v n
forall b (v :: * -> *) n. LegendEntry b v n -> LegendPic b v n
lPic (\LegendEntry b v n
l LegendPic b v n
pic -> LegendEntry b v n
l {lPic :: LegendPic b v n
lPic = LegendPic b v n
pic})

-- | The text used in the legend entry.
legendText :: Lens' (LegendEntry b v n) String
legendText :: forall b (v :: * -> *) n. Lens' (LegendEntry b v n) String
legendText = (LegendEntry b v n -> String)
-> (LegendEntry b v n -> String -> LegendEntry b v n)
-> Lens (LegendEntry b v n) (LegendEntry b v n) String String
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens LegendEntry b v n -> String
forall b (v :: * -> *) n. LegendEntry b v n -> String
lText (\LegendEntry b v n
l String
txt -> LegendEntry b v n
l {lText :: String
lText = String
txt})

-- | The order in which the legend entries are rendered. If precedences
--   are equal, the entries are put in the order they are added to the
--   axis.
--
--   Default is @0@.
legendPrecedence :: Lens' (LegendEntry b v n) n
legendPrecedence :: forall b (v :: * -> *) n. Lens' (LegendEntry b v n) n
legendPrecedence = (LegendEntry b v n -> n)
-> (LegendEntry b v n -> n -> LegendEntry b v n)
-> Lens (LegendEntry b v n) (LegendEntry b v n) n n
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens LegendEntry b v n -> n
forall b (v :: * -> *) n. LegendEntry b v n -> n
lPrecedence (\LegendEntry b v n
l n
n -> LegendEntry b v n
l {lPrecedence :: n
lPrecedence = n
n})

type instance V (LegendEntry b v n) = v
type instance N (LegendEntry b v n) = n

-- | Make a legend entry with a default 'legendPicture' and
--   'legendPrecedence' 0 using the string as the 'legendText'.
mkLegendEntry :: Num n => String -> LegendEntry b v n
mkLegendEntry :: forall n b (v :: * -> *). Num n => String -> LegendEntry b v n
mkLegendEntry String
x = LegendPic b v n -> String -> n -> LegendEntry b v n
forall b (v :: * -> *) n.
LegendPic b v n -> String -> n -> LegendEntry b v n
LegendEntry LegendPic b v n
forall b (v :: * -> *) n. LegendPic b v n
DefaultLegendPic String
x n
0

------------------------------------------------------------------------
-- Plot attributes
------------------------------------------------------------------------

-- Generic Plot info

-- | Data type for holding information all plots must contain.
data PlotOptions b v n = PlotOptions
  { forall b (v :: * -> *) n. PlotOptions b v n -> Name
poName      :: Name
  , forall b (v :: * -> *) n. PlotOptions b v n -> Bool
poClipPlot  :: Bool
  , forall b (v :: * -> *) n. PlotOptions b v n -> [LegendEntry b v n]
poLegend    :: [LegendEntry b v n]
  , forall b (v :: * -> *) n. PlotOptions b v n -> Bool
poVisible   :: Bool
  , forall b (v :: * -> *) n. PlotOptions b v n -> Transformation v n
poTransform :: Transformation v n
  -- , poPostPlotBoundingBox :: BoundingBox v n -> BoundingBox v n
  -- , poPlotPostProduction  :: QDiagram b v n Any -> QDiagram b v n Any
  } deriving Typeable

type instance V (PlotOptions b v n) = v
type instance N (PlotOptions b v n) = n

-- | Class of things that have 'PlotOptions'.
class HasPlotOptions f a b | a -> b where
  {-# MINIMAL plotOptions #-}
  -- | Lens onto the 'PlotOptions'.
  plotOptions :: LensLike' f a (PlotOptions b (V a) (N a))

  -- | The 'Name' applied to the plot. This gives a way to reference a
  --   specific plot in a rendered axis.
  --
  --   'Default' is 'mempty'.
  plotName :: Functor f => LensLike' f a Name
  plotName = LensLike' f a (PlotOptions b (V a) (N a))
forall (f :: * -> *) a b.
HasPlotOptions f a b =>
LensLike' f a (PlotOptions b (V a) (N a))
plotOptions LensLike' f a (PlotOptions b (V a) (N a))
-> ((Name -> f Name)
    -> PlotOptions b (V a) (N a) -> f (PlotOptions b (V a) (N a)))
-> LensLike' f a Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PlotOptions b (V a) (N a) -> Name)
-> (PlotOptions b (V a) (N a) -> Name -> PlotOptions b (V a) (N a))
-> Lens
     (PlotOptions b (V a) (N a)) (PlotOptions b (V a) (N a)) Name Name
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens PlotOptions b (V a) (N a) -> Name
forall b (v :: * -> *) n. PlotOptions b v n -> Name
poName (\PlotOptions b (V a) (N a)
g Name
a -> PlotOptions b (V a) (N a)
g {poName :: Name
poName = Name
a})
  {-# INLINE plotName #-}

  -- | Whether the plot should be clipped to the bounds of the axes.
  --
  --   'Default' is 'True'.
  clipPlot :: Functor f => LensLike' f a Bool
  clipPlot = LensLike' f a (PlotOptions b (V a) (N a))
forall (f :: * -> *) a b.
HasPlotOptions f a b =>
LensLike' f a (PlotOptions b (V a) (N a))
plotOptions LensLike' f a (PlotOptions b (V a) (N a))
-> ((Bool -> f Bool)
    -> PlotOptions b (V a) (N a) -> f (PlotOptions b (V a) (N a)))
-> LensLike' f a Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PlotOptions b (V a) (N a) -> Bool)
-> (PlotOptions b (V a) (N a) -> Bool -> PlotOptions b (V a) (N a))
-> Lens
     (PlotOptions b (V a) (N a)) (PlotOptions b (V a) (N a)) Bool Bool
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens PlotOptions b (V a) (N a) -> Bool
forall b (v :: * -> *) n. PlotOptions b v n -> Bool
poClipPlot (\PlotOptions b (V a) (N a)
g Bool
a -> PlotOptions b (V a) (N a)
g {poClipPlot :: Bool
poClipPlot = Bool
a})
  {-# INLINE clipPlot #-}

  -- | The legend entries to be used for the current plot.
  --
  --   'Default' is 'mempty'.
  legendEntries :: Functor f => LensLike' f a [LegendEntry b (V a) (N a)]
  legendEntries = LensLike' f a (PlotOptions b (V a) (N a))
forall (f :: * -> *) a b.
HasPlotOptions f a b =>
LensLike' f a (PlotOptions b (V a) (N a))
plotOptions LensLike' f a (PlotOptions b (V a) (N a))
-> (([LegendEntry b (V a) (N a)] -> f [LegendEntry b (V a) (N a)])
    -> PlotOptions b (V a) (N a) -> f (PlotOptions b (V a) (N a)))
-> LensLike' f a [LegendEntry b (V a) (N a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PlotOptions b (V a) (N a) -> [LegendEntry b (V a) (N a)])
-> (PlotOptions b (V a) (N a)
    -> [LegendEntry b (V a) (N a)] -> PlotOptions b (V a) (N a))
-> Lens
     (PlotOptions b (V a) (N a))
     (PlotOptions b (V a) (N a))
     [LegendEntry b (V a) (N a)]
     [LegendEntry b (V a) (N a)]
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens PlotOptions b (V a) (N a) -> [LegendEntry b (V a) (N a)]
forall b (v :: * -> *) n. PlotOptions b v n -> [LegendEntry b v n]
poLegend (\PlotOptions b (V a) (N a)
g [LegendEntry b (V a) (N a)]
a -> PlotOptions b (V a) (N a)
g {poLegend :: [LegendEntry b (V a) (N a)]
poLegend = [LegendEntry b (V a) (N a)]
a})
  {-# INLINE legendEntries #-}

  -- | The transform applied to the plot once it's in the axis
  --   coordinates.
  --
  --   'Default' is 'mempty'.
  plotTransform :: Functor f => LensLike' f a (Transformation (V a) (N a))
  plotTransform = LensLike' f a (PlotOptions b (V a) (N a))
forall (f :: * -> *) a b.
HasPlotOptions f a b =>
LensLike' f a (PlotOptions b (V a) (N a))
plotOptions LensLike' f a (PlotOptions b (V a) (N a))
-> ((Transformation (V a) (N a) -> f (Transformation (V a) (N a)))
    -> PlotOptions b (V a) (N a) -> f (PlotOptions b (V a) (N a)))
-> LensLike' f a (Transformation (V a) (N a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PlotOptions b (V a) (N a) -> Transformation (V a) (N a))
-> (PlotOptions b (V a) (N a)
    -> Transformation (V a) (N a) -> PlotOptions b (V a) (N a))
-> Lens
     (PlotOptions b (V a) (N a))
     (PlotOptions b (V a) (N a))
     (Transformation (V a) (N a))
     (Transformation (V a) (N a))
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens PlotOptions b (V a) (N a) -> Transformation (V a) (N a)
forall b (v :: * -> *) n. PlotOptions b v n -> Transformation v n
poTransform (\PlotOptions b (V a) (N a)
g Transformation (V a) (N a)
a -> PlotOptions b (V a) (N a)
g {poTransform :: Transformation (V a) (N a)
poTransform = Transformation (V a) (N a)
a})
  {-# INLINE plotTransform #-}

  -- | Whether or not the plot should be shown. The 'BoundingBox' of the
  --   plot will still affect the inferred axis bounds.
  --
  --   'Default' is 'True'.
  plotVisible :: Functor f => LensLike' f a Bool
  plotVisible = LensLike' f a (PlotOptions b (V a) (N a))
forall (f :: * -> *) a b.
HasPlotOptions f a b =>
LensLike' f a (PlotOptions b (V a) (N a))
plotOptions LensLike' f a (PlotOptions b (V a) (N a))
-> ((Bool -> f Bool)
    -> PlotOptions b (V a) (N a) -> f (PlotOptions b (V a) (N a)))
-> LensLike' f a Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PlotOptions b (V a) (N a) -> Bool)
-> (PlotOptions b (V a) (N a) -> Bool -> PlotOptions b (V a) (N a))
-> Lens
     (PlotOptions b (V a) (N a)) (PlotOptions b (V a) (N a)) Bool Bool
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens PlotOptions b (V a) (N a) -> Bool
forall b (v :: * -> *) n. PlotOptions b v n -> Bool
poVisible (\PlotOptions b (V a) (N a)
po Bool
b -> PlotOptions b (V a) (N a)
po {poVisible :: Bool
poVisible = Bool
b})
  {-# INLINE plotVisible #-}

instance (Additive v, Num n) => Default (PlotOptions b v n) where
  def :: PlotOptions b v n
def = PlotOptions
    { poName :: Name
poName                = Name
forall a. Monoid a => a
mempty
    , poClipPlot :: Bool
poClipPlot            = Bool
True
    , poLegend :: [LegendEntry b v n]
poLegend              = []
    , poVisible :: Bool
poVisible             = Bool
True
    , poTransform :: Transformation v n
poTransform           = Transformation v n
forall a. Monoid a => a
mempty
    -- , poPostPlotBoundingBox = id
    -- , poPlotPostProduction  = id
    }

instance HasPlotOptions f (PlotOptions b v n) b where
  plotOptions :: LensLike'
  f
  (PlotOptions b v n)
  (PlotOptions b (V (PlotOptions b v n)) (N (PlotOptions b v n)))
plotOptions = LensLike'
  f
  (PlotOptions b v n)
  (PlotOptions b (V (PlotOptions b v n)) (N (PlotOptions b v n)))
forall a. a -> a
id
  {-# INLINE plotOptions #-}

instance (HasLinearMap v, Num n) => Transformable (PlotOptions b v n) where
  transform :: Transformation (V (PlotOptions b v n)) (N (PlotOptions b v n))
-> PlotOptions b v n -> PlotOptions b v n
transform = ASetter
  (PlotOptions b v n)
  (PlotOptions b v n)
  (Transformation v n)
  (Transformation v n)
-> (Transformation v n -> Transformation v n)
-> PlotOptions b v n
-> PlotOptions b v n
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter
  (PlotOptions b v n)
  (PlotOptions b v n)
  (Transformation v n)
  (Transformation v n)
forall (f :: * -> *) a b.
(HasPlotOptions f a b, Functor f) =>
LensLike' f a (Transformation (V a) (N a))
plotTransform ((Transformation v n -> Transformation v n)
 -> PlotOptions b v n -> PlotOptions b v n)
-> (Transformation v n -> Transformation v n -> Transformation v n)
-> Transformation v n
-> PlotOptions b v n
-> PlotOptions b v n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transformation v n -> Transformation v n -> Transformation v n
forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform

-- instance HasBounds (PlotOptions b v n) v where
--   bounds = plotBounds

-- | Move origin by applying to @plotTransform@.
instance (Additive v, Num n) => HasOrigin (PlotOptions b v n) where
  moveOriginTo :: Point (V (PlotOptions b v n)) (N (PlotOptions b v n))
-> PlotOptions b v n -> PlotOptions b v n
moveOriginTo = ASetter
  (PlotOptions b v n)
  (PlotOptions b v n)
  (Transformation v n)
  (Transformation v n)
-> (Transformation v n -> Transformation v n)
-> PlotOptions b v n
-> PlotOptions b v n
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter
  (PlotOptions b v n)
  (PlotOptions b v n)
  (Transformation v n)
  (Transformation v n)
forall (f :: * -> *) a b.
(HasPlotOptions f a b, Functor f) =>
LensLike' f a (Transformation (V a) (N a))
plotTransform ((Transformation v n -> Transformation v n)
 -> PlotOptions b v n -> PlotOptions b v n)
-> (Point v n -> Transformation v n -> Transformation v n)
-> Point v n
-> PlotOptions b v n
-> PlotOptions b v n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Point v n -> Transformation v n -> Transformation v n
forall t. HasOrigin t => Point (V t) (N t) -> t -> t
moveOriginTo

instance Qualifiable (PlotOptions b v n) where
  a
n .>> :: forall a. IsName a => a -> PlotOptions b v n -> PlotOptions b v n
.>> PlotOptions b v n
p = ASetter (PlotOptions b v n) (PlotOptions b v n) Name Name
-> (Name -> Name) -> PlotOptions b v n -> PlotOptions b v n
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter (PlotOptions b v n) (PlotOptions b v n) Name Name
forall (f :: * -> *) a b.
(HasPlotOptions f a b, Functor f) =>
LensLike' f a Name
plotName (a
n a -> Name -> Name
forall q a. (Qualifiable q, IsName a) => a -> q -> q
.>>) PlotOptions b v n
p

-- XXX template haskell getting in the way
-- instance HasVisibility (PlotOptions b v n) where
--   visible = plotVisible

-- | Add a 'LegendEntry' to something with 'PlotOptions' using the
--   'String' as the 'legendText' and a 'DefaultLegendPic'. Here are
--   some typical examples:
--
-- @
-- 'key' :: 'String' -> 'State' ('Plot' ('ScatterPlot' v n) b) ()
-- 'key' :: 'String' -> 'State' ('DynamicPlot' b v n) ()
-- 'key' :: 'String' -> 'State' ('PlotMods' b v n) ()
-- @
--
--  If you only care about the name of the legend, use 'key'.
key :: (HasPlotOptions Identity a b, MonadState a m, Num (N a)) => String -> m ()
key :: forall a b (m :: * -> *).
(HasPlotOptions Identity a b, MonadState a m, Num (N a)) =>
String -> m ()
key = LegendEntry b (V a) (N a) -> m ()
forall a b (m :: * -> *).
(HasPlotOptions Identity a b, MonadState a m) =>
LegendEntry b (V a) (N a) -> m ()
addLegendEntry (LegendEntry b (V a) (N a) -> m ())
-> (String -> LegendEntry b (V a) (N a)) -> String -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> LegendEntry b (V a) (N a)
forall n b (v :: * -> *). Num n => String -> LegendEntry b v n
mkLegendEntry

-- | Add a 'LegendEntry' to something with 'PlotOptions'. Here are some
--   typical examples:
--
-- @
-- 'addLegendEntry' :: 'LegendEntry' b v n -> 'State' ('Plot' ('ScatterPlot' v n) b) ()
-- 'addLegendEntry' :: 'LegendEntry' b v n -> 'State' ('DynamicPlot' b v n) ()
-- @
--
--  If you only care about the name of the legend, use 'key'.
addLegendEntry
  :: (HasPlotOptions Identity a b, MonadState a m)
  => LegendEntry b (V a) (N a)
  -> m ()
addLegendEntry :: forall a b (m :: * -> *).
(HasPlotOptions Identity a b, MonadState a m) =>
LegendEntry b (V a) (N a) -> m ()
addLegendEntry LegendEntry b (V a) (N a)
l = LensLike' Identity a [LegendEntry b (V a) (N a)]
forall (f :: * -> *) a b.
(HasPlotOptions f a b, Functor f) =>
LensLike' f a [LegendEntry b (V a) (N a)]
legendEntries LensLike' Identity a [LegendEntry b (V a) (N a)]
-> [LegendEntry b (V a) (N a)] -> m ()
forall s (m :: * -> *) a.
(MonadState s m, Semigroup a) =>
ASetter' s a -> a -> m ()
<>= [LegendEntry b (V a) (N a)
l]

-- zeroInt :: Additive v => v Int
-- zeroInt = zero

------------------------------------------------------------------------
-- AxisSpec
------------------------------------------------------------------------

-- | Information from the 'Plots.Axis.Axis' necessary to render a 'Plotable'.
data AxisSpec v n = AxisSpec
  { forall (v :: * -> *) n. AxisSpec v n -> v (n, n)
_specBounds    :: v (n, n)
  , forall (v :: * -> *) n. AxisSpec v n -> Transformation v n
_specTrans     :: Transformation v n
  , forall (v :: * -> *) n. AxisSpec v n -> v LogScale
_specScale     :: v LogScale
  , forall (v :: * -> *) n. AxisSpec v n -> ColourMap
_specColourMap :: ColourMap
  }

makeLenses ''AxisSpec

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

-- | Scale a number by log10-ing it and linearly scaling it so it's
--   within the same range.
scaleNum :: Floating n => (n, n) -> LogScale -> n -> n
scaleNum :: forall n. Floating n => (n, n) -> LogScale -> n -> n
scaleNum (n
a,n
b) LogScale
s n
x = case LogScale
s of
  LogScale
LinearAxis -> n
x
  LogScale
LogAxis    -> n -> n -> n
forall a. Num a => a -> a -> a
subtract n
a (n -> n) -> n -> n
forall a b. (a -> b) -> a -> b
$ (n
b n -> n -> n
forall a. Fractional a => a -> a -> a
/ n -> n -> n
forall a. Floating a => a -> a -> a
logBase n
10 n
d) n -> n -> n
forall a. Num a => a -> a -> a
* (n -> n -> n
forall a. Floating a => a -> a -> a
logBase n
10 n
x)
    where d :: n
d = n
b n -> n -> n
forall a. Num a => a -> a -> a
- n
a

-- | Apply log scaling and the transform to a point.
specPoint :: (Applicative v, Additive v, Floating n) => AxisSpec v n -> Point v n -> Point v n
specPoint :: forall (v :: * -> *) n.
(Applicative v, Additive v, Floating n) =>
AxisSpec v n -> Point v n -> Point v n
specPoint (AxisSpec v (n, n)
bs Transformation v n
tr v LogScale
ss ColourMap
_) Point v n
p =
  Transformation v n -> Point v n -> Point v n
forall (v :: * -> *) n.
(Additive v, Num n) =>
Transformation v n -> Point v n -> Point v n
papply Transformation v n
tr (Point v n -> Point v n) -> Point v n -> Point v n
forall a b. (a -> b) -> a -> b
$ ASetter (Point v n) (Point v n) (v n) (v n)
-> (v n -> v n) -> Point v n -> Point v n
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter (Point v n) (Point v n) (v n) (v n)
forall (f :: * -> *) a. Iso' (Point f a) (f a)
_Point ((n, n) -> LogScale -> n -> n
forall n. Floating n => (n, n) -> LogScale -> n -> n
scaleNum ((n, n) -> LogScale -> n -> n)
-> v (n, n) -> v (LogScale -> n -> n)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> v (n, n)
bs v (LogScale -> n -> n) -> v LogScale -> v (n -> n)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> v LogScale
ss v (n -> n) -> v n -> v n
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>) Point v n
p

------------------------------------------------------------------------
-- Plotable class
------------------------------------------------------------------------

-- | Class defining how plots should be rendered.
class (Typeable p, Enveloped p) => Plotable p b where
  -- | Render a plot according to the 'AxisSpec', using the 'PlotStyle'.
  renderPlotable
    :: InSpace v n p
    => AxisSpec v n
    -> PlotStyle b v n
    -> p
    -> QDiagram b v n Any

  -- | The default legend picture when the 'LegendPic' is
  --   'DefaultLegendPic'.
  defLegendPic
    :: InSpace v n p
    => PlotStyle b v n
    -> p
    -> QDiagram b v n Any
  defLegendPic = PlotStyle b v n -> p -> QDiagram b v n Any
forall a. Monoid a => a
mempty

instance (Typeable b, Typeable v, Metric v, Typeable n, OrderedField n)
  => Plotable (QDiagram b v n Any) b where
  renderPlotable :: forall (v :: * -> *) n.
InSpace v n (QDiagram b v n Any) =>
AxisSpec v n
-> PlotStyle b v n -> QDiagram b v n Any -> QDiagram b v n Any
renderPlotable AxisSpec v n
s PlotStyle b v n
_ QDiagram b v n Any
dia = QDiagram b v n Any
dia QDiagram b v n Any
-> (QDiagram b v n Any -> QDiagram b v n Any) -> QDiagram b v n Any
forall a b. a -> (a -> b) -> b
# Transformation (V (QDiagram b v n Any)) (N (QDiagram b v n Any))
-> QDiagram b v n Any -> QDiagram b v n Any
forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform (AxisSpec v n
sAxisSpec v n
-> Getting (Transformation v n) (AxisSpec v n) (Transformation v n)
-> Transformation v n
forall s a. s -> Getting a s a -> a
^.Getting (Transformation v n) (AxisSpec v n) (Transformation v n)
forall (v :: * -> *) n. Lens' (AxisSpec v n) (Transformation v n)
specTrans)

instance (TypeableFloat n, Renderable (Path V2 n) b) => Plotable (Path V2 n) b where
  renderPlotable :: forall (v :: * -> *) n.
InSpace v n (Path V2 n) =>
AxisSpec v n -> PlotStyle b v n -> Path V2 n -> QDiagram b v n Any
renderPlotable AxisSpec v n
s PlotStyle b v n
sty Path V2 n
path
    = Path V2 n -> QDiagram b V2 n Any
forall n t b.
(InSpace V2 n t, ToPath t, TypeableFloat n,
 Renderable (Path V2 n) b) =>
t -> QDiagram b V2 n Any
stroke Path V2 n
path
        # transform (s^.specTrans)
        # applyLineStyle sty

  defLegendPic :: forall (v :: * -> *) n.
InSpace v n (Path V2 n) =>
PlotStyle b v n -> Path V2 n -> QDiagram b v n Any
defLegendPic PlotStyle b v n
sty Path V2 n
_
    = ((n, n) -> P2 n
forall n. (n, n) -> P2 n
p2 (-n
10,n
0) P2 n -> P2 n -> QDiagram b v n Any
forall t (v :: * -> *) n.
(V t ~ v, N t ~ n, TrailLike t) =>
Point v n -> Point v n -> t
~~ (n, n) -> P2 n
forall n. (n, n) -> P2 n
p2 (n
10,n
0))
        # applyLineStyle sty

------------------------------------------------------------------------
-- Visibility
------------------------------------------------------------------------

-- | Class of objects that can be hidden.
class HasVisibility a where
  -- | Lens onto whether an object should be visible when rendered.
  visible :: Lens' a Bool

  -- | The opposite of 'visible'.
  hidden :: Lens' a Bool
  hidden = (Bool -> f Bool) -> a -> f a
forall a. HasVisibility a => Lens' a Bool
visible ((Bool -> f Bool) -> a -> f a)
-> ((Bool -> f Bool) -> Bool -> f Bool)
-> (Bool -> f Bool)
-> a
-> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Bool) -> Iso' Bool Bool
forall a. (a -> a) -> Iso' a a
involuted Bool -> Bool
not
  {-# INLINE hidden #-}

instance HasVisibility (PlotOptions b v n) where
  visible :: Lens' (PlotOptions b v n) Bool
visible = LensLike' f (PlotOptions b v n) Bool
forall (f :: * -> *) a b.
(HasPlotOptions f a b, Functor f) =>
LensLike' f a Bool
plotVisible

instance HasVisibility (PlotMods b v n) where
  visible :: Lens' (PlotMods b v n) Bool
visible = LensLike' f (PlotMods b v n) Bool
forall (f :: * -> *) a b.
(HasPlotOptions f a b, Functor f) =>
LensLike' f a Bool
plotVisible

instance HasVisibility (Plot p b) where
  visible :: Lens' (Plot p b) Bool
visible = LensLike' f (Plot p b) Bool
forall (f :: * -> *) a b.
(HasPlotOptions f a b, Functor f) =>
LensLike' f a Bool
plotVisible

instance HasVisibility (DynamicPlot b v n) where
  visible :: Lens' (DynamicPlot b v n) Bool
visible = LensLike' f (DynamicPlot b v n) Bool
forall (f :: * -> *) a b.
(HasPlotOptions f a b, Functor f) =>
LensLike' f a Bool
plotVisible

instance HasVisibility (StyledPlot b v n) where
  visible :: Lens' (StyledPlot b v n) Bool
visible = LensLike' f (StyledPlot b v n) Bool
forall (f :: * -> *) a b.
(HasPlotOptions f a b, Functor f) =>
LensLike' f a Bool
plotVisible

-- | Set 'visible' to 'False' for the given setter.
--
-- @
-- 'hide' 'minorTicks'          :: 'State' ('Axis' b v n) ()
-- 'hide' ('xAxis' . 'gridLines') :: 'State' ('Axis' b v n) ()
-- @
hide :: (MonadState s m, HasVisibility a) => ASetter' s a -> m ()
hide :: forall s (m :: * -> *) a.
(MonadState s m, HasVisibility a) =>
ASetter' s a -> m ()
hide ASetter' s a
l = ASetter' s a
l ASetter' s a
-> ((Bool -> Identity Bool) -> a -> Identity a)
-> (Bool -> Identity Bool)
-> s
-> Identity s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Identity Bool) -> a -> Identity a
forall a. HasVisibility a => Lens' a Bool
visible ((Bool -> Identity Bool) -> s -> Identity s) -> Bool -> m ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Bool
False

-- | Set 'visible' to 'True' for the given setter.
--
-- @
-- 'display' 'minorGridLines' :: 'State' ('Axis' b v n) ()
-- 'display' 'colourBar'      :: 'State' ('Axis' b v n) ()
-- @
display :: (MonadState s m, HasVisibility a) => ASetter' s a -> m ()
display :: forall s (m :: * -> *) a.
(MonadState s m, HasVisibility a) =>
ASetter' s a -> m ()
display ASetter' s a
l = ASetter' s a
l ASetter' s a
-> ((Bool -> Identity Bool) -> a -> Identity a)
-> (Bool -> Identity Bool)
-> s
-> Identity s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Identity Bool) -> a -> Identity a
forall a. HasVisibility a => Lens' a Bool
visible ((Bool -> Identity Bool) -> s -> Identity s) -> Bool -> m ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Bool
True

------------------------------------------------------------------------
-- Plot modification
------------------------------------------------------------------------

-- | A 'PlotOptions' with modifications to a 'PlotStyle'.
data PlotMods b v n
  = PlotMods (PlotOptions b v n) (PlotStyle b v n -> PlotStyle b v n)

type instance V (PlotMods b v n) = v
type instance N (PlotMods b v n) = n

instance Functor f => HasPlotOptions f (PlotMods b v n) b where
  plotOptions :: LensLike'
  f
  (PlotMods b v n)
  (PlotOptions b (V (PlotMods b v n)) (N (PlotMods b v n)))
plotOptions PlotOptions b (V (PlotMods b v n)) (N (PlotMods b v n))
-> f (PlotOptions b (V (PlotMods b v n)) (N (PlotMods b v n)))
f (PlotMods PlotOptions b v n
opts PlotStyle b v n -> PlotStyle b v n
sty) = PlotOptions b (V (PlotMods b v n)) (N (PlotMods b v n))
-> f (PlotOptions b (V (PlotMods b v n)) (N (PlotMods b v n)))
f PlotOptions b v n
PlotOptions b (V (PlotMods b v n)) (N (PlotMods b v n))
opts f (PlotOptions b v n)
-> (PlotOptions b v n -> PlotMods b v n) -> f (PlotMods b v n)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \PlotOptions b v n
opts' -> PlotOptions b v n
-> (PlotStyle b v n -> PlotStyle b v n) -> PlotMods b v n
forall b (v :: * -> *) n.
PlotOptions b v n
-> (PlotStyle b v n -> PlotStyle b v n) -> PlotMods b v n
PlotMods PlotOptions b v n
opts' PlotStyle b v n -> PlotStyle b v n
sty

instance Settable f => HasPlotStyle f (PlotMods b v n) b where
  plotStyle :: LensLike'
  f
  (PlotMods b v n)
  (PlotStyle b (V (PlotMods b v n)) (N (PlotMods b v n)))
plotStyle = ((PlotStyle b v n -> PlotStyle b v n)
 -> f (PlotStyle b v n -> PlotStyle b v n))
-> PlotMods b v n -> f (PlotMods b v n)
forall {f :: * -> *} {b} {v :: * -> *} {n}.
Functor f =>
((PlotStyle b v n -> PlotStyle b v n)
 -> f (PlotStyle b v n -> PlotStyle b v n))
-> PlotMods b v n -> f (PlotMods b v n)
sty (((PlotStyle b v n -> PlotStyle b v n)
  -> f (PlotStyle b v n -> PlotStyle b v n))
 -> PlotMods b v n -> f (PlotMods b v n))
-> ((PlotStyle b v n -> f (PlotStyle b v n))
    -> (PlotStyle b v n -> PlotStyle b v n)
    -> f (PlotStyle b v n -> PlotStyle b v n))
-> (PlotStyle b v n -> f (PlotStyle b v n))
-> PlotMods b v n
-> f (PlotMods b v n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PlotStyle b v n -> f (PlotStyle b v n))
-> (PlotStyle b v n -> PlotStyle b v n)
-> f (PlotStyle b v n -> PlotStyle b v n)
forall (f :: * -> *) a b. Functor f => Setter (f a) (f b) a b
mapped where
    sty :: ((PlotStyle b v n -> PlotStyle b v n)
 -> f (PlotStyle b v n -> PlotStyle b v n))
-> PlotMods b v n -> f (PlotMods b v n)
sty (PlotStyle b v n -> PlotStyle b v n)
-> f (PlotStyle b v n -> PlotStyle b v n)
f (PlotMods PlotOptions b v n
opts PlotStyle b v n -> PlotStyle b v n
s) = (PlotStyle b v n -> PlotStyle b v n)
-> f (PlotStyle b v n -> PlotStyle b v n)
f PlotStyle b v n -> PlotStyle b v n
s f (PlotStyle b v n -> PlotStyle b v n)
-> ((PlotStyle b v n -> PlotStyle b v n) -> PlotMods b v n)
-> f (PlotMods b v n)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \PlotStyle b v n -> PlotStyle b v n
s' -> PlotOptions b v n
-> (PlotStyle b v n -> PlotStyle b v n) -> PlotMods b v n
forall b (v :: * -> *) n.
PlotOptions b v n
-> (PlotStyle b v n -> PlotStyle b v n) -> PlotMods b v n
PlotMods PlotOptions b v n
opts PlotStyle b v n -> PlotStyle b v n
s'

instance (Additive v, Num n) => Default (PlotMods b v n) where
  def :: PlotMods b v n
def = PlotOptions b v n
-> (PlotStyle b v n -> PlotStyle b v n) -> PlotMods b v n
forall b (v :: * -> *) n.
PlotOptions b v n
-> (PlotStyle b v n -> PlotStyle b v n) -> PlotMods b v n
PlotMods PlotOptions b v n
forall a. Default a => a
def PlotStyle b v n -> PlotStyle b v n
forall a. a -> a
id

------------------------------------------------------------------------
-- Plot type
------------------------------------------------------------------------

-- | A parameterised plot, together with a 'PlotMods'. This type has an
--   instance of many classes for modifying specific plots.
data Plot p b =
  Plot p
       (PlotOptions b (V p) (N p))
       (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
  deriving Typeable

type instance V (Plot p b) = V p
type instance N (Plot p b) = N p

instance Functor f => HasPlotOptions f (Plot p b) b where
  plotOptions :: LensLike'
  f (Plot p b) (PlotOptions b (V (Plot p b)) (N (Plot p b)))
plotOptions PlotOptions b (V (Plot p b)) (N (Plot p b))
-> f (PlotOptions b (V (Plot p b)) (N (Plot p b)))
f (Plot p
p PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
sty) = PlotOptions b (V (Plot p b)) (N (Plot p b))
-> f (PlotOptions b (V (Plot p b)) (N (Plot p b)))
f PlotOptions b (V p) (N p)
PlotOptions b (V (Plot p b)) (N (Plot p b))
opts f (PlotOptions b (V p) (N p))
-> (PlotOptions b (V p) (N p) -> Plot p b) -> f (Plot p b)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \PlotOptions b (V p) (N p)
opts' -> p
-> PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> Plot p b
forall p b.
p
-> PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> Plot p b
Plot p
p PlotOptions b (V p) (N p)
opts' PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
sty

instance Settable f => HasPlotStyle f (Plot p b) b where
  plotStyle :: LensLike' f (Plot p b) (PlotStyle b (V (Plot p b)) (N (Plot p b)))
plotStyle = ((PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
 -> f (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)))
-> Plot p b -> f (Plot p b)
forall {f :: * -> *} {b} {p}.
Functor f =>
((PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
 -> f (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)))
-> Plot p b -> f (Plot p b)
sty (((PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
  -> f (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)))
 -> Plot p b -> f (Plot p b))
-> ((PlotStyle b (V p) (N p) -> f (PlotStyle b (V p) (N p)))
    -> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
    -> f (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)))
-> (PlotStyle b (V p) (N p) -> f (PlotStyle b (V p) (N p)))
-> Plot p b
-> f (Plot p b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PlotStyle b (V p) (N p) -> f (PlotStyle b (V p) (N p)))
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> f (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
forall (f :: * -> *) a b. Functor f => Setter (f a) (f b) a b
mapped where
    sty :: ((PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
 -> f (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)))
-> Plot p b -> f (Plot p b)
sty (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> f (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
f (Plot p
p PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
s) = (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> f (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
f PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
s f (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> ((PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
    -> Plot p b)
-> f (Plot p b)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
s' -> p
-> PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> Plot p b
forall p b.
p
-> PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> Plot p b
Plot p
p PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
s'

instance HasOrientation p => HasOrientation (Plot p b) where
  orientation :: Lens' (Plot p b) Orientation
orientation = (p -> f p) -> Plot p b -> f (Plot p b)
forall p p' b. SameSpace p p' => Lens (Plot p b) (Plot p' b) p p'
rawPlot ((p -> f p) -> Plot p b -> f (Plot p b))
-> ((Orientation -> f Orientation) -> p -> f p)
-> (Orientation -> f Orientation)
-> Plot p b
-> f (Plot p b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Orientation -> f Orientation) -> p -> f p
forall a. HasOrientation a => Lens' a Orientation
orientation

-- | Make a 'Plot' with 'Default' 'PlotOptions'.
mkPlot :: (Additive (V p), Num (N p)) => p -> Plot p b
mkPlot :: forall p b. (Additive (V p), Num (N p)) => p -> Plot p b
mkPlot p
p = p
-> PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> Plot p b
forall p b.
p
-> PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> Plot p b
Plot p
p PlotOptions b (V p) (N p)
forall a. Default a => a
def PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
forall a. a -> a
id

-- | Lens onto the raw 'Plotable' inside a 'Plot'.
rawPlot :: SameSpace p p' => Lens (Plot p b) (Plot p' b) p p'
rawPlot :: forall p p' b. SameSpace p p' => Lens (Plot p b) (Plot p' b) p p'
rawPlot p -> f p'
f (Plot p
p PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
ps) = p -> f p'
f p
p f p' -> (p' -> Plot p' b) -> f (Plot p' b)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \p'
p' -> p'
-> PlotOptions b (V p') (N p')
-> (PlotStyle b (V p') (N p') -> PlotStyle b (V p') (N p'))
-> Plot p' b
forall p b.
p
-> PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> Plot p b
Plot p'
p' PlotOptions b (V p) (N p)
PlotOptions b (V p') (N p')
opts PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
PlotStyle b (V p') (N p') -> PlotStyle b (V p') (N p')
ps

-- | The modifications to the 'PlotOptions' and 'PlotStyle' in a 'Plot'.
plotMods :: Lens' (Plot p b) (PlotMods b (V p) (N p))
plotMods :: forall p b. Lens' (Plot p b) (PlotMods b (V p) (N p))
plotMods PlotMods b (V p) (N p) -> f (PlotMods b (V p) (N p))
f (Plot p
p PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
ps) =
  PlotMods b (V p) (N p) -> f (PlotMods b (V p) (N p))
f (PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> PlotMods b (V p) (N p)
forall b (v :: * -> *) n.
PlotOptions b v n
-> (PlotStyle b v n -> PlotStyle b v n) -> PlotMods b v n
PlotMods PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
ps) f (PlotMods b (V p) (N p))
-> (PlotMods b (V p) (N p) -> Plot p b) -> f (Plot p b)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \(PlotMods PlotOptions b (V p) (N p)
opts' PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
ps') -> p
-> PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> Plot p b
forall p b.
p
-> PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> Plot p b
Plot p
p PlotOptions b (V p) (N p)
opts' PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
ps'

------------------------------------------------------------------------
-- DynamicPlot
------------------------------------------------------------------------

-- | A wrapped up 'Plot', used to store plots in an 'Axis'.
data DynamicPlot b v n where
  DynamicPlot :: (InSpace v n p, Plotable p b) => Plot p b -> DynamicPlot b v n
  deriving Typeable

type instance V (DynamicPlot b v n) = v
type instance N (DynamicPlot b v n) = n

-- | Prism for a 'DynamicPlot'.
_DynamicPlot :: (Plotable p b, Typeable b) => Prism' (DynamicPlot b (V p) (N p)) (Plot p b)
_DynamicPlot :: forall p b.
(Plotable p b, Typeable b) =>
Prism' (DynamicPlot b (V p) (N p)) (Plot p b)
_DynamicPlot = (Plot p b -> DynamicPlot b (V p) (N p))
-> (DynamicPlot b (V p) (N p) -> Maybe (Plot p b))
-> Prism
     (DynamicPlot b (V p) (N p))
     (DynamicPlot b (V p) (N p))
     (Plot p b)
     (Plot p b)
forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b
prism' Plot p b -> DynamicPlot b (V p) (N p)
forall (v :: * -> *) n p b.
(InSpace v n p, Plotable p b) =>
Plot p b -> DynamicPlot b v n
DynamicPlot (\(DynamicPlot Plot p b
p) -> Plot p b -> Maybe (Plot p b)
forall a b. (Typeable a, Typeable b) => a -> Maybe b
cast Plot p b
p)

-- | Traversal over the dynamic plot without the 'Plotable' constraint
--   '_DynamicPlot' has.
dynamicPlot :: forall p b. (Typeable p, Typeable b)
            => Traversal' (DynamicPlot b (V p) (N p)) (Plot p b)
dynamicPlot :: forall p b.
(Typeable p, Typeable b) =>
Traversal' (DynamicPlot b (V p) (N p)) (Plot p b)
dynamicPlot Plot p b -> f (Plot p b)
f d :: DynamicPlot b (V p) (N p)
d@(DynamicPlot Plot p b
p) =
  case Plot p b -> Maybe (Plot p b :~: Plot p b)
forall a. Typeable a => a -> Maybe (a :~: Plot p b)
eq Plot p b
p of
    Just Plot p b :~: Plot p b
Refl -> Plot p b -> f (Plot p b)
f Plot p b
Plot p b
p f (Plot p b)
-> (Plot p b -> DynamicPlot b (V p) (N p))
-> f (DynamicPlot b (V p) (N p))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \Plot p b
p' -> Plot p b -> DynamicPlot b (V p) (N p)
forall (v :: * -> *) n p b.
(InSpace v n p, Plotable p b) =>
Plot p b -> DynamicPlot b v n
DynamicPlot Plot p b
p'
    Maybe (Plot p b :~: Plot p b)
Nothing   -> DynamicPlot b (V p) (N p) -> f (DynamicPlot b (V p) (N p))
forall (f :: * -> *) a. Applicative f => a -> f a
pure DynamicPlot b (V p) (N p)
d
  where eq :: Typeable a => a -> Maybe (a :~: Plot p b)
        eq :: forall a. Typeable a => a -> Maybe (a :~: Plot p b)
eq a
_ = Maybe (a :~: Plot p b)
forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
eqT
instance Functor f => HasPlotOptions f (DynamicPlot b v n) b where
  plotOptions :: LensLike'
  f
  (DynamicPlot b v n)
  (PlotOptions b (V (DynamicPlot b v n)) (N (DynamicPlot b v n)))
plotOptions PlotOptions b (V (DynamicPlot b v n)) (N (DynamicPlot b v n))
-> f (PlotOptions
        b (V (DynamicPlot b v n)) (N (DynamicPlot b v n)))
f (DynamicPlot (Plot p
p PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
sty)) =
    PlotOptions b (V (DynamicPlot b v n)) (N (DynamicPlot b v n))
-> f (PlotOptions
        b (V (DynamicPlot b v n)) (N (DynamicPlot b v n)))
f PlotOptions b (V p) (N p)
PlotOptions b (V (DynamicPlot b v n)) (N (DynamicPlot b v n))
opts f (PlotOptions b v n)
-> (PlotOptions b v n -> DynamicPlot b v n)
-> f (DynamicPlot b v n)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \PlotOptions b v n
opts' -> Plot p b -> DynamicPlot b v n
forall (v :: * -> *) n p b.
(InSpace v n p, Plotable p b) =>
Plot p b -> DynamicPlot b v n
DynamicPlot (p
-> PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> Plot p b
forall p b.
p
-> PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> Plot p b
Plot p
p PlotOptions b v n
PlotOptions b (V p) (N p)
opts' PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
sty)

instance Settable f => HasPlotStyle f (DynamicPlot b v n) b where
  plotStyle :: LensLike'
  f
  (DynamicPlot b v n)
  (PlotStyle b (V (DynamicPlot b v n)) (N (DynamicPlot b v n)))
plotStyle = ((PlotStyle b v n -> PlotStyle b v n)
 -> f (PlotStyle b v n -> PlotStyle b v n))
-> DynamicPlot b v n -> f (DynamicPlot b v n)
Setter' (DynamicPlot b v n) (PlotStyle b v n -> PlotStyle b v n)
sty (((PlotStyle b v n -> PlotStyle b v n)
  -> f (PlotStyle b v n -> PlotStyle b v n))
 -> DynamicPlot b v n -> f (DynamicPlot b v n))
-> ((PlotStyle b v n -> f (PlotStyle b v n))
    -> (PlotStyle b v n -> PlotStyle b v n)
    -> f (PlotStyle b v n -> PlotStyle b v n))
-> (PlotStyle b v n -> f (PlotStyle b v n))
-> DynamicPlot b v n
-> f (DynamicPlot b v n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PlotStyle b v n -> f (PlotStyle b v n))
-> (PlotStyle b v n -> PlotStyle b v n)
-> f (PlotStyle b v n -> PlotStyle b v n)
forall (f :: * -> *) a b. Functor f => Setter (f a) (f b) a b
mapped where
    sty :: Setter' (DynamicPlot b v n) (PlotStyle b v n -> PlotStyle b v n)
    sty :: Setter' (DynamicPlot b v n) (PlotStyle b v n -> PlotStyle b v n)
sty (PlotStyle b v n -> PlotStyle b v n)
-> f (PlotStyle b v n -> PlotStyle b v n)
f (DynamicPlot (Plot p
p PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
s)) = (PlotStyle b v n -> PlotStyle b v n)
-> f (PlotStyle b v n -> PlotStyle b v n)
f PlotStyle b v n -> PlotStyle b v n
PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
s f (PlotStyle b v n -> PlotStyle b v n)
-> ((PlotStyle b v n -> PlotStyle b v n) -> DynamicPlot b v n)
-> f (DynamicPlot b v n)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \PlotStyle b v n -> PlotStyle b v n
s' -> Plot p b -> DynamicPlot b v n
forall (v :: * -> *) n p b.
(InSpace v n p, Plotable p b) =>
Plot p b -> DynamicPlot b v n
DynamicPlot (p
-> PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> Plot p b
forall p b.
p
-> PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> Plot p b
Plot p
p PlotOptions b (V p) (N p)
opts PlotStyle b v n -> PlotStyle b v n
PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
s')

-- | The modifications to the 'PlotOptions' and 'PlotStyle' in a 'DynamicPlot'.
dynamicPlotMods :: Lens' (DynamicPlot b v n) (PlotMods b v n)
dynamicPlotMods :: forall b (v :: * -> *) n.
Lens' (DynamicPlot b v n) (PlotMods b v n)
dynamicPlotMods PlotMods b v n -> f (PlotMods b v n)
f (DynamicPlot (Plot p
p PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
ps)) =
  PlotMods b v n -> f (PlotMods b v n)
f (PlotOptions b v n
-> (PlotStyle b v n -> PlotStyle b v n) -> PlotMods b v n
forall b (v :: * -> *) n.
PlotOptions b v n
-> (PlotStyle b v n -> PlotStyle b v n) -> PlotMods b v n
PlotMods PlotOptions b v n
PlotOptions b (V p) (N p)
opts PlotStyle b v n -> PlotStyle b v n
PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
ps) f (PlotMods b v n)
-> (PlotMods b v n -> DynamicPlot b v n) -> f (DynamicPlot b v n)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \(PlotMods PlotOptions b v n
opts' PlotStyle b v n -> PlotStyle b v n
ps') -> Plot p b -> DynamicPlot b v n
forall (v :: * -> *) n p b.
(InSpace v n p, Plotable p b) =>
Plot p b -> DynamicPlot b v n
DynamicPlot (p
-> PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> Plot p b
forall p b.
p
-> PlotOptions b (V p) (N p)
-> (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p))
-> Plot p b
Plot p
p PlotOptions b v n
PlotOptions b (V p) (N p)
opts' PlotStyle b v n -> PlotStyle b v n
PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
ps')

------------------------------------------------------------------------
-- StyledPlot
------------------------------------------------------------------------

-- | A 'DynamicPlot' with a concrete style. This is suitable for being
--   rendered with 'renderStyledPlot' and get extract the legend entries
--   with 'styledPlotLegend'.
--
--   You can make a 'StyledPlot' with 'styleDynamic'
data StyledPlot b v n where
  StyledPlot
    :: Plotable p b
    => p
    -> PlotOptions b (V p) (N p)
    -> PlotStyle b (V p) (N p)
    -> StyledPlot b (V p) (N p)

type instance V (StyledPlot b v n) = v
type instance N (StyledPlot b v n) = n

instance Functor f => HasPlotOptions f (StyledPlot b v n) b where
  plotOptions :: LensLike'
  f
  (StyledPlot b v n)
  (PlotOptions b (V (StyledPlot b v n)) (N (StyledPlot b v n)))
plotOptions PlotOptions b (V (StyledPlot b v n)) (N (StyledPlot b v n))
-> f (PlotOptions b (V (StyledPlot b v n)) (N (StyledPlot b v n)))
f (StyledPlot p
p PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p)
sty) =
    PlotOptions b (V (StyledPlot b v n)) (N (StyledPlot b v n))
-> f (PlotOptions b (V (StyledPlot b v n)) (N (StyledPlot b v n)))
f PlotOptions b (V p) (N p)
PlotOptions b (V (StyledPlot b v n)) (N (StyledPlot b v n))
opts f (PlotOptions b v n)
-> (PlotOptions b v n -> StyledPlot b v n) -> f (StyledPlot b v n)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \PlotOptions b v n
opts' -> p
-> PlotOptions b (V p) (N p)
-> PlotStyle b (V p) (N p)
-> StyledPlot b (V p) (N p)
forall p b.
Plotable p b =>
p
-> PlotOptions b (V p) (N p)
-> PlotStyle b (V p) (N p)
-> StyledPlot b (V p) (N p)
StyledPlot p
p PlotOptions b v n
PlotOptions b (V p) (N p)
opts' PlotStyle b (V p) (N p)
sty

instance (Metric v, OrderedField n) => Enveloped (StyledPlot b v n) where
  getEnvelope :: StyledPlot b v n
-> Envelope (V (StyledPlot b v n)) (N (StyledPlot b v n))
getEnvelope (StyledPlot p
p PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p)
_) =
    p -> Envelope (V p) (N p)
forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope p
p Envelope v n -> (Envelope v n -> Envelope v n) -> Envelope v n
forall a b. a -> (a -> b) -> b
& Transformation (V (Envelope v n)) (N (Envelope v n))
-> Envelope v n -> Envelope v n
forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform (PlotOptions b v n -> Transformation v n
forall b (v :: * -> *) n. PlotOptions b v n -> Transformation v n
poTransform PlotOptions b v n
PlotOptions b (V p) (N p)
opts)

instance Functor f => HasPlotStyle f (StyledPlot b v n) b where
  plotStyle :: LensLike'
  f
  (StyledPlot b v n)
  (PlotStyle b (V (StyledPlot b v n)) (N (StyledPlot b v n)))
plotStyle PlotStyle b (V (StyledPlot b v n)) (N (StyledPlot b v n))
-> f (PlotStyle b (V (StyledPlot b v n)) (N (StyledPlot b v n)))
f (StyledPlot p
p PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p)
sty) =
    PlotStyle b (V (StyledPlot b v n)) (N (StyledPlot b v n))
-> f (PlotStyle b (V (StyledPlot b v n)) (N (StyledPlot b v n)))
f PlotStyle b (V p) (N p)
PlotStyle b (V (StyledPlot b v n)) (N (StyledPlot b v n))
sty f (PlotStyle b v n)
-> (PlotStyle b v n -> StyledPlot b v n) -> f (StyledPlot b v n)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> p
-> PlotOptions b (V p) (N p)
-> PlotStyle b (V p) (N p)
-> StyledPlot b (V p) (N p)
forall p b.
Plotable p b =>
p
-> PlotOptions b (V p) (N p)
-> PlotStyle b (V p) (N p)
-> StyledPlot b (V p) (N p)
StyledPlot p
p PlotOptions b (V p) (N p)
opts

-- | Traversal over a raw plot of a styled plot. The type of the plot
--   must match for the traversal to be successful.
styledPlot :: forall p b. Typeable p => Traversal' (StyledPlot b (V p) (N p)) p
styledPlot :: forall p b. Typeable p => Traversal' (StyledPlot b (V p) (N p)) p
styledPlot p -> f p
f s :: StyledPlot b (V p) (N p)
s@(StyledPlot p
p PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p)
sty) =
  case p -> Maybe (p :~: p)
forall a. Typeable a => a -> Maybe (a :~: p)
eq p
p of
    Just p :~: p
Refl -> p -> f p
f p
p
p f p
-> (p -> StyledPlot b (V p) (N p)) -> f (StyledPlot b (V p) (N p))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \p
p' -> p
-> PlotOptions b (V p) (N p)
-> PlotStyle b (V p) (N p)
-> StyledPlot b (V p) (N p)
forall p b.
Plotable p b =>
p
-> PlotOptions b (V p) (N p)
-> PlotStyle b (V p) (N p)
-> StyledPlot b (V p) (N p)
StyledPlot p
p' PlotOptions b (V p) (N p)
PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p)
PlotStyle b (V p) (N p)
sty
    Maybe (p :~: p)
Nothing   -> StyledPlot b (V p) (N p) -> f (StyledPlot b (V p) (N p))
forall (f :: * -> *) a. Applicative f => a -> f a
pure StyledPlot b (V p) (N p)
StyledPlot b (V p) (N p)
s
  where eq :: Typeable a => a -> Maybe (a :~: p)
        eq :: forall a. Typeable a => a -> Maybe (a :~: p)
eq a
_ = Maybe (a :~: p)
forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
eqT

-- | Give a 'DynamicPlot' a concrete 'PlotStyle'.
styleDynamic :: PlotStyle b v n -> DynamicPlot b v n -> StyledPlot b v n
styleDynamic :: forall b (v :: * -> *) n.
PlotStyle b v n -> DynamicPlot b v n -> StyledPlot b v n
styleDynamic PlotStyle b v n
sty (DynamicPlot (Plot p
p PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
styF)) = p
-> PlotOptions b (V p) (N p)
-> PlotStyle b (V p) (N p)
-> StyledPlot b (V p) (N p)
forall p b.
Plotable p b =>
p
-> PlotOptions b (V p) (N p)
-> PlotStyle b (V p) (N p)
-> StyledPlot b (V p) (N p)
StyledPlot p
p PlotOptions b (V p) (N p)
opts (PlotStyle b (V p) (N p) -> PlotStyle b (V p) (N p)
styF PlotStyle b v n
PlotStyle b (V p) (N p)
sty)

-- | Render a 'StyledPlot' given an and 'AxisSpec'.
renderStyledPlot
  :: TypeableFloat n
  => AxisSpec V2 n
  -> StyledPlot b V2 n
  -> QDiagram b V2 n Any
renderStyledPlot :: forall n b.
TypeableFloat n =>
AxisSpec V2 n -> StyledPlot b V2 n -> QDiagram b V2 n Any
renderStyledPlot AxisSpec V2 n
aSpec (StyledPlot p
p PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p)
sty)
  = AxisSpec V2 n -> PlotStyle b V2 n -> p -> QDiagram b V2 n Any
forall p b (v :: * -> *) n.
(Plotable p b, InSpace v n p) =>
AxisSpec v n -> PlotStyle b v n -> p -> QDiagram b v n Any
renderPlotable AxisSpec V2 n
aSpec PlotStyle b (V p) (N p)
PlotStyle b V2 n
sty p
p
      QDiagram b V2 n Any
-> (QDiagram b V2 n Any -> QDiagram b V2 n Any)
-> QDiagram b V2 n Any
forall a b. a -> (a -> b) -> b
& Bool
-> (QDiagram b V2 n Any -> QDiagram b V2 n Any)
-> QDiagram b V2 n Any
-> QDiagram b V2 n Any
forall a. Bool -> (a -> a) -> a -> a
whenever (PlotOptions b (V p) (N p)
PlotOptions b V2 n
optsPlotOptions b V2 n
-> Getting Bool (PlotOptions b V2 n) Bool -> Bool
forall s a. s -> Getting a s a -> a
^.Getting Bool (PlotOptions b V2 n) Bool
forall a. HasVisibility a => Lens' a Bool
hidden) QDiagram b V2 n Any -> QDiagram b V2 n Any
forall (v :: * -> *) n a m b.
(InSpace v n a, Monoid' m, Enveloped a, Traced a) =>
a -> QDiagram b v n m
phantom
      QDiagram b V2 n Any
-> (QDiagram b V2 n Any -> QDiagram b V2 n Any)
-> QDiagram b V2 n Any
forall a b. a -> (a -> b) -> b
& Bool
-> (QDiagram b V2 n Any -> QDiagram b V2 n Any)
-> QDiagram b V2 n Any
-> QDiagram b V2 n Any
forall a. Bool -> (a -> a) -> a -> a
whenever (PlotOptions b (V p) (N p)
PlotOptions b V2 n
optsPlotOptions b V2 n
-> Getting Bool (PlotOptions b V2 n) Bool -> Bool
forall s a. s -> Getting a s a -> a
^.Getting Bool (PlotOptions b V2 n) Bool
forall (f :: * -> *) a b.
(HasPlotOptions f a b, Functor f) =>
LensLike' f a Bool
clipPlot) (Path V2 n -> QDiagram b V2 n Any -> QDiagram b V2 n Any
forall n b.
TypeableFloat n =>
Path V2 n -> QDiagram b V2 n Any -> QDiagram b V2 n Any
clipTo (Path V2 n -> QDiagram b V2 n Any -> QDiagram b V2 n Any)
-> Path V2 n -> QDiagram b V2 n Any -> QDiagram b V2 n Any
forall a b. (a -> b) -> a -> b
$ AxisSpec V2 n -> Path V2 n
forall n. TypeableFloat n => AxisSpec V2 n -> Path V2 n
specRect AxisSpec V2 n
aSpec)

specRect :: TypeableFloat n => AxisSpec V2 n -> Path V2 n
specRect :: forall n. TypeableFloat n => AxisSpec V2 n -> Path V2 n
specRect AxisSpec V2 n
aSpec =
  n -> n -> Path V2 n
forall n t. (InSpace V2 n t, TrailLike t) => n -> n -> t
rect (n
xU n -> n -> n
forall a. Num a => a -> a -> a
- n
xL) (n
yU n -> n -> n
forall a. Num a => a -> a -> a
- n
yL)
    # moveTo (mkP2 ((xU+xL)/2) ((yU+yL)/2))
    # transform t
  where
  V2 (n
xL,n
xU) (n
yL,n
yU) = AxisSpec V2 n -> V2 (n, n)
forall (v :: * -> *) n. AxisSpec v n -> v (n, n)
_specBounds AxisSpec V2 n
aSpec
  t :: Transformation V2 n
t                   = AxisSpec V2 n -> Transformation V2 n
forall (v :: * -> *) n. AxisSpec v n -> Transformation v n
_specTrans AxisSpec V2 n
aSpec

-- | Get the legend rendered entries from a single styled plot. The
--   resulting entries are in no particular order. See also
--   'styledPlotLegends'.
singleStyledPlotLegend
  :: StyledPlot b v n
  -> [(n, QDiagram b v n Any, String)] -- ^ @(z-order, legend pic, legend text)@
singleStyledPlotLegend :: forall b (v :: * -> *) n.
StyledPlot b v n -> [(n, QDiagram b v n Any, String)]
singleStyledPlotLegend (StyledPlot p
p PlotOptions b (V p) (N p)
opts PlotStyle b (V p) (N p)
sty) =
  (LegendEntry b v n -> (n, QDiagram b v n Any, String))
-> [LegendEntry b v n] -> [(n, QDiagram b v n Any, String)]
forall a b. (a -> b) -> [a] -> [b]
map LegendEntry b v n -> (n, QDiagram b v n Any, String)
mk (PlotOptions b v n
PlotOptions b (V p) (N p)
opts PlotOptions b v n
-> Getting
     [LegendEntry b v n] (PlotOptions b v n) [LegendEntry b v n]
-> [LegendEntry b v n]
forall s a. s -> Getting a s a -> a
^. Getting [LegendEntry b v n] (PlotOptions b v n) [LegendEntry b v n]
forall (f :: * -> *) a b.
(HasPlotOptions f a b, Functor f) =>
LensLike' f a [LegendEntry b (V a) (N a)]
legendEntries)
  where
    mk :: LegendEntry b v n -> (n, QDiagram b v n Any, String)
mk LegendEntry b v n
entry = (LegendEntry b v n
entry LegendEntry b v n -> Getting n (LegendEntry b v n) n -> n
forall s a. s -> Getting a s a -> a
^. Getting n (LegendEntry b v n) n
forall b (v :: * -> *) n. Lens' (LegendEntry b v n) n
legendPrecedence, QDiagram b v n Any
pic, LegendEntry b v n
entry LegendEntry b v n
-> Getting String (LegendEntry b v n) String -> String
forall s a. s -> Getting a s a -> a
^. Getting String (LegendEntry b v n) String
forall b (v :: * -> *) n. Lens' (LegendEntry b v n) String
legendText)
      where
        pic :: QDiagram b v n Any
pic = case LegendEntry b v n -> LegendPic b v n
forall b (v :: * -> *) n. LegendEntry b v n -> LegendPic b v n
lPic LegendEntry b v n
entry of
                LegendPic b v n
DefaultLegendPic  -> PlotStyle b v n -> p -> QDiagram b v n Any
forall p b (v :: * -> *) n.
(Plotable p b, InSpace v n p) =>
PlotStyle b v n -> p -> QDiagram b v n Any
defLegendPic PlotStyle b v n
PlotStyle b (V p) (N p)
sty p
p
                CustomLegendPic PlotStyle b v n -> QDiagram b v n Any
f -> PlotStyle b v n -> QDiagram b v n Any
f PlotStyle b v n
PlotStyle b (V p) (N p)
sty

-- | Render a list of legend entries, in order.
styledPlotLegends
  :: Ord n
  => [StyledPlot b v n]
  -> [(QDiagram b v n Any, String)] -- ^ @[(legend pic, legend text)]@
styledPlotLegends :: forall n b (v :: * -> *).
Ord n =>
[StyledPlot b v n] -> [(QDiagram b v n Any, String)]
styledPlotLegends
  = ((n, QDiagram b v n Any, String) -> (QDiagram b v n Any, String))
-> [(n, QDiagram b v n Any, String)]
-> [(QDiagram b v n Any, String)]
forall a b. (a -> b) -> [a] -> [b]
map (\(n
_,QDiagram b v n Any
p,String
t) -> (QDiagram b v n Any
p,String
t))
  ([(n, QDiagram b v n Any, String)]
 -> [(QDiagram b v n Any, String)])
-> ([StyledPlot b v n] -> [(n, QDiagram b v n Any, String)])
-> [StyledPlot b v n]
-> [(QDiagram b v n Any, String)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((n, QDiagram b v n Any, String) -> n)
-> [(n, QDiagram b v n Any, String)]
-> [(n, QDiagram b v n Any, String)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (Getting n (n, QDiagram b v n Any, String) n
-> (n, QDiagram b v n Any, String) -> n
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting n (n, QDiagram b v n Any, String) n
forall s t a b. Field1 s t a b => Lens s t a b
_1)
  ([(n, QDiagram b v n Any, String)]
 -> [(n, QDiagram b v n Any, String)])
-> ([StyledPlot b v n] -> [(n, QDiagram b v n Any, String)])
-> [StyledPlot b v n]
-> [(n, QDiagram b v n Any, String)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (StyledPlot b v n -> [(n, QDiagram b v n Any, String)])
-> [StyledPlot b v n] -> [(n, QDiagram b v n Any, String)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap StyledPlot b v n -> [(n, QDiagram b v n Any, String)]
forall b (v :: * -> *) n.
StyledPlot b v n -> [(n, QDiagram b v n Any, String)]
singleStyledPlotLegend

-- XXX taken from "Data.List", defined here because it was only added in
-- base-4.8 (ghc-7.10)
sortOn :: Ord b => (a -> b) -> [a] -> [a]
sortOn :: forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn a -> b
f =
  ((b, a) -> a) -> [(b, a)] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (b, a) -> a
forall a b. (a, b) -> b
snd ([(b, a)] -> [a]) -> ([a] -> [(b, a)]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((b, a) -> (b, a) -> Ordering) -> [(b, a)] -> [(b, a)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((b, a) -> b) -> (b, a) -> (b, a) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (b, a) -> b
forall a b. (a, b) -> a
fst) ([(b, a)] -> [(b, a)]) -> ([a] -> [(b, a)]) -> [a] -> [(b, a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> (b, a)) -> [a] -> [(b, a)]
forall a b. (a -> b) -> [a] -> [b]
map (\a
x -> let y :: b
y = a -> b
f a
x in b
y b -> (b, a) -> (b, a)
`seq` (b
y, a
x))