module Graphics.Rendering.Plot.Render.Plot.Annotation (
renderAnnotations
) where
import qualified Graphics.Rendering.Cairo as C
import Control.Monad.Reader
import Control.Monad.State
import Graphics.Rendering.Plot.Types
import Graphics.Rendering.Plot.Render.Types
import Graphics.Rendering.Plot.Render.Text
import Graphics.Rendering.Plot.Render.Plot.Glyph
import Graphics.Rendering.Plot.Render.Plot.Format
renderAnnotations :: Ranges -> Annotations -> Render ()
renderAnnotations r an = do
(BoundingBox x y w h) <- get
let (xsc,xmin',xmax') = getRanges XAxis Lower r
let (xmin,xmax) = if xsc == Log then (logBase 10 xmin',logBase 10 xmax') else (xmin',xmax')
let xscale = w/(xmaxxmin)
cairo $ C.save
let (yscl,yminl',ymaxl') = getRanges YAxis Lower r
let (yminl,ymaxl) = if yscl == Log then (logBase 10 yminl',logBase 10 ymaxl') else (yminl',ymaxl')
let yscalel = h/(ymaxlyminl)
cairo $ do
C.translate x (y+h)
C.scale xscale yscalel
C.translate (xmin) yminl
flipVertical
put (BoundingBox (xmin) (yminl) (xmaxxmin) (ymaxlyminl))
mapM_ (renderAnnotation xscale yscalel) an
put (BoundingBox x y w h)
cairo $ C.restore
renderAnnotation :: Double -> Double -> Annotation -> Render ()
renderAnnotation xsc ysc (AnnArrow h lt (x1,y1) (x2,y2)) = do
formatLineSeries lt xsc ysc
cairo $ do
C.moveTo x1 y1
C.lineTo x2 y2
C.stroke
when h (do
C.moveTo x2 y2
let theta = atan2 (y2y1) (x2x1)
lw <- C.getLineWidth
let ln = lw*10
cx = x2 ln * cos theta
cy = y2 ln * sin theta
xl = cx + (ln/2) * sin (theta + pi/2)
yl = cy + (ln/2) * cos (theta + pi/2)
xu = cx + (ln/2) * sin (theta pi/2)
yu = cy + (ln/2) * cos (theta pi/2)
C.lineTo xl yl
C.lineTo xu yu
C.closePath
C.fill
)
C.stroke
renderAnnotation xsc ysc (AnnOval f b (x1,y1) (x2,y2)) = do
(_,bc,c) <- formatBarSeries b xsc ysc
let width = x2 x1
height = y2 y1
x = x1 + width/2
y = y1 + height/2
cairo $ do
C.save
setColour c
C.translate (x + width / 2) (y + height / 2)
C.scale (1 / (height / 2)) (1 / (width / 2))
C.arc 0 0 1 0 (2 * pi)
C.restore
C.strokePreserve
when f (do
setColour bc
C.fill)
C.newPath
renderAnnotation xsc ysc (AnnRect f b (x1,y1) (x2,y2)) = do
(_,bc,c) <- formatBarSeries b xsc ysc
cairo $ do
C.save
setColour c
C.rectangle x1 y1 x2 y2
C.restore
C.strokePreserve
when f (do
setColour bc
C.fill)
C.newPath
renderAnnotation xsc ysc (AnnGlyph pt (x1,y1)) = do
(pw,g) <- formatPointSeries pt xsc ysc
cairo $ do
C.moveTo x1 y1
renderGlyph xsc ysc pw g
renderAnnotation xsc ysc (AnnText te (x1,y1)) = do
cairo $ do
C.save
C.scale (recip xsc) (recip (ysc))
_ <- renderText te TRight TTop (x1*xsc) (y1*ysc)
cairo $ C.restore
return ()
renderAnnotation _ _ (AnnCairo r) = do
(BoundingBox x y w h) <- get
cairo $ do
C.save
r x y w h
C.restore