{-| Module : Plot Description : main module for the plot library Copyright : (C) Jonathan Lamothe License : AGPL-3.0-or-later Maintainer : jonathan@jlamothe.net Stability : experimental Portability : POSIX This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . -} module Plot ( -- * Types and Constructors Plottable (..), Plot, -- * Constructors newPlot, -- * Helpers valAtXY' ) where -- | defines values that can be plotted class Plottable p where -- | gets the width of the plottable area plotWidth :: p a -> Int -- | gets the height of the plottable area plotHeight :: p a -> Int -- | gets the value at a given (X, Y) coordinate (if available) valAtXY :: (Int, Int) -> p a -> Maybe a -- | transforms a plottable value transformPlot :: ((Int, Int) -> p a -> Maybe b) -- ^ transformation function that returns a new value based on an -- (X, Y) coordinate and the old plottable value -> p a -- ^ the initial plottable value -> p b -- ^ the new plottable value -- | fills every coordinate with a given value plotFill :: a -- ^ the value to fill with -> p a -- ^ the 'Plottable' value being modified -> p a -- ^ the resulting 'Plottable' value plotFill val = transformPlot (\_ _ -> Just val) -- | plots a value at a given set of coordinates plotVal :: (Int, Int) -- ^ the coordinates where the value will be plotted -> a -- ^ The vlaue being plotted -> p a -- ^ the 'Plottable' value being modified -> p a -- ^ the resulting 'Plottable' value plotVal coords val = transformPlot ( \c p -> if c == coords then Just val else valAtXY c p ) -- clears the value at a given set of coordinates from a 'Plottable' -- value clearVal :: (Int, Int) -- ^ the coordinates to delete the value from -> p a -- ^ the 'Plottable' value being modified -> p a -- ^ the resulting 'Plottable' value clearVal coords = transformPlot ( \c p -> if c == coords then Nothing else valAtXY c p ) -- | a basic 'Plottable' type data Plot a = Plot { pWidth :: Int , pHeight :: Int , pVal :: (Int, Int) -> Maybe a } instance Plottable Plot where plotWidth = pWidth plotHeight = pHeight valAtXY = flip pVal transformPlot f plot = Plot { pWidth = pWidth plot , pHeight = pHeight plot , pVal = flip f plot } -- | creates a new blank 'Plot' value newPlot :: Int -- ^ the width of the plottable area -> Int -- ^ the height of the plottable area -> Plot a newPlot w h = Plot { pWidth = w , pHeight = h , pVal = const Nothing } -- | gets the value at a given (X, Y) coordinate, returning Nothing -- when outside the plottable range valAtXY' :: Plottable p => (Int, Int) -> p a -> Maybe a valAtXY' (x, y) plot | x < 0 = Nothing | x >= plotWidth plot = Nothing | y < 0 = Nothing | y >= plotHeight plot = Nothing | otherwise = valAtXY (x, y) plot --jl