packages feed

a50-0.2: src/Gnuplot.hs

module Gnuplot where    

import System.Process
import System.Exit
import System.IO
import Data.List (intersperse)

import Control.Monad (when)
import System.Directory (findExecutable)
import Control.Concurrent (forkIO)

gnuplot :: Num i => [String] -> [(String,[i])] -> [Int] -> IO ()
gnuplot preamble cols hlines = do
  fe <- findExecutable "gnuplot"
  when (fe == Nothing) $ error "Couldn't find the 'gnuplot' executable - aborting"
  (i,o,e,p) <- runInteractiveCommand "gnuplot -persist"
  _ <- forkIO (hGetContents o >>= hPutStr stdout)
  -- ugly hack to limit error output
  _ <- forkIO $ do 
    let go ~(l1:l2:ls) =do putStrLn l1
                           if ('^' `elem` l1) 
                             then do 
                               putStrLn l2
                             else go (l2:ls)
    go =<< fmap lines (hGetContents e)

  
  hPutStr i $ unlines $ preamble
  hPutStrLn i (mkplots cols ++ concatMap ((',':) . show) hlines)
  mapM_ (\col -> do {hPutStr i . unlines . map show . snd $ col; hPutStrLn i "e"}) cols

  hClose i

  x <- waitForProcess p
  case x of ExitSuccess ->  return ()
            ExitFailure j -> hPutStrLn stderr (errmsg++show j) >> return ()
    where errmsg = "'gnuplot' failed with exit code "

-- | generate the plot command
mkplots :: [(String,[a])] -> String
mkplots cs = "plot " ++ (concat . intersperse "," . map mkp $ cs)
  where mkp :: (String,a) -> String
        mkp (s,_) = "'-' with lines title '"++s++"'"