{-# LANGUAGE OverloadedStrings #-} -- | Visualize a force-directed network from connectivity. module Web.Lightning.Plots.Force ( ForcePlot(..) , Visualization (..) , forcePlot ) where -------------------------------------------------------------------------------- import Control.Monad.Reader import Data.Aeson import Data.Default.Class import qualified Data.Text as T import qualified Web.Lightning.Routes as R import Web.Lightning.Types.Lightning import Web.Lightning.Types.Visualization (Visualization (..)) import Web.Lightning.Utilities -------------------------------------------------------------------------------- -- | Force plot parameters data ForcePlot = ForcePlot { fpConn :: [[Double]] -- ^ Matrix that defines the connectivity of the plot. The -- dimensions of the matrix can be (n, n), (n, 2) or (n, 3). -- Matrix can be binary or continuous valued. Links should -- contain either 2 elements per link (source, target) or -- 3 elements (source, target, value). , fpValues :: Maybe [Double] -- ^ Values to set node colors via a linear scale. , fpLabels :: Maybe [T.Text] -- ^ List of text labels to set as tooltips. , fpColor :: Maybe [Int] -- ^ Single RGB value or list to set node colors. , fpGroup :: Maybe [Int] -- ^ Single integer or list to set node colors via groups. , fpColorMap :: Maybe T.Text -- ^ Specification of color map, only colorbrewer types supported. , fpSize :: Maybe [Int] -- ^ Single size or list to set node sizes. , fpToolTips :: Maybe Bool -- ^ Whether or not to show tooltips. , fpZoom :: Maybe Bool -- ^ Whether or not to allow zooming. , fpBrush :: Maybe Bool -- ^ Whether or not to support brushing. } deriving (Show, Eq) instance Default ForcePlot where def = ForcePlot [[]] Nothing Nothing Nothing Nothing Nothing Nothing (Just True) (Just True) (Just True) instance ToJSON ForcePlot where toJSON (ForcePlot conn vs lbs cs gs cm ss tt z b) = omitNulls [ "links" .= getLinks conn , "nodes" .= getNodes conn , "values" .= vs , "labels" .= lbs , "color" .= cs , "group" .= gs , "colormap" .= cm , "size" .= ss , "tooltips" .= tt , "zoom" .= z , "brush" .= b ] instance ValidatablePlot ForcePlot where validatePlot (ForcePlot conn vl lbl c grp cm s tt z b) = do conn' <- validateConn conn c' <- validateColor c cm' <- validateColorMap cm s' <- validateSize s return $ ForcePlot conn' vl lbl c' grp cm' s' tt z b -- | Submits a request to the specified lightning-viz server to create a -- force-directed network visualization from connectivity. -- -- forcePlot :: Monad m => ForcePlot -- ^ Force plot to create. -> LightningT m Visualization -- ^ Transformer stack with created visualization. forcePlot forcePlt = do url <- ask viz <- sendPlot "force" forcePlt R.plot return $ viz { vizBaseUrl = Just url }