-- |
-- Module     :  Graphics.Rendering.Chart.Plot.AreaSpots
-- Copyright  :  (c) Malcolm Wallace 2009
-- License    :  BSD-style (see COPYRIGHT file)
--
-- Area spots are a collection of unconnected filled circles,
-- with x,y position, and an independent z value to be represented
-- by the relative area of the spots.

{-# LANGUAGE TemplateHaskell #-}

module Graphics.Rendering.Chart.Plot.AreaSpots
  ( AreaSpots(..)

  , area_spots_title
  , area_spots_linethick
  , area_spots_linecolour
  , area_spots_fillcolour
  , area_spots_opacity
  , area_spots_max_radius
  , area_spots_values

  , AreaSpots4D(..)

  , area_spots_4d_title
  , area_spots_4d_linethick
  , area_spots_4d_palette
  , area_spots_4d_opacity
  , area_spots_4d_max_radius
  , area_spots_4d_values
  ) where

import Graphics.Rendering.Chart.Geometry hiding (scale, x0, y0)
import Graphics.Rendering.Chart.Drawing
import Graphics.Rendering.Chart.Plot.Types
import Graphics.Rendering.Chart.Axis
import Control.Lens
import Data.Colour hiding (over)
import Data.Colour.Names
import Data.Default.Class

import Control.Monad

-- | A collection of unconnected spots, with x,y position, and an
--   independent z value to be represented by the area of the spot.
data AreaSpots z x y = AreaSpots
  { AreaSpots z x y -> String
_area_spots_title      :: String
  , AreaSpots z x y -> Double
_area_spots_linethick  :: Double
  , AreaSpots z x y -> AlphaColour Double
_area_spots_linecolour :: AlphaColour Double
  , AreaSpots z x y -> Colour Double
_area_spots_fillcolour :: Colour Double
  , AreaSpots z x y -> Double
_area_spots_opacity    :: Double
  , AreaSpots z x y -> Double
_area_spots_max_radius :: Double   -- ^ the largest size of spot
  , AreaSpots z x y -> [(x, y, z)]
_area_spots_values     :: [(x,y,z)]
  }

instance Default (AreaSpots z x y) where
  def :: AreaSpots z x y
def = AreaSpots :: forall z x y.
String
-> Double
-> AlphaColour Double
-> Colour Double
-> Double
-> Double
-> [(x, y, z)]
-> AreaSpots z x y
AreaSpots
    { _area_spots_title :: String
_area_spots_title      = String
""
    , _area_spots_linethick :: Double
_area_spots_linethick  = Double
0.1
    , _area_spots_linecolour :: AlphaColour Double
_area_spots_linecolour = Colour Double -> AlphaColour Double
forall a. Num a => Colour a -> AlphaColour a
opaque Colour Double
forall a. (Ord a, Floating a) => Colour a
blue
    , _area_spots_fillcolour :: Colour Double
_area_spots_fillcolour = Colour Double
forall a. (Ord a, Floating a) => Colour a
blue
    , _area_spots_opacity :: Double
_area_spots_opacity    = Double
0.2
    , _area_spots_max_radius :: Double
_area_spots_max_radius = Double
20  -- in pixels
    , _area_spots_values :: [(x, y, z)]
_area_spots_values     = []
    }

instance (PlotValue z) => ToPlot (AreaSpots z) where
    toPlot :: AreaSpots z x y -> Plot x y
toPlot AreaSpots z x y
p = Plot :: forall x y.
(PointMapFn x y -> BackendProgram ())
-> [(String, Rect -> BackendProgram ())] -> ([x], [y]) -> Plot x y
Plot { _plot_render :: PointMapFn x y -> BackendProgram ()
_plot_render = AreaSpots z x y -> PointMapFn x y -> BackendProgram ()
forall z x y.
PlotValue z =>
AreaSpots z x y -> PointMapFn x y -> BackendProgram ()
renderAreaSpots AreaSpots z x y
p
                    , _plot_legend :: [(String, Rect -> BackendProgram ())]
_plot_legend = [(AreaSpots z x y -> String
forall z x y. AreaSpots z x y -> String
_area_spots_title AreaSpots z x y
p, AreaSpots z x y -> Rect -> BackendProgram ()
forall z x y. AreaSpots z x y -> Rect -> BackendProgram ()
renderSpotLegend AreaSpots z x y
p)]
                    , _plot_all_points :: ([x], [y])
_plot_all_points = ( ((x, y, z) -> x) -> [(x, y, z)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
map ((x, y, z) -> Getting x (x, y, z) x -> x
forall s a. s -> Getting a s a -> a
^.Getting x (x, y, z) x
forall s t a b. Field1 s t a b => Lens s t a b
_1) (AreaSpots z x y -> [(x, y, z)]
forall z x y. AreaSpots z x y -> [(x, y, z)]
_area_spots_values AreaSpots z x y
p)
                                         , ((x, y, z) -> y) -> [(x, y, z)] -> [y]
forall a b. (a -> b) -> [a] -> [b]
map ((x, y, z) -> Getting y (x, y, z) y -> y
forall s a. s -> Getting a s a -> a
^.Getting y (x, y, z) y
forall s t a b. Field2 s t a b => Lens s t a b
_2) (AreaSpots z x y -> [(x, y, z)]
forall z x y. AreaSpots z x y -> [(x, y, z)]
_area_spots_values AreaSpots z x y
p) )
                    }

renderAreaSpots  :: (PlotValue z) => AreaSpots z x y -> PointMapFn x y -> BackendProgram ()
renderAreaSpots :: AreaSpots z x y -> PointMapFn x y -> BackendProgram ()
renderAreaSpots AreaSpots z x y
p PointMapFn x y
pmap = 
    [(x, y, Double)]
-> ((x, y, Double) -> BackendProgram ()) -> BackendProgram ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (Double -> [(x, y, z)] -> [(x, y, Double)]
forall z x y.
PlotValue z =>
Double -> [(x, y, z)] -> [(x, y, Double)]
scaleMax (AreaSpots z x y -> Double
forall z x y. AreaSpots z x y -> Double
_area_spots_max_radius AreaSpots z x y
pDouble -> Integer -> Double
forall a b. (Num a, Integral b) => a -> b -> a
^(Integer
2::Integer))
                    (AreaSpots z x y -> [(x, y, z)]
forall z x y. AreaSpots z x y -> [(x, y, z)]
_area_spots_values AreaSpots z x y
p))
          (\ (x
x,y
y,Double
z)-> do
              let radius :: Double
radius = Double -> Double
forall a. Floating a => a -> a
sqrt Double
z
              let psSpot :: PointStyle
psSpot = Double -> AlphaColour Double -> PointStyle
filledCircles Double
radius (AlphaColour Double -> PointStyle)
-> AlphaColour Double -> PointStyle
forall a b. (a -> b) -> a -> b
$
                                                    (Colour Double -> Double -> AlphaColour Double)
-> Double -> Colour Double -> AlphaColour Double
forall a b c. (a -> b -> c) -> b -> a -> c
flip Colour Double -> Double -> AlphaColour Double
forall a. Num a => Colour a -> a -> AlphaColour a
withOpacity 
                                                      (AreaSpots z x y -> Double
forall z x y. AreaSpots z x y -> Double
_area_spots_opacity AreaSpots z x y
p) (Colour Double -> AlphaColour Double)
-> Colour Double -> AlphaColour Double
forall a b. (a -> b) -> a -> b
$
                                                    AreaSpots z x y -> Colour Double
forall z x y. AreaSpots z x y -> Colour Double
_area_spots_fillcolour AreaSpots z x y
p
              PointStyle -> Point -> BackendProgram ()
drawPoint PointStyle
psSpot (PointMapFn x y
pmap (x -> Limit x
forall a. a -> Limit a
LValue x
x, y -> Limit y
forall a. a -> Limit a
LValue y
y))
              let psOutline :: PointStyle
psOutline = Double -> Double -> AlphaColour Double -> PointStyle
hollowCircles Double
radius
                                                      (AreaSpots z x y -> Double
forall z x y. AreaSpots z x y -> Double
_area_spots_linethick AreaSpots z x y
p)
                                                      (AreaSpots z x y -> AlphaColour Double
forall z x y. AreaSpots z x y -> AlphaColour Double
_area_spots_linecolour AreaSpots z x y
p)
              PointStyle -> Point -> BackendProgram ()
drawPoint PointStyle
psOutline (PointMapFn x y
pmap (x -> Limit x
forall a. a -> Limit a
LValue x
x, y -> Limit y
forall a. a -> Limit a
LValue y
y))
          )
  where
    scaleMax :: PlotValue z => Double -> [(x,y,z)] -> [(x,y,Double)]
    scaleMax :: Double -> [(x, y, z)] -> [(x, y, Double)]
scaleMax Double
n [(x, y, z)]
points = let largest :: Double
largest  = [Double] -> Double
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum (((x, y, z) -> Double) -> [(x, y, z)] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map ((x, y, z) -> Getting Double (x, y, z) Double -> Double
forall s a. s -> Getting a s a -> a
^.(z -> Const Double z) -> (x, y, z) -> Const Double (x, y, z)
forall s t a b. Field3 s t a b => Lens s t a b
_3((z -> Const Double z) -> (x, y, z) -> Const Double (x, y, z))
-> ((Double -> Const Double Double) -> z -> Const Double z)
-> Getting Double (x, y, z) Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(z -> Double)
-> (Double -> Const Double Double) -> z -> Const Double z
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to z -> Double
forall a. PlotValue a => a -> Double
toValue) [(x, y, z)]
points)
                            scale :: a -> Double
scale a
v  = Double
n Double -> Double -> Double
forall a. Num a => a -> a -> a
* a -> Double
forall a. PlotValue a => a -> Double
toValue a
v Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
largest
                        in ASetter [(x, y, z)] [(x, y, Double)] z Double
-> (z -> Double) -> [(x, y, z)] -> [(x, y, Double)]
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over (((x, y, z) -> Identity (x, y, Double))
-> [(x, y, z)] -> Identity [(x, y, Double)]
forall (f :: * -> *) a b. Functor f => Setter (f a) (f b) a b
mapped(((x, y, z) -> Identity (x, y, Double))
 -> [(x, y, z)] -> Identity [(x, y, Double)])
-> ((z -> Identity Double) -> (x, y, z) -> Identity (x, y, Double))
-> ASetter [(x, y, z)] [(x, y, Double)] z Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(z -> Identity Double) -> (x, y, z) -> Identity (x, y, Double)
forall s t a b. Field3 s t a b => Lens s t a b
_3) z -> Double
forall a. PlotValue a => a -> Double
scale [(x, y, z)]
points

renderSpotLegend :: AreaSpots z x y -> Rect -> BackendProgram ()
renderSpotLegend :: AreaSpots z x y -> Rect -> BackendProgram ()
renderSpotLegend AreaSpots z x y
p (Rect Point
p1 Point
p2) = do
    let radius :: Double
radius = Double -> Double -> Double
forall a. Ord a => a -> a -> a
min (Double -> Double
forall a. Num a => a -> a
abs (Point -> Double
p_y Point
p1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Point -> Double
p_y Point
p2)) (Double -> Double
forall a. Num a => a -> a
abs (Point -> Double
p_x Point
p1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Point -> Double
p_x Point
p2))
        centre :: Point
centre = Point -> Point -> Point
linearInterpolate Point
p1 Point
p2
        psSpot :: PointStyle
psSpot = Double -> AlphaColour Double -> PointStyle
filledCircles Double
radius (AlphaColour Double -> PointStyle)
-> AlphaColour Double -> PointStyle
forall a b. (a -> b) -> a -> b
$ Colour Double -> Double -> AlphaColour Double
forall a. Num a => Colour a -> a -> AlphaColour a
withOpacity 
                                        (AreaSpots z x y -> Colour Double
forall z x y. AreaSpots z x y -> Colour Double
_area_spots_fillcolour AreaSpots z x y
p)
                                        (AreaSpots z x y -> Double
forall z x y. AreaSpots z x y -> Double
_area_spots_opacity AreaSpots z x y
p)
        psOutline :: PointStyle
psOutline = Double -> Double -> AlphaColour Double -> PointStyle
hollowCircles Double
radius (AreaSpots z x y -> Double
forall z x y. AreaSpots z x y -> Double
_area_spots_linethick AreaSpots z x y
p)
                                         (AreaSpots z x y -> AlphaColour Double
forall z x y. AreaSpots z x y -> AlphaColour Double
_area_spots_linecolour AreaSpots z x y
p)
    PointStyle -> Point -> BackendProgram ()
drawPoint PointStyle
psSpot Point
centre
    PointStyle -> Point -> BackendProgram ()
drawPoint PointStyle
psOutline Point
centre
  where
    linearInterpolate :: Point -> Point -> Point
linearInterpolate (Point Double
x0 Double
y0) (Point Double
x1 Double
y1) =
        Double -> Double -> Point
Point (Double
x0 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
forall a. Num a => a -> a
abs(Double
x1Double -> Double -> Double
forall a. Num a => a -> a -> a
-Double
x0)Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2) (Double
y0 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
forall a. Num a => a -> a
abs(Double
y1Double -> Double -> Double
forall a. Num a => a -> a -> a
-Double
y0)Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2)

-- | A collection of unconnected spots, with x,y position, an
--   independent z value to be represented by the area of the spot,
--   and in addition, a fourth variable t to be represented by a colour
--   from a given palette.  (A linear transfer function from t to palette
--   is assumed.)
data AreaSpots4D z t x y = AreaSpots4D
  { AreaSpots4D z t x y -> String
_area_spots_4d_title      :: String
  , AreaSpots4D z t x y -> Double
_area_spots_4d_linethick  :: Double
  , AreaSpots4D z t x y -> [Colour Double]
_area_spots_4d_palette    :: [Colour Double]
  , AreaSpots4D z t x y -> Double
_area_spots_4d_opacity    :: Double
  , AreaSpots4D z t x y -> Double
_area_spots_4d_max_radius :: Double        -- ^ the largest size of spot
  , AreaSpots4D z t x y -> [(x, y, z, t)]
_area_spots_4d_values     :: [(x,y,z,t)]
  }

instance Default (AreaSpots4D z t x y) where
  def :: AreaSpots4D z t x y
def = AreaSpots4D :: forall z t x y.
String
-> Double
-> [Colour Double]
-> Double
-> Double
-> [(x, y, z, t)]
-> AreaSpots4D z t x y
AreaSpots4D
    { _area_spots_4d_title :: String
_area_spots_4d_title      = String
""
    , _area_spots_4d_linethick :: Double
_area_spots_4d_linethick  = Double
0.1
    , _area_spots_4d_palette :: [Colour Double]
_area_spots_4d_palette    = [ Colour Double
forall a. (Ord a, Floating a) => Colour a
blue, Colour Double
forall a. (Ord a, Floating a) => Colour a
green, Colour Double
forall a. (Ord a, Floating a) => Colour a
yellow, Colour Double
forall a. (Ord a, Floating a) => Colour a
orange, Colour Double
forall a. (Ord a, Floating a) => Colour a
red ]
    , _area_spots_4d_opacity :: Double
_area_spots_4d_opacity    = Double
0.2
    , _area_spots_4d_max_radius :: Double
_area_spots_4d_max_radius = Double
20  -- in pixels
    , _area_spots_4d_values :: [(x, y, z, t)]
_area_spots_4d_values     = []
    }

instance (PlotValue z, PlotValue t, Show t) => ToPlot (AreaSpots4D z t) where
    toPlot :: AreaSpots4D z t x y -> Plot x y
toPlot AreaSpots4D z t x y
p = Plot :: forall x y.
(PointMapFn x y -> BackendProgram ())
-> [(String, Rect -> BackendProgram ())] -> ([x], [y]) -> Plot x y
Plot { _plot_render :: PointMapFn x y -> BackendProgram ()
_plot_render = AreaSpots4D z t x y -> PointMapFn x y -> BackendProgram ()
forall z t x y.
(PlotValue z, PlotValue t, Show t) =>
AreaSpots4D z t x y -> PointMapFn x y -> BackendProgram ()
renderAreaSpots4D AreaSpots4D z t x y
p
                    , _plot_legend :: [(String, Rect -> BackendProgram ())]
_plot_legend = [ (AreaSpots4D z t x y -> String
forall z t x y. AreaSpots4D z t x y -> String
_area_spots_4d_title AreaSpots4D z t x y
p
                                       , AreaSpots4D z t x y -> Rect -> BackendProgram ()
forall z t x y. AreaSpots4D z t x y -> Rect -> BackendProgram ()
renderSpotLegend4D AreaSpots4D z t x y
p) ]
                    , _plot_all_points :: ([x], [y])
_plot_all_points = ( ((x, y, z, t) -> x) -> [(x, y, z, t)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
map ((x, y, z, t) -> Getting x (x, y, z, t) x -> x
forall s a. s -> Getting a s a -> a
^.Getting x (x, y, z, t) x
forall s t a b. Field1 s t a b => Lens s t a b
_1) (AreaSpots4D z t x y -> [(x, y, z, t)]
forall z t x y. AreaSpots4D z t x y -> [(x, y, z, t)]
_area_spots_4d_values AreaSpots4D z t x y
p)
                                         , ((x, y, z, t) -> y) -> [(x, y, z, t)] -> [y]
forall a b. (a -> b) -> [a] -> [b]
map ((x, y, z, t) -> Getting y (x, y, z, t) y -> y
forall s a. s -> Getting a s a -> a
^.Getting y (x, y, z, t) y
forall s t a b. Field2 s t a b => Lens s t a b
_2) (AreaSpots4D z t x y -> [(x, y, z, t)]
forall z t x y. AreaSpots4D z t x y -> [(x, y, z, t)]
_area_spots_4d_values AreaSpots4D z t x y
p) )
                    }

renderAreaSpots4D  :: (PlotValue z, PlotValue t, Show t) =>
                      AreaSpots4D z t x y -> PointMapFn x y -> BackendProgram ()
renderAreaSpots4D :: AreaSpots4D z t x y -> PointMapFn x y -> BackendProgram ()
renderAreaSpots4D AreaSpots4D z t x y
p PointMapFn x y
pmap = 
    [(x, y, Double, Int)]
-> ((x, y, Double, Int) -> BackendProgram ()) -> BackendProgram ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (Double -> Int -> [(x, y, z, t)] -> [(x, y, Double, Int)]
forall z t x y.
(PlotValue z, PlotValue t, Show t) =>
Double -> Int -> [(x, y, z, t)] -> [(x, y, Double, Int)]
scaleMax (AreaSpots4D z t x y -> Double
forall z t x y. AreaSpots4D z t x y -> Double
_area_spots_4d_max_radius AreaSpots4D z t x y
pDouble -> Integer -> Double
forall a b. (Num a, Integral b) => a -> b -> a
^(Integer
2::Integer))
                    ([Colour Double] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (AreaSpots4D z t x y -> [Colour Double]
forall z t x y. AreaSpots4D z t x y -> [Colour Double]
_area_spots_4d_palette AreaSpots4D z t x y
p))
                    (AreaSpots4D z t x y -> [(x, y, z, t)]
forall z t x y. AreaSpots4D z t x y -> [(x, y, z, t)]
_area_spots_4d_values AreaSpots4D z t x y
p))
          (\ (x
x,y
y,Double
z,Int
t)-> do
              let radius :: Double
radius  = Double -> Double
forall a. Floating a => a -> a
sqrt Double
z
              let colour :: Colour Double
colour  = AreaSpots4D z t x y -> [Colour Double]
forall z t x y. AreaSpots4D z t x y -> [Colour Double]
_area_spots_4d_palette AreaSpots4D z t x y
p [Colour Double] -> Int -> Colour Double
forall a. [a] -> Int -> a
!! Int
t 
              let psSpot :: PointStyle
psSpot
                    = Double -> AlphaColour Double -> PointStyle
filledCircles Double
radius (AlphaColour Double -> PointStyle)
-> AlphaColour Double -> PointStyle
forall a b. (a -> b) -> a -> b
$
                          Colour Double -> Double -> AlphaColour Double
forall a. Num a => Colour a -> a -> AlphaColour a
withOpacity Colour Double
colour (AreaSpots4D z t x y -> Double
forall z t x y. AreaSpots4D z t x y -> Double
_area_spots_4d_opacity AreaSpots4D z t x y
p)
              PointStyle -> Point -> BackendProgram ()
drawPoint PointStyle
psSpot (PointMapFn x y
pmap (x -> Limit x
forall a. a -> Limit a
LValue x
x, y -> Limit y
forall a. a -> Limit a
LValue y
y))
              let psOutline :: PointStyle
psOutline
                    = Double -> Double -> AlphaColour Double -> PointStyle
hollowCircles Double
radius (AreaSpots4D z t x y -> Double
forall z t x y. AreaSpots4D z t x y -> Double
_area_spots_4d_linethick AreaSpots4D z t x y
p)
                                           (Colour Double -> AlphaColour Double
forall a. Num a => Colour a -> AlphaColour a
opaque Colour Double
colour)
              PointStyle -> Point -> BackendProgram ()
drawPoint PointStyle
psOutline (PointMapFn x y
pmap (x -> Limit x
forall a. a -> Limit a
LValue x
x, y -> Limit y
forall a. a -> Limit a
LValue y
y))
          )
  where
    scaleMax :: (PlotValue z, PlotValue t, Show t) =>
                Double -> Int -> [(x,y,z,t)] -> [(x,y,Double,Int)]
    scaleMax :: Double -> Int -> [(x, y, z, t)] -> [(x, y, Double, Int)]
scaleMax Double
n Int
c [(x, y, z, t)]
points = let largest :: Double
largest  = [Double] -> Double
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum (((x, y, z, t) -> Double) -> [(x, y, z, t)] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map ((x, y, z, t) -> Getting Double (x, y, z, t) Double -> Double
forall s a. s -> Getting a s a -> a
^.(z -> Const Double z) -> (x, y, z, t) -> Const Double (x, y, z, t)
forall s t a b. Field3 s t a b => Lens s t a b
_3((z -> Const Double z)
 -> (x, y, z, t) -> Const Double (x, y, z, t))
-> ((Double -> Const Double Double) -> z -> Const Double z)
-> Getting Double (x, y, z, t) Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(z -> Double)
-> (Double -> Const Double Double) -> z -> Const Double z
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to z -> Double
forall a. PlotValue a => a -> Double
toValue) [(x, y, z, t)]
points)
                              scale :: a -> Double
scale a
v  = Double
n Double -> Double -> Double
forall a. Num a => a -> a -> a
* a -> Double
forall a. PlotValue a => a -> Double
toValue a
v Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
largest
                              colVals :: [Double]
colVals  = ((x, y, z, t) -> Double) -> [(x, y, z, t)] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map ((x, y, z, t) -> Getting Double (x, y, z, t) Double -> Double
forall s a. s -> Getting a s a -> a
^.(t -> Const Double t) -> (x, y, z, t) -> Const Double (x, y, z, t)
forall s t a b. Field4 s t a b => Lens s t a b
_4((t -> Const Double t)
 -> (x, y, z, t) -> Const Double (x, y, z, t))
-> ((Double -> Const Double Double) -> t -> Const Double t)
-> Getting Double (x, y, z, t) Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(t -> Double)
-> (Double -> Const Double Double) -> t -> Const Double t
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to t -> Double
forall a. PlotValue a => a -> Double
toValue) [(x, y, z, t)]
points
                              colMin :: Double
colMin   = [Double] -> Double
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [Double]
colVals
                              colMax :: Double
colMax   = [Double] -> Double
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [Double]
colVals
                              select :: a -> Int
select a
t = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (Int
cInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ 
                                         Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
truncate ( Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
c
                                                       Double -> Double -> Double
forall a. Num a => a -> a -> a
* (a -> Double
forall a. PlotValue a => a -> Double
toValue a
tDouble -> Double -> Double
forall a. Num a => a -> a -> a
-Double
colMin)
                                                       Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
colMaxDouble -> Double -> Double
forall a. Num a => a -> a -> a
-Double
colMin))
                          in ((x, y, z, t) -> (x, y, Double, Int))
-> [(x, y, z, t)] -> [(x, y, Double, Int)]
forall a b. (a -> b) -> [a] -> [b]
map (\ (x
x,y
y,z
z,t
t) -> (x
x,y
y, z -> Double
forall a. PlotValue a => a -> Double
scale z
z, t -> Int
forall a. PlotValue a => a -> Int
select t
t))
                                 [(x, y, z, t)]
points

renderSpotLegend4D :: AreaSpots4D z t x y -> Rect -> BackendProgram ()
renderSpotLegend4D :: AreaSpots4D z t x y -> Rect -> BackendProgram ()
renderSpotLegend4D AreaSpots4D z t x y
p (Rect Point
p1 Point
p2) = do
    let radius :: Double
radius = Double -> Double -> Double
forall a. Ord a => a -> a -> a
min (Double -> Double
forall a. Num a => a -> a
abs (Point -> Double
p_y Point
p1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Point -> Double
p_y Point
p2)) (Double -> Double
forall a. Num a => a -> a
abs (Point -> Double
p_x Point
p1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Point -> Double
p_x Point
p2))
        centre :: Point
centre = Point -> Point -> Point
linearInterpolate Point
p1 Point
p2
        palCol :: Colour Double
palCol = [Colour Double] -> Colour Double
forall a. [a] -> a
head ([Colour Double] -> Colour Double)
-> [Colour Double] -> Colour Double
forall a b. (a -> b) -> a -> b
$ AreaSpots4D z t x y -> [Colour Double]
forall z t x y. AreaSpots4D z t x y -> [Colour Double]
_area_spots_4d_palette AreaSpots4D z t x y
p
        psSpot :: PointStyle
psSpot = Double -> AlphaColour Double -> PointStyle
filledCircles Double
radius (AlphaColour Double -> PointStyle)
-> AlphaColour Double -> PointStyle
forall a b. (a -> b) -> a -> b
$ Colour Double -> Double -> AlphaColour Double
forall a. Num a => Colour a -> a -> AlphaColour a
withOpacity Colour Double
palCol
                                        (AreaSpots4D z t x y -> Double
forall z t x y. AreaSpots4D z t x y -> Double
_area_spots_4d_opacity AreaSpots4D z t x y
p)
        psOutline :: PointStyle
psOutline = Double -> Double -> AlphaColour Double -> PointStyle
hollowCircles Double
radius (AreaSpots4D z t x y -> Double
forall z t x y. AreaSpots4D z t x y -> Double
_area_spots_4d_linethick AreaSpots4D z t x y
p)
                                         (Colour Double -> AlphaColour Double
forall a. Num a => Colour a -> AlphaColour a
opaque Colour Double
palCol)
    PointStyle -> Point -> BackendProgram ()
drawPoint PointStyle
psSpot Point
centre
    PointStyle -> Point -> BackendProgram ()
drawPoint PointStyle
psOutline Point
centre
  where
    linearInterpolate :: Point -> Point -> Point
linearInterpolate (Point Double
x0 Double
y0) (Point Double
x1 Double
y1) =
        Double -> Double -> Point
Point (Double
x0 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
forall a. Num a => a -> a
abs(Double
x1Double -> Double -> Double
forall a. Num a => a -> a -> a
-Double
x0)Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2) (Double
y0 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
forall a. Num a => a -> a
abs(Double
y1Double -> Double -> Double
forall a. Num a => a -> a -> a
-Double
y0)Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2)

$( makeLenses ''AreaSpots )
$( makeLenses ''AreaSpots4D )