mirror of
https://github.com/IHaskell/IHaskell.git
synced 2025-04-19 12:56:08 +00:00
avoid switching directory in ihaskell-display
This commit is contained in:
parent
5bcfb8976c
commit
5bf443fb7c
@ -5,6 +5,7 @@ import Data.Default.Class
|
||||
import Graphics.Rendering.Chart.Renderable
|
||||
import Graphics.Rendering.Chart.Backend.Cairo
|
||||
import qualified Data.ByteString.Char8 as Char
|
||||
import System.IO.Temp
|
||||
import System.IO.Unsafe
|
||||
|
||||
import IHaskell.Display
|
||||
@ -27,16 +28,15 @@ instance IHaskellDisplay (Renderable a) where
|
||||
|
||||
chartData :: Renderable a -> FileFormat -> IO DisplayData
|
||||
chartData renderable format = do
|
||||
switchToTmpDir
|
||||
withSystemTempFile "ihaskell-chart.png" $ \path _ -> do
|
||||
|
||||
-- Write the PNG image.
|
||||
let filename = ".ihaskell-chart.png"
|
||||
opts = def { _fo_format = format, _fo_size = (width, height) }
|
||||
renderableToFile opts filename renderable
|
||||
-- Write the PNG image.
|
||||
let opts = def { _fo_format = format, _fo_size = (width, height) }
|
||||
renderableToFile opts path renderable
|
||||
|
||||
-- Convert to base64.
|
||||
imgData <- Char.readFile filename
|
||||
return $
|
||||
case format of
|
||||
PNG -> png width height $ base64 imgData
|
||||
SVG -> svg $ Char.unpack imgData
|
||||
-- Convert to base64.
|
||||
imgData <- Char.readFile path
|
||||
return $
|
||||
case format of
|
||||
PNG -> png width height $ base64 imgData
|
||||
SVG -> svg $ Char.unpack imgData
|
||||
|
@ -58,6 +58,7 @@ library
|
||||
bytestring,
|
||||
data-default-class,
|
||||
directory,
|
||||
temporary,
|
||||
Chart,
|
||||
Chart-cairo >=1.2,
|
||||
ihaskell >= 0.6.2
|
||||
|
@ -9,6 +9,7 @@ module IHaskell.Display.Diagrams
|
||||
|
||||
import qualified Data.ByteString.Char8 as Char
|
||||
import System.Directory
|
||||
import System.IO.Temp
|
||||
import Diagrams.Backend.Cairo
|
||||
import Diagrams.Prelude
|
||||
import IHaskell.Display
|
||||
@ -23,21 +24,20 @@ instance IHaskellDisplay (ManuallySized (QDiagram Cairo V2 Double Any)) where
|
||||
|
||||
diagramData :: ManuallySized (Diagram Cairo) -> OutputType -> IO DisplayData
|
||||
diagramData (ManuallySized renderable imgWidth imgHeight) format = do
|
||||
switchToTmpDir
|
||||
withSystemTempFile ("ihaskell-diagram." ++ extension format) $ \path _ -> do
|
||||
|
||||
-- Write the image.
|
||||
let filename = ".ihaskell-diagram." ++ extension format
|
||||
renderCairo filename (mkSizeSpec2D (Just imgWidth)
|
||||
(Just imgHeight)) renderable
|
||||
-- Write the image.
|
||||
renderCairo path (mkSizeSpec2D (Just imgWidth)
|
||||
(Just imgHeight)) renderable
|
||||
|
||||
-- Convert to base64.
|
||||
imgData <- Char.readFile filename
|
||||
let value =
|
||||
case format of
|
||||
PNG -> png (floor imgWidth) (floor imgHeight) $ base64 imgData
|
||||
SVG -> svg (Char.unpack imgData)
|
||||
-- Convert to base64.
|
||||
imgData <- Char.readFile path
|
||||
let value =
|
||||
case format of
|
||||
PNG -> png (floor imgWidth) (floor imgHeight) $ base64 imgData
|
||||
SVG -> svg (Char.unpack imgData)
|
||||
|
||||
return value
|
||||
return value
|
||||
|
||||
where
|
||||
extension SVG = "svg"
|
||||
|
@ -16,6 +16,7 @@ import Diagrams.Prelude
|
||||
import Diagrams.Backend.Cairo
|
||||
import Diagrams.Backend.Cairo.CmdLine (GifOpts(..))
|
||||
import Diagrams.Backend.CmdLine (DiagramOpts(..), mainRender)
|
||||
import System.IO.Temp
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Display.Diagrams.ImgSize
|
||||
@ -45,28 +46,27 @@ instance IHaskellDisplay (ManuallySized (ManuallySampled (QAnimation Cairo V2 Do
|
||||
|
||||
animationData :: ManuallySized (ManuallySampled (Animation Cairo V2 Double)) -> IO String
|
||||
animationData (ManuallySized (ManuallySampled renderable fps) imgWidth imgHeight) = do
|
||||
switchToTmpDir
|
||||
withSystemTempFile "ihaskell-diagram.gif" $ \path _ -> do
|
||||
|
||||
-- Generate the frames
|
||||
let actualFps = fromMaybe defaultFps fps
|
||||
animAdjusted = animEnvelope' actualFps renderable
|
||||
frames = simulate actualFps animAdjusted
|
||||
timediff = 100 `div` ceiling actualFps :: Int
|
||||
frameSet = map (\x -> (x # bg white, timediff)) frames
|
||||
-- Generate the frames
|
||||
let actualFps = fromMaybe defaultFps fps
|
||||
animAdjusted = animEnvelope' actualFps renderable
|
||||
frames = simulate actualFps animAdjusted
|
||||
timediff = 100 `div` ceiling actualFps :: Int
|
||||
frameSet = map (\x -> (x # bg white, timediff)) frames
|
||||
|
||||
-- Write the image.
|
||||
let filename = ".ihaskell-diagram.gif"
|
||||
diagOpts = DiagramOpts
|
||||
{ _width = Just . ceiling $ imgWidth
|
||||
, _height = Just . ceiling $ imgHeight
|
||||
, _output = filename
|
||||
}
|
||||
gifOpts = GifOpts { _dither = True, _noLooping = False, _loopRepeat = Nothing }
|
||||
mainRender (diagOpts, gifOpts) frameSet
|
||||
-- Write the image.
|
||||
let diagOpts = DiagramOpts
|
||||
{ _width = Just . ceiling $ imgWidth
|
||||
, _height = Just . ceiling $ imgHeight
|
||||
, _output = path
|
||||
}
|
||||
gifOpts = GifOpts { _dither = True, _noLooping = False, _loopRepeat = Nothing }
|
||||
mainRender (diagOpts, gifOpts) frameSet
|
||||
|
||||
-- Convert to ascii represented base64 encoding
|
||||
imgData <- CBS.readFile filename
|
||||
return . T.unpack . base64 $ imgData
|
||||
-- Convert to ascii represented base64 encoding
|
||||
imgData <- CBS.readFile path
|
||||
return . T.unpack . base64 $ imgData
|
||||
|
||||
|
||||
-- Rendering hint.
|
||||
@ -134,4 +134,4 @@ instance IHaskellDisplay (ManuallySampled (ManuallySized (QAnimation Cairo V2 Do
|
||||
display (ManuallySampled (ManuallySized renderable w h) fps) = out
|
||||
where
|
||||
sizeSpec = mkSizeSpec2D (Just w) (Just h)
|
||||
out = display . withSizeSpec sizeSpec $ withSamplingSpec fps renderable
|
||||
out = display . withSizeSpec sizeSpec $ withSamplingSpec fps renderable
|
||||
|
@ -59,6 +59,7 @@ library
|
||||
text,
|
||||
bytestring,
|
||||
directory,
|
||||
temporary,
|
||||
-- Use diagrams wrapper package to ensure all same versions of subpackages
|
||||
diagrams >= 1.3,
|
||||
diagrams-lib,
|
||||
|
@ -21,6 +21,7 @@ import qualified Graphics.Gnuplot.Terminal.SVG as Sv
|
||||
import qualified Graphics.Gnuplot.Graph.TwoDimensional as Tw
|
||||
import qualified Graphics.Gnuplot.Graph.ThreeDimensional as Th
|
||||
import qualified Data.ByteString.Char8 as Char
|
||||
import System.IO.Temp
|
||||
import Graphics.Gnuplot.Advanced (plot)
|
||||
import Graphics.Gnuplot.Value.Atom (C)
|
||||
import IHaskell.Display
|
||||
@ -58,9 +59,6 @@ instance IHaskellDisplay M.T where
|
||||
svgDisp <- graphDataSVGM fig
|
||||
return $ Display [pngDisp, svgDisp]
|
||||
|
||||
-- Filename
|
||||
name = ".ihaskell-gnuplot."
|
||||
|
||||
-- Width and height
|
||||
w = 300
|
||||
|
||||
@ -68,120 +66,110 @@ h = 300
|
||||
|
||||
graphDataPNG2P :: (C x, C y) => P.T (Tw.T x y) -> IO DisplayData
|
||||
graphDataPNG2P graph = do
|
||||
switchToTmpDir
|
||||
withSystemTempFile "ihaskell-gnuplot.png" $ \path _ -> do
|
||||
|
||||
-- Write the image.
|
||||
let fname = Pn.cons $ name ++ "png"
|
||||
plot fname graph
|
||||
-- Write the image.
|
||||
plot (Pn.cons path) graph
|
||||
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile $ name ++ "png"
|
||||
return $ png w h $ base64 imgData
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile path
|
||||
return $ png w h $ base64 imgData
|
||||
|
||||
graphDataSVG2P :: (C x, C y) => P.T (Tw.T x y) -> IO DisplayData
|
||||
graphDataSVG2P graph = do
|
||||
switchToTmpDir
|
||||
withSystemTempFile "ihaskell-gnuplot.svg" $ \path _ -> do
|
||||
|
||||
-- Write the image.
|
||||
let fname = Sv.cons $ name ++ "svg"
|
||||
plot fname graph
|
||||
-- Write the image.
|
||||
plot (Sv.cons path) graph
|
||||
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile $ name ++ "svg"
|
||||
return $ svg $ Char.unpack imgData
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile path
|
||||
return $ svg $ Char.unpack imgData
|
||||
|
||||
graphDataPNG2F :: (C x, C y) => F.T (Tw.T x y) -> IO DisplayData
|
||||
graphDataPNG2F graph = do
|
||||
switchToTmpDir
|
||||
withSystemTempFile "ihaskell-gnuplot.png" $ \path _ -> do
|
||||
|
||||
-- Write the image.
|
||||
let fname = Pn.cons $ name ++ "png"
|
||||
plot fname graph
|
||||
-- Write the image.
|
||||
plot (Pn.cons path) graph
|
||||
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile $ name ++ "png"
|
||||
return $ png w h $ base64 imgData
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile path
|
||||
return $ png w h $ base64 imgData
|
||||
|
||||
graphDataSVG2F :: (C x, C y) => F.T (Tw.T x y) -> IO DisplayData
|
||||
graphDataSVG2F graph = do
|
||||
switchToTmpDir
|
||||
withSystemTempFile "ihaskell-gnuplot.svg" $ \path _ -> do
|
||||
|
||||
-- Write the image.
|
||||
let fname = Sv.cons $ name ++ "svg"
|
||||
plot fname graph
|
||||
-- Write the image.
|
||||
plot (Sv.cons path) graph
|
||||
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile $ name ++ "svg"
|
||||
return $ svg $ Char.unpack imgData
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile path
|
||||
return $ svg $ Char.unpack imgData
|
||||
|
||||
graphDataPNG3P :: (C x, C y, C z) => P.T (Th.T x y z) -> IO DisplayData
|
||||
graphDataPNG3P graph = do
|
||||
switchToTmpDir
|
||||
withSystemTempFile "ihaskell-gnuplot.png" $ \path _ -> do
|
||||
|
||||
-- Write the image.
|
||||
let fname = Pn.cons $ name ++ "png"
|
||||
plot fname graph
|
||||
-- Write the image.
|
||||
plot (Pn.cons path) graph
|
||||
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile $ name ++ "png"
|
||||
return $ png w h $ base64 imgData
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile path
|
||||
return $ png w h $ base64 imgData
|
||||
|
||||
graphDataSVG3P :: (C x, C y, C z) => P.T (Th.T x y z) -> IO DisplayData
|
||||
graphDataSVG3P graph = do
|
||||
switchToTmpDir
|
||||
withSystemTempFile "ihaskell-gnuplot.svg" $ \path _ -> do
|
||||
|
||||
-- Write the image.
|
||||
let fname = Sv.cons $ name ++ "svg"
|
||||
plot fname graph
|
||||
-- Write the image.
|
||||
plot (Sv.cons path) graph
|
||||
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile $ name ++ "svg"
|
||||
return $ svg $ Char.unpack imgData
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile path
|
||||
return $ svg $ Char.unpack imgData
|
||||
|
||||
graphDataPNG3F :: (C x, C y, C z) => F.T (Th.T x y z) -> IO DisplayData
|
||||
graphDataPNG3F graph = do
|
||||
switchToTmpDir
|
||||
withSystemTempFile "ihaskell-gnuplot.png" $ \path _ -> do
|
||||
|
||||
-- Write the image.
|
||||
let fname = Pn.cons $ name ++ "png"
|
||||
plot fname graph
|
||||
-- Write the image.
|
||||
plot (Pn.cons path) graph
|
||||
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile $ name ++ "png"
|
||||
return $ png w h $ base64 imgData
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile path
|
||||
return $ png w h $ base64 imgData
|
||||
|
||||
graphDataSVG3F :: (C x, C y, C z) => F.T (Th.T x y z) -> IO DisplayData
|
||||
graphDataSVG3F graph = do
|
||||
switchToTmpDir
|
||||
withSystemTempFile "ihaskell-gnuplot.svg" $ \path _ -> do
|
||||
|
||||
-- Write the image.
|
||||
let fname = Sv.cons $ name ++ "svg"
|
||||
plot fname graph
|
||||
-- Write the image.
|
||||
plot (Sv.cons path) graph
|
||||
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile $ name ++ "svg"
|
||||
return $ svg $ Char.unpack imgData
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile path
|
||||
return $ svg $ Char.unpack imgData
|
||||
|
||||
graphDataPNGM :: M.T -> IO DisplayData
|
||||
graphDataPNGM graph = do
|
||||
switchToTmpDir
|
||||
withSystemTempFile "ihaskell-gnuplot.png" $ \path _ -> do
|
||||
|
||||
-- Write the image.
|
||||
let fname = Pn.cons $ name ++ "png"
|
||||
plot fname graph
|
||||
-- Write the image.
|
||||
plot (Pn.cons path) graph
|
||||
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile $ name ++ "png"
|
||||
return $ png w h $ base64 imgData
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile path
|
||||
return $ png w h $ base64 imgData
|
||||
|
||||
graphDataSVGM :: M.T -> IO DisplayData
|
||||
graphDataSVGM graph = do
|
||||
switchToTmpDir
|
||||
withSystemTempFile "ihaskell-gnuplot.svg" $ \path _ -> do
|
||||
|
||||
-- Write the image.
|
||||
let fname = Sv.cons $ name ++ "svg"
|
||||
plot fname graph
|
||||
-- Write the image.
|
||||
plot (Sv.cons path) graph
|
||||
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile $ name ++ "svg"
|
||||
return $ svg $ Char.unpack imgData
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile path
|
||||
return $ svg $ Char.unpack imgData
|
||||
|
@ -56,6 +56,7 @@ library
|
||||
-- Other library packages from which modules are imported.
|
||||
build-depends: base >=4.9 && <5,
|
||||
bytestring,
|
||||
temporary,
|
||||
gnuplot >= 0.5.4,
|
||||
ihaskell >= 0.6.2
|
||||
|
||||
|
@ -4,6 +4,7 @@ import qualified Data.ByteString.Char8 as Char
|
||||
import Graphics.Rendering.Plot
|
||||
import Control.Monad (void)
|
||||
import Control.Applicative ((<$>))
|
||||
import System.IO.Temp
|
||||
|
||||
import IHaskell.Display
|
||||
|
||||
@ -16,26 +17,25 @@ instance IHaskellDisplay (Figure a) where
|
||||
|
||||
figureData :: Figure () -> OutputType -> IO DisplayData
|
||||
figureData figure format = do
|
||||
switchToTmpDir
|
||||
withSystemTempFile ("ihaskell-plot." ++ extension format) $ \path _ -> do
|
||||
|
||||
-- Width and height
|
||||
let size = 300
|
||||
w = size
|
||||
h = size
|
||||
-- Width and height
|
||||
let size = 300
|
||||
w = size
|
||||
h = size
|
||||
|
||||
-- Write the image.
|
||||
let fname = ".ihaskell-plot." ++ extension format
|
||||
writeFigure format fname (w, h) figure
|
||||
-- Write the image.
|
||||
writeFigure format path (w, h) figure
|
||||
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile fname
|
||||
let value =
|
||||
case format of
|
||||
PNG -> png w h $ base64 imgData
|
||||
SVG -> svg $ Char.unpack imgData
|
||||
_ -> error "Unsupported format for display"
|
||||
-- Read back, and convert to base64.
|
||||
imgData <- Char.readFile path
|
||||
let value =
|
||||
case format of
|
||||
PNG -> png w h $ base64 imgData
|
||||
SVG -> svg $ Char.unpack imgData
|
||||
_ -> error "Unsupported format for display"
|
||||
|
||||
return value
|
||||
return value
|
||||
|
||||
where
|
||||
extension SVG = "svg"
|
||||
|
@ -57,6 +57,7 @@ library
|
||||
build-depends: base >=4.9 && <5,
|
||||
plot,
|
||||
bytestring,
|
||||
temporary,
|
||||
hmatrix >= 0.10,
|
||||
ihaskell >= 0.6.2
|
||||
|
||||
|
@ -48,9 +48,6 @@ module IHaskell.Display (
|
||||
encode64,
|
||||
base64,
|
||||
|
||||
-- ** Utilities
|
||||
switchToTmpDir,
|
||||
|
||||
-- * Internal only use
|
||||
displayFromChanEncoded,
|
||||
serializeDisplay,
|
||||
@ -64,10 +61,8 @@ import qualified Data.ByteString.Lazy as LBS
|
||||
|
||||
import Data.Binary as Binary
|
||||
import qualified Data.ByteString.Base64 as Base64
|
||||
import System.Directory (getTemporaryDirectory, setCurrentDirectory)
|
||||
|
||||
import Control.Concurrent.STM (atomically)
|
||||
import Control.Exception (try)
|
||||
import Control.Concurrent.STM.TChan
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
|
||||
@ -184,12 +179,3 @@ displayFromChanEncoded =
|
||||
-- execution call ends.
|
||||
printDisplay :: IHaskellDisplay a => a -> IO ()
|
||||
printDisplay disp = display disp >>= atomically . writeTChan displayChan
|
||||
|
||||
-- | Convenience function for client libraries. Switch to a temporary directory so that any files we
|
||||
-- create aren't visible. On Unix, this is usually /tmp.
|
||||
switchToTmpDir :: IO ()
|
||||
switchToTmpDir = void (try switchDir :: IO (Either SomeException ()))
|
||||
where
|
||||
switchDir =
|
||||
getTemporaryDirectory >>=
|
||||
setCurrentDirectory
|
||||
|
Loading…
x
Reference in New Issue
Block a user