packages feed

Plot-ho-matic 0.9.0.8 → 0.9.0.9

raw patch · 5 files changed

+102/−70 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -1,3 +1,7 @@+0.9.0.9+---+* Add option to remember the min/max ranges past the view window+ 0.9.0.8 --- * Make title text smaller
Plot-ho-matic.cabal view
@@ -1,5 +1,5 @@ name:                Plot-ho-matic-version:             0.9.0.8+version:             0.9.0.9 synopsis:            Real-time line plotter for generic data license:             BSD3 license-file:        LICENSE
src/PlotHo/ChartRender.hs view
@@ -18,12 +18,15 @@ -- take the data and use Chart to make a Renderable () toChartRender :: forall a                  . (Chart.PlotValue a, Show a, RealFloat a)-                 => (AxisScaling, AxisScaling) -> (Maybe (a,a), Maybe (a,a))+                 => (AxisScaling, AxisScaling)+                 -> ((a,a), (a,a))+                 -> ((a,a), (a,a))                  -> Maybe String                  -> [(String, [[(a,a)]])]                  -> Chart.RectSize                  -> Cairo.Render ()-toChartRender (xScaling, yScaling) (xRange, yRange) mtitle namePcs rectSize =+toChartRender (xScaling, yScaling) (manualXRange, manualYRange) (historyXRange, historyYRange)+  mtitle namePcs rectSize =   void $ runBackend (defaultEnv Chart.bitmapAlignmentFns) (Chart.render renderable rectSize)   where     renderable :: Chart.Renderable ()@@ -40,15 +43,20 @@      xscaleFun = case xScaling of       LogScaling -> Chart.layout_x_axis . Chart.laxis_generate .~ Chart.autoScaledLogAxis def-      LinearScaling -> case xRange of-        Nothing -> id-        Just range -> Chart.layout_x_axis . Chart.laxis_generate .~ Chart.scaledAxis def range+      LinearScalingAutoRange -> id+      LinearScalingManualRange ->+        Chart.layout_x_axis . Chart.laxis_generate .~ Chart.scaledAxis def manualXRange+      LinearScalingHistoryRange ->+        Chart.layout_x_axis . Chart.laxis_generate .~ Chart.scaledAxis def historyXRange +     yscaleFun = case yScaling of       LogScaling -> Chart.layout_y_axis . Chart.laxis_generate .~ Chart.autoScaledLogAxis def-      LinearScaling -> case yRange of-        Nothing -> id-        Just range -> Chart.layout_y_axis . Chart.laxis_generate .~ Chart.scaledAxis def range+      LinearScalingAutoRange -> id+      LinearScalingManualRange ->+        Chart.layout_y_axis . Chart.laxis_generate .~ Chart.scaledAxis def manualYRange+      LinearScalingHistoryRange ->+        Chart.layout_y_axis . Chart.laxis_generate .~ Chart.scaledAxis def historyYRange      title = case mtitle of       Nothing -> id
src/PlotHo/GraphWidget.hs view
@@ -12,7 +12,7 @@ import Control.Monad.IO.Class ( MonadIO, liftIO ) import Data.Either ( isRight ) import qualified Data.IORef as IORef-import Data.List ( intercalate )+import Data.List ( foldl', intercalate ) import qualified Data.Map as M import Data.Maybe ( isNothing, fromJust ) import Data.Time.Clock ( getCurrentTime, diffUTCTime )@@ -32,6 +32,9 @@ --debug = liftIO . putStrLn debug = const (return ()) +defaultHistoryRange :: (Double, Double)+defaultHistoryRange = (read "Infinity", - read "Infinity")+ -- make a new graph window newGraph ::   forall a@@ -50,12 +53,14 @@     ]    -- mvar with all the user input-  graphInfoMVar <- CC.newMVar GraphInfo { giXScaling = LinearScaling-                                        , giYScaling = LinearScaling-                                        , giXRange = Nothing-                                        , giYRange = Nothing+  graphInfoMVar <- CC.newMVar GraphInfo { giXScaling = LinearScalingAutoRange+                                        , giYScaling = LinearScalingAutoRange+                                        , giManualXRange = (-10, 10)+                                        , giManualYRange = (-10, 10)                                         , giGetters = []                                         , giTitle = Nothing+                                        , giHistoryXRange = defaultHistoryRange+                                        , giHistoryYRange = defaultHistoryRange                                         } :: IO (CC.MVar (GraphInfo a))    let -- turn latest signals into a Chart render@@ -70,10 +75,30 @@           else do datalog <- Gtk.listStoreGetValue msgStore 0                   return $ map (fmap (\g -> g datalog)) (giGetters gi)                     :: IO [(String, [[(Double,Double)]])]++        let f :: ((Double, Double), (Double, Double)) -> (Double, Double)+                 -> ((Double, Double), (Double, Double))+            f ((minX, maxX), (minY, maxY)) (x, y) =+              ( (min minX x, max maxX x)+              , (min minY y, max maxY y)+              )++            pcs :: [(Double, Double)]+            pcs = concatMap (concat . snd) namePcs++            newRanges = foldl' f (giHistoryXRange gi, giHistoryYRange gi) pcs+            newGi =+              gi+              { giHistoryXRange = fst newRanges+              , giHistoryYRange = snd newRanges+              }+        void $ CC.swapMVar graphInfoMVar newGi+         return $           toChartRender           (giXScaling gi, giYScaling gi)-          (giXRange gi, giYRange gi)+          (giManualXRange gi, giManualYRange gi)+          newRanges           (giTitle gi)           namePcs @@ -498,51 +523,45 @@   -- user selectable range   xRange <- Gtk.entryNew   yRange <- Gtk.entryNew-  Gtk.set xRange [ Gtk.entryEditable := False-                 , Gtk.widgetSensitive := False+  Gtk.set xRange [ Gtk.entryEditable := True+                 , Gtk.widgetSensitive := True                  ]-  Gtk.set yRange [ Gtk.entryEditable := False-                 , Gtk.widgetSensitive := False+  Gtk.set yRange [ Gtk.entryEditable := True+                 , Gtk.widgetSensitive := True                  ]   xRangeBox <- labeledWidget "x range:" xRange   yRangeBox <- labeledWidget "y range:" yRange   Gtk.set xRange [Gtk.entryText := "(-10,10)"]   Gtk.set yRange [Gtk.entryText := "(-10,10)"]   let updateXRange = do-        Gtk.set xRange [ Gtk.entryEditable := True-                       , Gtk.widgetSensitive := True-                       ]         txt <- Gtk.get xRange Gtk.entryText         gi <- CC.readMVar graphInfoMVar         case readMaybe txt of           Nothing -> do             putStrLn $ "invalid x range entry: " ++ txt-            Gtk.set xRange [Gtk.entryText := "(min,max)"]+            Gtk.set xRange [Gtk.entryText := show (giManualXRange gi)]           Just (z0,z1) -> if z0 >= z1                     then do                       putStrLn $ "invalid x range entry (min >= max): " ++ txt-                      Gtk.set xRange [Gtk.entryText := "(min,max)"]+                      Gtk.set xRange [Gtk.entryText := show (giManualXRange gi)]                       return ()                     else do-                      _ <- CC.swapMVar graphInfoMVar (gi {giXRange = Just (z0,z1)})+                      _ <- CC.swapMVar graphInfoMVar (gi {giManualXRange = (z0, z1)})                       redraw   let updateYRange = do-        Gtk.set yRange [ Gtk.entryEditable := True-                       , Gtk.widgetSensitive := True-                       ]         txt <- Gtk.get yRange Gtk.entryText         gi <- CC.readMVar graphInfoMVar         case readMaybe txt of           Nothing -> do             putStrLn $ "invalid y range entry: " ++ txt-            Gtk.set yRange [Gtk.entryText := "(min,max)"]+            Gtk.set yRange [Gtk.entryText := show (giManualYRange gi)]           Just (z0,z1) -> if z0 >= z1                     then do                       putStrLn $ "invalid y range entry (min >= max): " ++ txt-                      Gtk.set yRange [Gtk.entryText := "(min,max)"]+                      Gtk.set yRange [Gtk.entryText := show (giManualYRange gi)]                       return ()                     else do-                      _ <- CC.swapMVar graphInfoMVar (gi {giYRange = Just (z0,z1)})+                      _ <- CC.swapMVar graphInfoMVar (gi {giManualYRange = (z0, z1)})                       redraw   _ <- on xRange Gtk.entryActivate updateXRange   _ <- on yRange Gtk.entryActivate updateYRange@@ -551,9 +570,9 @@   xScalingSelector <- Gtk.comboBoxNewText   yScalingSelector <- Gtk.comboBoxNewText   mapM_ (Gtk.comboBoxAppendText xScalingSelector . T.pack)-    ["linear (auto)","linear (manual)","logarithmic (auto)"]+    ["linear (auto)", "linear (history)", "linear (manual)", "logarithmic (auto)"]   mapM_ (Gtk.comboBoxAppendText yScalingSelector . T.pack)-    ["linear (auto)","linear (manual)","logarithmic (auto)"]+    ["linear (auto)", "linear (history)", "linear (manual)", "logarithmic (auto)"]   Gtk.comboBoxSetActive xScalingSelector 0   Gtk.comboBoxSetActive yScalingSelector 0   xScalingBox <- labeledWidget "x scaling:" xScalingSelector@@ -561,50 +580,42 @@   let updateXScaling = do         k <- Gtk.comboBoxGetActive xScalingSelector         _ <- case k of-          0 -> do-            Gtk.set xRange [ Gtk.entryEditable := False-                           , Gtk.widgetSensitive := False-                           ]-            CC.modifyMVar_ graphInfoMVar $-              \gi -> return $ gi {giXScaling = LinearScaling, giXRange = Nothing}-          1 -> do-            CC.modifyMVar_ graphInfoMVar $-              \gi -> return $ gi {giXScaling = LinearScaling, giXRange = Nothing}-            updateXRange-          2 -> do-            Gtk.set xRange [ Gtk.entryEditable := False-                           , Gtk.widgetSensitive := False-                           ]-            CC.modifyMVar_ graphInfoMVar $-              \gi -> return $ gi {giXScaling = LogScaling, giXRange = Nothing}-          _ -> error "the \"impossible\" happened: x scaling comboBox index should be < 3"+          0 -> CC.modifyMVar_ graphInfoMVar $+                 \gi -> return $ gi {giXScaling = LinearScalingAutoRange}+          1 -> CC.modifyMVar_ graphInfoMVar $+                 \gi -> return $ gi {giXScaling = LinearScalingHistoryRange}+          2 -> CC.modifyMVar_ graphInfoMVar $+                 \gi -> return $ gi {giXScaling = LinearScalingManualRange}+          3 -> CC.modifyMVar_ graphInfoMVar $+                 \gi -> return $ gi {giXScaling = LogScaling}+          _ -> error "the \"impossible\" happened: x scaling comboBox index should be < 4"         redraw   let updateYScaling = do         k <- Gtk.comboBoxGetActive yScalingSelector         _ <- case k of-          0 -> do-            Gtk.set yRange [ Gtk.entryEditable := False-                           , Gtk.widgetSensitive := False-                           ]-            CC.modifyMVar_ graphInfoMVar $-              \gi -> return $ gi {giYScaling = LinearScaling, giYRange = Nothing}-          1 -> do-            CC.modifyMVar_ graphInfoMVar $-              \gi -> return $ gi {giYScaling = LinearScaling, giYRange = Nothing}-            updateYRange-          2 -> do-            Gtk.set yRange [ Gtk.entryEditable := False-                           , Gtk.widgetSensitive := False-                           ]-            CC.modifyMVar_ graphInfoMVar $-              \gi -> return $ gi {giYScaling = LogScaling, giYRange = Nothing}-          _ -> error "the \"impossible\" happened: y scaling comboBox index should be < 3"+          0 -> CC.modifyMVar_ graphInfoMVar $+                 \gi -> return $ gi {giYScaling = LinearScalingAutoRange}+          1 -> CC.modifyMVar_ graphInfoMVar $+                 \gi -> return $ gi {giYScaling = LinearScalingHistoryRange}+          2 -> CC.modifyMVar_ graphInfoMVar $+                 \gi -> return $ gi {giYScaling = LinearScalingManualRange}+          3 -> CC.modifyMVar_ graphInfoMVar $+                 \gi -> return $ gi {giYScaling = LogScaling}+          _ -> error "the \"impossible\" happened: y scaling comboBox index should be < 4"         redraw   updateXScaling   updateYScaling   void $ on xScalingSelector Gtk.changed updateXScaling   void $ on yScalingSelector Gtk.changed updateYScaling +  resetXHistory <- Gtk.buttonNewWithLabel "reset X range"+  resetYHistory <- Gtk.buttonNewWithLabel "reset Y range"+  void $ on resetXHistory Gtk.buttonActivated $+    CC.modifyMVar_ graphInfoMVar (\gi -> return (gi {giHistoryXRange = defaultHistoryRange}))+  void $ on resetYHistory Gtk.buttonActivated $+    CC.modifyMVar_ graphInfoMVar (\gi -> return (gi {giHistoryYRange = defaultHistoryRange}))++   -- vbox to hold the little window on the left   vbox <- Gtk.vBoxNew False 4 @@ -613,10 +624,14 @@     , Gtk.boxChildPacking   xScalingBox := Gtk.PackNatural     , Gtk.containerChild := xRangeBox     , Gtk.boxChildPacking   xRangeBox := Gtk.PackNatural+    , Gtk.containerChild := resetXHistory+    , Gtk.boxChildPacking   resetXHistory := Gtk.PackNatural     , Gtk.containerChild := yScalingBox     , Gtk.boxChildPacking   yScalingBox := Gtk.PackNatural     , Gtk.containerChild := yRangeBox     , Gtk.boxChildPacking   yRangeBox := Gtk.PackNatural+    , Gtk.containerChild := resetYHistory+    , Gtk.boxChildPacking   resetYHistory := Gtk.PackNatural     ]    return vbox
src/PlotHo/PlotTypes.hs view
@@ -31,16 +31,21 @@   show (ListViewInfo n (Right _) m) = "ListViewInfo " ++ show (n,m)  data AxisScaling = LogScaling-                 | LinearScaling+                 | LinearScalingAutoRange+                 | LinearScalingHistoryRange+                 | LinearScalingManualRange  -- what the graph should draw data GraphInfo a =   GraphInfo { giXScaling :: AxisScaling             , giYScaling :: AxisScaling-            , giXRange :: Maybe (Double,Double)-            , giYRange :: Maybe (Double,Double)+            , giManualXRange :: (Double,Double)+            , giManualYRange :: (Double,Double)+            , giHistoryXRange :: (Double, Double)+            , giHistoryYRange :: (Double, Double)             , giGetters :: [(String, a -> [[(Double,Double)]])]             , giTitle :: Maybe String+--            , giGetVal :: IO a             }  data Channel a =