{-# LANGUAGE TemplateHaskell #-}
module Graphics.Rendering.Chart.Plot.Lines(
PlotLines(..),
defaultPlotLineStyle,
hlinePlot,
vlinePlot,
plot_lines_title,
plot_lines_style,
plot_lines_values,
plot_lines_limit_values,
) where
import Control.Lens
import Graphics.Rendering.Chart.Geometry
import Graphics.Rendering.Chart.Drawing
import Graphics.Rendering.Chart.Plot.Types
import Data.Colour (opaque)
import Data.Colour.Names (blue)
import Data.Default.Class
data PlotLines x y = PlotLines {
forall x y. PlotLines x y -> String
_plot_lines_title :: String,
forall x y. PlotLines x y -> LineStyle
_plot_lines_style :: LineStyle,
forall x y. PlotLines x y -> [[(x, y)]]
_plot_lines_values :: [[(x,y)]],
forall x y. PlotLines x y -> [[(Limit x, Limit y)]]
_plot_lines_limit_values :: [[(Limit x, Limit y)]]
}
instance ToPlot PlotLines where
toPlot :: forall x y. PlotLines x y -> Plot x y
toPlot PlotLines x y
p = Plot {
_plot_render :: PointMapFn x y -> BackendProgram ()
_plot_render = forall x y. PlotLines x y -> PointMapFn x y -> BackendProgram ()
renderPlotLines PlotLines x y
p,
_plot_legend :: [(String, Rect -> BackendProgram ())]
_plot_legend = [(forall x y. PlotLines x y -> String
_plot_lines_title PlotLines x y
p, forall x y. PlotLines x y -> Rect -> BackendProgram ()
renderPlotLegendLines PlotLines x y
p)],
_plot_all_points :: ([x], [y])
_plot_all_points = ( forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst [(x, y)]
pts forall a. [a] -> [a] -> [a]
++ [x]
xs, forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [(x, y)]
pts forall a. [a] -> [a] -> [a]
++ [y]
ys )
}
where
pts :: [(x, y)]
pts = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (forall x y. PlotLines x y -> [[(x, y)]]
_plot_lines_values PlotLines x y
p)
xs :: [x]
xs = [ x
x | (LValue x
x,Limit y
_) <- forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (forall x y. PlotLines x y -> [[(Limit x, Limit y)]]
_plot_lines_limit_values PlotLines x y
p)]
ys :: [y]
ys = [ y
y | (Limit x
_,LValue y
y) <- forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (forall x y. PlotLines x y -> [[(Limit x, Limit y)]]
_plot_lines_limit_values PlotLines x y
p)]
renderPlotLines :: PlotLines x y -> PointMapFn x y -> BackendProgram ()
renderPlotLines :: forall x y. PlotLines x y -> PointMapFn x y -> BackendProgram ()
renderPlotLines PlotLines x y
p PointMapFn x y
pmap =
forall a. LineStyle -> BackendProgram a -> BackendProgram a
withLineStyle (forall x y. PlotLines x y -> LineStyle
_plot_lines_style PlotLines x y
p) forall a b. (a -> b) -> a -> b
$ do
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall {a}. (a -> Point) -> [a] -> BackendProgram ()
drawLines (forall x y. PointMapFn x y -> (x, y) -> Point
mapXY PointMapFn x y
pmap)) (forall x y. PlotLines x y -> [[(x, y)]]
_plot_lines_values PlotLines x y
p)
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall {a}. (a -> Point) -> [a] -> BackendProgram ()
drawLines PointMapFn x y
pmap) (forall x y. PlotLines x y -> [[(Limit x, Limit y)]]
_plot_lines_limit_values PlotLines x y
p)
where
drawLines :: (a -> Point) -> [a] -> BackendProgram ()
drawLines a -> Point
mapfn [a]
pts = [Point] -> BackendProgram [Point]
alignStrokePoints (forall a b. (a -> b) -> [a] -> [b]
map a -> Point
mapfn [a]
pts) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Point] -> BackendProgram ()
strokePointPath
renderPlotLegendLines :: PlotLines x y -> Rect -> BackendProgram ()
renderPlotLegendLines :: forall x y. PlotLines x y -> Rect -> BackendProgram ()
renderPlotLegendLines PlotLines x y
p (Rect Point
p1 Point
p2) =
forall a. LineStyle -> BackendProgram a -> BackendProgram a
withLineStyle (forall x y. PlotLines x y -> LineStyle
_plot_lines_style PlotLines x y
p) forall a b. (a -> b) -> a -> b
$ do
let y :: Double
y = (Point -> Double
p_y Point
p1 forall a. Num a => a -> a -> a
+ Point -> Double
p_y Point
p2) forall a. Fractional a => a -> a -> a
/ Double
2
[Point]
ps <- [Point] -> BackendProgram [Point]
alignStrokePoints [Double -> Double -> Point
Point (Point -> Double
p_x Point
p1) Double
y, Double -> Double -> Point
Point (Point -> Double
p_x Point
p2) Double
y]
[Point] -> BackendProgram ()
strokePointPath [Point]
ps
defaultPlotLineStyle :: LineStyle
defaultPlotLineStyle :: LineStyle
defaultPlotLineStyle = (Double -> AlphaColour Double -> LineStyle
solidLine Double
1 forall a b. (a -> b) -> a -> b
$ forall a. Num a => Colour a -> AlphaColour a
opaque forall a. (Ord a, Floating a) => Colour a
blue){
_line_cap :: LineCap
_line_cap = LineCap
LineCapRound,
_line_join :: LineJoin
_line_join = LineJoin
LineJoinRound
}
instance Default (PlotLines x y) where
def :: PlotLines x y
def = PlotLines
{ _plot_lines_title :: String
_plot_lines_title = String
""
, _plot_lines_style :: LineStyle
_plot_lines_style = LineStyle
defaultPlotLineStyle
, _plot_lines_values :: [[(x, y)]]
_plot_lines_values = []
, _plot_lines_limit_values :: [[(Limit x, Limit y)]]
_plot_lines_limit_values = []
}
hlinePlot :: String -> LineStyle -> b -> Plot a b
hlinePlot :: forall b a. String -> LineStyle -> b -> Plot a b
hlinePlot String
t LineStyle
ls b
v = forall (a :: * -> * -> *) x y. ToPlot a => a x y -> Plot x y
toPlot forall a. Default a => a
def {
_plot_lines_title :: String
_plot_lines_title = String
t,
_plot_lines_style :: LineStyle
_plot_lines_style = LineStyle
ls,
_plot_lines_limit_values :: [[(Limit a, Limit b)]]
_plot_lines_limit_values = [[(forall a. Limit a
LMin, forall a. a -> Limit a
LValue b
v),(forall a. Limit a
LMax, forall a. a -> Limit a
LValue b
v)]]
}
vlinePlot :: String -> LineStyle -> a -> Plot a b
vlinePlot :: forall a b. String -> LineStyle -> a -> Plot a b
vlinePlot String
t LineStyle
ls a
v = forall (a :: * -> * -> *) x y. ToPlot a => a x y -> Plot x y
toPlot forall a. Default a => a
def {
_plot_lines_title :: String
_plot_lines_title = String
t,
_plot_lines_style :: LineStyle
_plot_lines_style = LineStyle
ls,
_plot_lines_limit_values :: [[(Limit a, Limit b)]]
_plot_lines_limit_values = [[(forall a. a -> Limit a
LValue a
v,forall a. Limit a
LMin),(forall a. a -> Limit a
LValue a
v,forall a. Limit a
LMax)]]
}
$( makeLenses ''PlotLines )