{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} ----------------------------------------------------------------------------- -- | -- Module : Graphics.Rendering.Plot.Figure -- Copyright : (c) A. V. H. McPhail 2010 -- License : BSD3 -- -- Maintainer : haskell.vivian.mcphail gmail com -- Stability : provisional -- Portability : portable -- -- Creation and manipulation of 'Figure's -- -- The same problem of leaked instances as at occurs here. -- -- -- /with/, /set/, /clear/, /new/, and /add/ are the operations that can -- be performed on various elements of a figure. -- -- /glib/\//data-accessor/ abstractions (verbs/modifiers) are planned for future implementations ----------------------------------------------------------------------------- module Graphics.Rendering.Plot.Figure ( module Data.Colour.Names -- * Top level operation , Figure(), FigureState() -- * Default options , withTextDefaults , withLineDefaults , withPointDefaults , withBarDefaults -- * Figures , newFigure -- ** Formatting , setFigurePadding , withTitle , withSubTitle , setPlots , withPlot, withPlots -- * Sub-plots , Plot() -- ** Plot elements , Border , setBorder , setPlotPadding , withHeading -- ** Series data , Function(), Series(), MinMaxSeries(), ErrorSeries() , Surface() , SeriesLabel() , Abscissa(), Ordinate(), Dataset() , FormattedSeries(), SeriesType(..) , line, point, linepoint , impulse, step , area , bar , hist , candle, whisker , setDataset -- * Annotations , Location, Head, Fill , Annote() , arrow , oval , rect , glyph , text , cairo , withAnnotations -- ** Plot type , setSeriesType , setAllSeriesTypes -- ** Formatting , PlotFormats() , withSeriesFormat , withAllSeriesFormats -- * Range , Scale(..) , setRange , setRangeFromData -- * Axes , Axis , AxisType(..),AxisSide(..),AxisPosn(..) , clearAxes , clearAxis , addAxis , withAxis -- * Legend , Legend , LegendBorder , LegendLocation(..), LegendOrientation(..) , clearLegend , setLegend , withLegendFormat -- ** Formatting , Tick(..), TickValues(..), GridLines , setTicks , setGridlines , setTickLabelFormat , setTickLabels , withTickLabelFormat , withAxisLabel , withAxisLine , withGridLine -- * Lines , Line(), LineFormat() , DashStyle,Dash(..),LineWidth , clearLineFormat , setDashStyle , setLineWidth , setLineColour -- * Points , Point(), PointFormat() , Glyph(..) , PointSize , setGlyph , setPointSize , setPointColour -- * Bars , Bar(), BarFormat() , clearBarFormat , setBarWidth , setBarColour , setBarBorderWidth , setBarBorderColour -- * Text labels , Text() , FontFamily,FontSize,Color -- | A text element must exist for formatting to work , clearText , clearTextFormat , setText , setFontFamily , setFontStyle , setFontVariant , setFontWeight , setFontStretch , setFontSize , setFontColour ) where ----------------------------------------------------------------------------- --import Data.Packed.Vector --import Numeric.LinearAlgebra.Linear --import Data.Word --import Data.Colour.SRGB import Data.Colour.Names import qualified Data.Array.IArray as A --import qualified Graphics.Rendering.Cairo as C --import qualified Graphics.Rendering.Pango as P --import Control.Monad.State --import Control.Monad.Reader import Prelude hiding(min,max) import Graphics.Rendering.Plot.Figure.Text import Graphics.Rendering.Plot.Figure.Line import Graphics.Rendering.Plot.Figure.Point import Graphics.Rendering.Plot.Figure.Bar import Graphics.Rendering.Plot.Figure.Plot import Graphics.Rendering.Plot.Types import Graphics.Rendering.Plot.Defaults ----------------------------------------------------------------------------- -- | perform some actions on the text defaults, must be run before other text element modifications withTextDefaults :: Text () -> Figure () withTextDefaults m = do o <- getDefaults let to' = _textoptions o let (FontText to _) = execText m to' (FontText to' "") modifyDefaults $ \s -> s { _textoptions = to } -- | perform some actions on the line defaults, must be run before other line element modifications withLineDefaults :: Line () -> Figure () withLineDefaults m = do o <- getDefaults let lo' = _lineoptions o let (TypeLine lo _) = execLine m lo' (TypeLine lo' black) modifyDefaults $ \s -> s { _lineoptions = lo } -- | perform some actions on the point defaults, must be run before other point modifications withPointDefaults :: Point () -> Figure () withPointDefaults m = do o <- getDefaults let po' = _pointoptions o let (FullPoint po _) = execPoint m po' (FullPoint po' defaultGlyph) modifyDefaults $ \s -> s { _pointoptions = po } -- | perform some actions on the bar defaults, must be run before other point modifications withBarDefaults :: Bar () -> Figure () withBarDefaults m = do o <- getDefaults let bo' = _baroptions o let (TypeBar bo _) = execBar m bo' (TypeBar bo' black) modifyDefaults $ \s -> s { _baroptions = bo } ----------------------------------------------------------------------------- -- | create a new blank 'Figure' newFigure :: Figure () newFigure = putFigure $ Figure defaultFigurePadding NoText NoText (A.listArray ((1,1),(1,1)) [Nothing]) {- newLineFigure :: DataSeries -- ^ the y series -> FigureData newLineFigure d@(DS_1toN _ _) = let ((xmin,xmax),(ymin,ymax)) = calculateRanges d plot = Plot False defaultPlotPadding NoText (defaultRanges xmin xmax ymin ymax) [defaultXAxis,defaultYAxis] Nothing Line d [] in Figure defaultFigurePadding NoText NoText (A.listArray ((1,1),(1,1)) [Just plot]) -} {- -- | create a new 'Figure' newFigure :: PlotType -> DataSeries -> Figure () newFigure Line d@(DS_1toN _ _) = putFigure $ newLineFigure d --newFigure _ _ = error "Figure type not implemented" -} ----------------------------------------------------------------------------- -- | set the padding of the figure setFigurePadding :: Double -> Double -> Double -> Double -> Figure () setFigurePadding l r b t = modifyFigure $ \s -> s { _fig_pads = Padding l r b t } -- | operate on the title withTitle :: Text () -> Figure () withTitle m = do o <- getDefaults modifyFigure $ \s -> s { _title = execText m (_textoptions o) (_title s) } -- | operate on the sub-title withSubTitle :: Text () -> Figure () withSubTitle m = do o <- getDefaults modifyFigure $ \s -> s { _subtitle = execText m (_textoptions o) (_title s) } -- | set the shape of the plots, losing all current plots setPlots :: Int -- ^ rows -> Int -- ^ columns -> Figure () setPlots r c = modifyFigure $ \s -> s { _plots = A.listArray ((1,1),(r,c)) (replicate (r*c) Nothing) } -- | perform some actions on the specified subplot withPlot :: (Int,Int) -> Plot () -> Figure () withPlot i m = do o <- getDefaults s <- getSupplies modifyFigure $ \p -> p { _plots = let plots = _plots p plot' = plots A.! i plot = case plot' of Nothing -> emptyPlot Just p' -> p' -- we revert supplies to the original here -- since we might want the same colour -- order for all plots -- HOWEVER: need a better execPlot group in plots A.// [(i,Just $ execPlot m s o plot)] } -- | perform some actions all subplots withPlots :: Plot () -> Figure () withPlots m = do o <- getDefaults s <- getSupplies modifyFigure $ \p -> p { _plots = let plots = _plots p plot p' = case p' of Nothing -> emptyPlot Just p'' -> p'' in plots A.// map (\(i,e) -> (i,Just $ execPlot m s o (plot e))) (A.assocs plots) } -----------------------------------------------------------------------------