{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE DataKinds #-}
{-# OPTIONS_GHC -Wall #-}
module Chart.ADT
( ChartOptions(..)
, ChartSpec(..)
, renderSpec
, renderChart
, rangeSpec
, rangeChart
) where
import Chart.Arrow
import Chart.Bar
import Chart.Core
import Chart.Glyph
import Chart.Hud
import Chart.Line
import Chart.Rect
import Chart.Text
import Control.Lens
import Data.Default
import Data.Generics.Product (field)
import NumHask.Pair
import NumHask.Prelude
import NumHask.Rect
import NumHask.Space
data ChartSpec
= GlyphChart [(GlyphOptions, [Pair Double])]
| LGlyphChart [(LabelOptions, GlyphOptions, [(Text, Pair Double)])]
| LineChart [(LineOptions, [Pair Double])]
| GlineChart [(LineOptions, GlyphOptions, [Pair Double])]
| TextChart [(TextOptions, [(Text, Pair Double)])]
| RectChart [(RectOptions, [Rect Double])]
| PixelChart [[Pixel]]
| ArrowChart [(ArrowOptions, [Arrow])]
| BarChart BarOptions BarData
| HudChart HudOptions
deriving (Show, Generic)
data ChartOptions = ChartOptions
{ chartRange :: Maybe (Rect Double)
, chartAspect :: Rect Double
, charts :: [ChartSpec]
} deriving (Show, Generic)
instance Default ChartOptions where
def = ChartOptions Nothing sixbyfour []
renderChart :: ChartOptions -> Chart b
renderChart ch@(ChartOptions _ a cs) =
mconcat (renderSpec a (rangeChart ch) <$> cs)
renderSpec :: Rect Double -> Rect Double -> ChartSpec -> Chart b
renderSpec a r (GlyphChart xs) = glyphChart (fst <$> xs) a r (snd <$> xs)
renderSpec a r (LGlyphChart xs) =
lglyphChart
((\(x,_,_) -> x) <$> xs)
((\(_,x,_) -> x) <$> xs)
a
r
((\(_,_,x) -> x) <$> xs)
renderSpec a r (LineChart xs) = lineChart (fst <$> xs) a r (snd <$> xs)
renderSpec a r (GlineChart xs) =
glineChart
((\(x,_,_) -> x) <$> xs)
((\(_,x,_) -> x) <$> xs)
a
r
((\(_,_,x) -> x) <$> xs)
renderSpec a r (TextChart xs) = textChart (fst <$> xs) a r (snd <$> xs)
renderSpec a r (RectChart xs) = rectChart (fst <$> xs) a r (snd <$> xs)
renderSpec a r (PixelChart xs) = pixelChart a r xs
renderSpec a r (ArrowChart xs) = arrowChart (fst <$> xs) a r (snd <$> xs)
renderSpec _ _ (BarChart o d) = barChart o d
renderSpec a r (HudChart o) = hud o a r
rangeSpec :: ChartSpec -> Maybe (Rect Double)
rangeSpec (GlyphChart xs) = Just $ range (snd <$> xs)
rangeSpec (LGlyphChart xs) = Just $ range $ (\x -> fmap snd . toList <$> x)
((\(_,_,x) -> x) <$> xs)
rangeSpec (LineChart xs) = Just $ range (snd <$> xs)
rangeSpec (GlineChart xs) = Just $ range ((\(_,_,x) -> x) <$> xs)
rangeSpec (TextChart xs) = Just $ range $ (\x -> fmap snd . toList <$> x) (snd <$> xs)
rangeSpec (RectChart xs) = Just $ (\rs -> fold $ fold <$> rs) (snd <$> xs)
rangeSpec (PixelChart xs) = Just $ fold $ fold . map pixelRect <$> xs
rangeSpec (ArrowChart xs) = Just $ (\xss -> fold (space . map arrowPos <$> xss)) (snd <$> xs)
rangeSpec (BarChart _ d) = Just $ barRange (d ^. field @"barData")
rangeSpec (HudChart _) = Nothing
rangeChart :: ChartOptions -> Rect Double
rangeChart (ChartOptions mr _ cs) = fromMaybe (mconcat $ catMaybes (rangeSpec <$> cs)) mr