{-# OPTIONS_GHC -Wall #-} module PlotHo.PlotChart ( AxisScaling(..) , displayChart , chartGtkUpdateCanvas ) where import Control.Lens ( (.~) ) import Data.Default.Class ( def ) --import qualified Data.Foldable as F --import qualified Data.Sequence as S import qualified Graphics.UI.Gtk as Gtk import qualified Graphics.Rendering.Chart as Chart import Graphics.Rendering.Chart.Backend.Cairo ( runBackend, defaultEnv ) import Graphics.Rendering.Cairo hiding (width, height) --( Render, Format(..) --, renderWith, setSourceSurface, withImageSurface ) import PlotHo.PlotTypes ( AxisScaling(..) ) chartGtkUpdateCanvas :: Chart.Renderable () -> Gtk.DrawingArea -> IO () chartGtkUpdateCanvas chart canvas = do Gtk.threadsEnter maybeWin <- Gtk.widgetGetWindow canvas case maybeWin of Nothing -> Gtk.threadsLeave >> return () Just win -> do (width, height) <- Gtk.widgetGetSize canvas regio <- Gtk.regionRectangle $ Gtk.Rectangle 0 0 width height Gtk.threadsLeave let sz = (fromIntegral width,fromIntegral height) let render0 :: Render (Chart.PickFn ()) render0 = runBackend (defaultEnv Chart.bitmapAlignmentFns) (Chart.render chart sz) withImageSurface FormatARGB32 width height $ \surface -> do _ <- renderWith surface render0 let render1 = setSourceSurface surface 0 0 >> paint Gtk.threadsEnter Gtk.drawWindowBeginPaintRegion win regio _ <- Gtk.renderWithDrawable win render1 Gtk.drawWindowEndPaint win Gtk.threadsLeave displayChart :: (Chart.PlotValue a, Show a, RealFloat a) => (AxisScaling, AxisScaling) -> (Maybe (a,a),Maybe (a,a)) -> [(String, [[(a,a)]])] -> Chart.Renderable () displayChart (xScaling,yScaling) (xRange,yRange) namePcs = Chart.toRenderable layout where drawOne (name,pc) col = Chart.plot_lines_values .~ pc $ Chart.plot_lines_style . Chart.line_color .~ col -- $ Chart.plot_points_style ~. Chart.filledCircles 2 red $ Chart.plot_lines_title .~ name $ def allLines = zipWith drawOne namePcs Chart.defaultColorSeq xscaleFun = case xScaling of LogScaling -> Chart.layout_x_axis . Chart.laxis_generate .~ Chart.autoScaledLogAxis def LinearScaling -> case xRange of Nothing -> id Just range -> Chart.layout_x_axis . Chart.laxis_generate .~ Chart.scaledAxis def range yscaleFun = case yScaling of LogScaling -> Chart.layout_y_axis . Chart.laxis_generate .~ Chart.autoScaledLogAxis def LinearScaling -> case yRange of Nothing -> id Just range -> Chart.layout_y_axis . Chart.laxis_generate .~ Chart.scaledAxis def range layout = Chart.layout_plots .~ map Chart.toPlot allLines -- $ Chart.layout_title .~ "Wooo, Party Graph!" $ Chart.layout_x_axis . Chart.laxis_title .~ "time [s]" $ xscaleFun $ yscaleFun def