splot 0.1.4 → 0.1.5
raw patch · 2 files changed
+27/−12 lines, 2 files
Files
- Tools/StatePlot.hs +26/−11
- splot.cabal +1/−1
Tools/StatePlot.hs view
@@ -25,6 +25,8 @@ data Event = Event {time :: LocalTime, track :: String, edge :: Edge} deriving (Show) data Edge = Begin { color :: String } | End deriving (Show) +data Bar = Bar Double Double String | ExpiredBar Double Double String+ getArg :: String -> String -> [String] -> String getArg name def args = case [(k,v) | (k,v) <- zip args (tail args), k==("-"++name)] of (_,v):_ -> v@@ -43,8 +45,8 @@ diffToMillis t2 t1 = fromIntegral (truncate (1000000*d)) / 1000 where d = diffUTCTime (localTimeToUTC utc t2) (localTimeToUTC utc t1) -renderEvents :: Double -> Double -> [Event] -> (Event -> Event -> Ordering) -> Renderable ()-renderEvents bandHeight ticksIntervalMs es cmpTracks = Renderable {minsize = return (0,0), render = render'}+renderEvents :: Double -> Double -> Double -> [Event] -> (Event -> Event -> Ordering) -> Renderable ()+renderEvents bandHeight ticksIntervalMs expireTimeMs es cmpTracks = Renderable {minsize = return (0,0), render = render'} where events = sortBy (comparing time) es minTime = time $ head events@@ -61,7 +63,9 @@ bars track = execWriter . (`evalStateT` Nothing) . mapM_ step $ track++[Event maxTime undefined End] where step (Event t _ edge) = do- get >>= maybeM (\(t0,c0) -> tell [(time2ms t0, time2ms t, c0)])+ get >>= maybeM (\(t0,c0) -> tell $ if (time2ms t - time2ms t0 < expireTimeMs) + then [Bar (time2ms t0) (time2ms t) c0]+ else [ExpiredBar (time2ms t0) (time2ms t0 + expireTimeMs) c0]) put (case edge of { Begin c -> Just (t,c); End -> Nothing }) render' (w,h) = do@@ -76,11 +80,18 @@ ; lineTo $ Point (ms2x ms) (h-5) ; c $ C.stroke }- let drawBar i (ms1, ms2, color) = do {- setLineStyle $ solidLine 1 transparent- ; setFillStyle $ solidFillStyle $ opaque $ fromMaybe (error $ "unknown color: " ++ color) (readColourName color)- ; fillPath (rectPath $ Rect (Point (ms2x ms1) (track2y i)) (Point (ms2x ms2) (track2y i + bandHeight)))- }+ let drawBar i (Bar ms1 ms2 color) = do {+ setLineStyle $ solidLine 1 transparent+ ; setFillStyle $ solidFillStyle $ opaque $ fromMaybe (error $ "unknown color: " ++ color) (readColourName color)+ ; fillPath (rectPath $ Rect (Point (ms2x ms1) (track2y i)) (Point (ms2x ms2) (track2y i + bandHeight)))+ }+ drawBar i (ExpiredBar ms1 ms2 color) = do {+ setLineStyle $ dashedLine 1 [3,3] (opaque $ fromMaybe (error $ "unknown color: " ++ color) (readColourName color))+ ; strokePath [Point (ms2x ms1) (track2y i), Point (ms2x ms2) (track2y i)]+ ; setLineStyle $ solidLine 1 (opaque red)+ ; strokePath [Point (ms2x ms2 - 5) (track2y i - 5), Point (ms2x ms2 + 5) (track2y i + 5)]+ ; strokePath [Point (ms2x ms2 + 5) (track2y i - 5), Point (ms2x ms2 - 5) (track2y i + 5)]+ } let drawTrack (i, es) = mapM_ (drawBar i) (bars es) setFillStyle $ solidFillStyle (opaque white)@@ -98,7 +109,7 @@ showHelp = mapM_ putStrLn [ "splot - a tool for visualizing the lifecycle of many concurrent multi-stage processes. See http://www.haskell.org/haskellwiki/Splot",- "Usage: splot [-o PNGFILE] [-w WIDTH] [-h HEIGHT] [-bh BARHEIGHT] [-tf TIMEFORMAT] [-sort SORT]",+ "Usage: splot [-o PNGFILE] [-w WIDTH] [-h HEIGHT] [-bh BARHEIGHT] [-tf TIMEFORMAT] [-sort SORT] [-expire EXPIRE]", " [-tickInterval TICKINTERVAL]", " -o PNGFILE - filename to which the output will be written in PNG format.", " If omitted, it will be shown in a window.",@@ -109,7 +120,10 @@ " fractional seconds supported via %OS - will parse 12.4039 or 12,4039", " -tickInterval - ticks on the X axis will be this often (in millis).", " -sort SORT - sort tracks by SORT, where: 'time' - sort by time of first event, ",- " 'name' - sort by track name",+ " 'name' - sort by track name.",+ " -expire - expire activities after given time period (in millis) - for instance,",+ " to account that if an activity doesn't tell you it's finished for too long,",+ " then it probably was killed.", "", "Input is read from stdin. Example input (speaks for itself):", "2010-10-21 16:45:09,431 >foo green",@@ -138,7 +152,8 @@ input <- B.getContents let events = parse parseTime `map` B.lines input let cmpTracks = case getArg "sort" "time" args of { "time" -> comparing time ; "name" -> comparing track }- let pic = renderEvents bandHeight ticksIntervalMs events cmpTracks+ let expireTimeMs = read $ getArg "expire" "Infinity" args+ let pic = renderEvents bandHeight ticksIntervalMs expireTimeMs events cmpTracks case outPNG of "" -> renderableToWindow pic w h f -> const () `fmap` renderableToPNGFile pic w h outPNG
splot.cabal view
@@ -1,5 +1,5 @@ Name: splot-Version: 0.1.4+Version: 0.1.5 License: BSD3 License-file: LICENSE Copyright: Eugene Kirpichov, 2010