force-layout 0.2.0.1 → 0.3
raw patch · 3 files changed
+50/−32 lines, 3 filesdep +data-default-classdep −newtype
Dependencies added: data-default-class
Dependencies removed: newtype
Files
- CHANGES +4/−0
- force-layout.cabal +3/−3
- src/Physics/ForceLayout.hs +43/−29
CHANGES view
@@ -1,3 +1,7 @@+* 0.3: 1 January 2014++ - Use lenses for ForceLayoutOpts+ * 0.2.0.1: 22 Dec 2013 - Allow base-4.7
force-layout.cabal view
@@ -1,5 +1,5 @@ name: force-layout-version: 0.2.0.1+version: 0.3 synopsis: Simple force-directed layout description: Simulation engine for doing simple force-based layout, /e.g./ for trees or graphs. See the diagrams-contrib package@@ -20,10 +20,10 @@ library exposed-modules: Physics.ForceLayout build-depends: base >= 4.2 && < 4.8,- newtype ==0.2.*, vector-space >=0.7 && <0.9, vector-space-points >= 0.1.1 && < 0.2, lens >= 3 && < 4,- containers >=0.4 && < 0.6+ containers >=0.4 && < 0.6,+ data-default-class >= 0.0.1 && < 0.1 hs-source-dirs: src default-language: Haskell2010
src/Physics/ForceLayout.hs view
@@ -1,6 +1,7 @@-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE UndecidableInstances #-} ----------------------------------------------------------------------------- -- |@@ -17,6 +18,7 @@ -- > import Physics.ForceLayout -- > import qualified Data.Map as M -- > import Data.AffineSpace.Point+-- > import Data.Default (def) -- > -- > e :: Ensemble (Double, Double) -- > e = Ensemble [ (edges, hookeForce 0.05 4)@@ -37,10 +39,9 @@ -- state): -- -- > e' :: Ensemble (Double, Double)--- > e' = forceLayout (FLOpts { damping = 0.8--- > , energyLimit = Just 0.001--- > , stepLimit = Nothing--- > }+-- > e' = forceLayout (def & damping .~ 0.8+-- > & energyLimit .~ Just 0.001+-- > & stepLimit .~ Nothing -- > ) -- > e --@@ -68,6 +69,7 @@ -- * Running simulations , ForceLayoutOpts(..)+ , damping, energyLimit, stepLimit , simulate , forceLayout @@ -80,18 +82,16 @@ ) where -import Control.Monad-import Control.Newtype (ala) import Data.AffineSpace import Data.AffineSpace.Point-import Data.Foldable (foldMap)-import qualified Data.Foldable as F-import qualified Data.Map as M-import Data.Maybe+import Data.Default.Class+import Data.Foldable (foldMap)+import qualified Data.Foldable as F+import qualified Data.Map as M import Data.Monoid-import Data.VectorSpace hiding (Sum)+import Data.VectorSpace hiding (Sum) -import Control.Lens hiding (ala)+import Control.Lens ------------------------------------------------------------ -- Particles@@ -176,19 +176,33 @@ -- | Options for customizing a simulation. data ForceLayoutOpts v = FLOpts- { damping :: Scalar v -- ^ Damping factor to be- -- applied at each step.- -- Should be between 0 and 1.- , energyLimit :: Maybe (Scalar v) -- ^ Kinetic energy below which- -- simulation should stop. If- -- @Nothing@, pay no attention- -- to kinetic energy.- , stepLimit :: Maybe Int -- ^ Maximum number of- -- simulation steps. If- -- @Nothing@, pay no attention- -- to the number of steps.+ { _damping :: Scalar v -- ^ Damping factor to be+ -- applied at each step.+ -- Should be between 0 and 1.+ -- The default is 0.8.+ , _energyLimit :: Maybe (Scalar v) -- ^ Kinetic energy below which+ -- simulation should stop.+ -- If @Nothing@, pay no+ -- attention to kinetic+ -- energy. The default is+ -- @Just 0.001@.+ , _stepLimit :: Maybe Int -- ^ Maximum number of+ -- simulation steps. If+ -- @Nothing@, pay no+ -- attention to the number of+ -- steps. The default is+ -- @Just 1000@. } +makeLenses ''ForceLayoutOpts++instance Fractional (Scalar v) => Default (ForceLayoutOpts v) where+ def = FLOpts+ { _damping = 0.8+ , _energyLimit = Just 0.001+ , _stepLimit = Just 1000+ }+ -- | Simulate a starting ensemble according to the given options, -- producing a list of all the intermediate ensembles. Useful for, -- /e.g./, making an animation. Note that the resulting list could@@ -199,10 +213,10 @@ => ForceLayoutOpts v -> Ensemble v -> [Ensemble v] simulate opts e = (e:)- . takeWhile (maybe (const True) (<) (energyLimit opts) . kineticEnergy)- . maybe id take (stepLimit opts)+ . takeWhile (maybe (const True) (<) (opts ^. energyLimit) . kineticEnergy)+ . maybe id take (opts ^. stepLimit) . drop 1- . iterate (ensembleStep (damping opts))+ . iterate (ensembleStep (opts ^. damping)) $ e -- | Run a simluation from a starting ensemble, yielding either the