Commit 94c53ffa authored by Przemyslaw Kaminski's avatar Przemyslaw Kaminski

[Graph] implement transformedGraph computation

As an example, this transforms the fetched graph and: hides nodes (via
the nodeSize state) and changes their colour (via selectedNodeIds).
parent e898585b
...@@ -32,9 +32,10 @@ type Props sigma forceatlas2 = ...@@ -32,9 +32,10 @@ type Props sigma forceatlas2 =
, graph :: Graph , graph :: Graph
, selectedEdgeIds :: R.State SigmaxTypes.SelectedEdgeIds , selectedEdgeIds :: R.State SigmaxTypes.SelectedEdgeIds
, selectedNodeIds :: R.State SigmaxTypes.SelectedNodeIds , selectedNodeIds :: R.State SigmaxTypes.SelectedNodeIds
, sigmaSettings :: sigma
, sigmaRef :: R.Ref Sigmax.Sigma , sigmaRef :: R.Ref Sigmax.Sigma
, sigmaSettings :: sigma
, stage :: R.State Stage , stage :: R.State Stage
, transformedGraph :: Graph
) )
graph :: forall s fa2. Record (Props s fa2) -> R.Element graph :: forall s fa2. Record (Props s fa2) -> R.Element
...@@ -91,14 +92,14 @@ graphCpt = R.hooksComponent "Graph" cpt ...@@ -91,14 +92,14 @@ graphCpt = R.hooksComponent "Graph" cpt
pure $ pure unit pure $ pure unit
stageHooks props@{stage: (Ready /\ setStage)} = do stageHooks props@{stage: (Ready /\ setStage)} = do
let edgesMap = SigmaxTypes.edgesGraphMap props.graph let tEdgesMap = SigmaxTypes.edgesGraphMap props.transformedGraph
let nodesMap = SigmaxTypes.nodesGraphMap props.graph let tNodesMap = SigmaxTypes.nodesGraphMap props.transformedGraph
-- TODO Probably this can be optimized to re-mark selected nodes only when they changed -- TODO Probably this can be optimized to re-mark selected nodes only when they changed
R.useEffect' $ do R.useEffect' $ do
Sigmax.dependOnSigma (R.readRef props.sigmaRef) "[graphCpt] no sigma" $ \sigma -> do Sigmax.dependOnSigma (R.readRef props.sigmaRef) "[graphCpt] no sigma" $ \sigma -> do
Sigmax.markSelectedEdges sigma (fst props.selectedEdgeIds) edgesMap Sigmax.updateEdges sigma tEdgesMap
Sigmax.markSelectedNodes sigma (fst props.selectedNodeIds) nodesMap Sigmax.updateNodes sigma tNodesMap
stageHooks _ = pure unit stageHooks _ = pure unit
...@@ -228,9 +229,9 @@ sigmaSettings = ...@@ -228,9 +229,9 @@ sigmaSettings =
, labelSizeRatio: 2.0 -- label size in ratio of node size , labelSizeRatio: 2.0 -- label size in ratio of node size
, labelThreshold: 5.0 -- min node cam size to start showing label , labelThreshold: 5.0 -- min node cam size to start showing label
, maxEdgeSize: 1.0 , maxEdgeSize: 1.0
, maxNodeSize: 7.0 , maxNodeSize: 8.0
, minEdgeSize: 0.5 -- in fact used in tina as edge size , minEdgeSize: 0.5 -- in fact used in tina as edge size
, minNodeSize: 0.1 , minNodeSize: 1.0
, mouseEnabled: true , mouseEnabled: true
, mouseZoomDuration: 150.0 , mouseZoomDuration: 150.0
, nodeBorderColor: "default" -- choices: "default" color vs. "node" color , nodeBorderColor: "default" -- choices: "default" color vs. "node" color
......
...@@ -20,7 +20,6 @@ import Reactix.DOM.HTML as RH ...@@ -20,7 +20,6 @@ import Reactix.DOM.HTML as RH
import Math (log) import Math (log)
import Gargantext.Hooks.Loader (useLoader) import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Sigmax (Sigma)
import Gargantext.Hooks.Sigmax as Sigmax import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax.Types as SigmaxTypes import Gargantext.Hooks.Sigmax.Types as SigmaxTypes
import Gargantext.Components.GraphExplorer.Controls as Controls import Gargantext.Components.GraphExplorer.Controls as Controls
...@@ -33,6 +32,7 @@ import Gargantext.Ends (Frontends) ...@@ -33,6 +32,7 @@ import Gargantext.Ends (Frontends)
import Gargantext.Routes (SessionRoute(NodeAPI), AppRoute) import Gargantext.Routes (SessionRoute(NodeAPI), AppRoute)
import Gargantext.Sessions (Session, Sessions, get) import Gargantext.Sessions (Session, Sessions, get)
import Gargantext.Types (NodeType(Graph)) import Gargantext.Types (NodeType(Graph))
import Gargantext.Utils.Range as Range
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
type GraphId = Int type GraphId = Int
...@@ -78,8 +78,6 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt ...@@ -78,8 +78,6 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
dataRef <- R.useRef graph dataRef <- R.useRef graph
graphRef <- R.useRef null graphRef <- R.useRef null
controls <- Controls.useGraphControls controls <- Controls.useGraphControls
selectedNodeIds <- R.useState' $ Set.empty
selectedEdgeIds <- R.useState' $ Set.empty
R.useEffect' $ do R.useEffect' $ do
case Tuple (R.readRef dataRef) graph of case Tuple (R.readRef dataRef) graph of
...@@ -89,16 +87,10 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt ...@@ -89,16 +87,10 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
let rSigma = R.readRef controls.sigmaRef let rSigma = R.readRef controls.sigmaRef
Sigmax.cleanupSigma rSigma "explorerCpt" Sigmax.cleanupSigma rSigma "explorerCpt"
R.setRef dataRef graph R.setRef dataRef graph
snd selectedNodeIds $ const Set.empty snd controls.selectedEdgeIds $ const Set.empty
snd selectedEdgeIds $ const Set.empty snd controls.selectedNodeIds $ const Set.empty
snd controls.graphStage $ const Graph.Init snd controls.graphStage $ const Graph.Init
R.useEffect' $ do
if fst controls.showSidePanel == GET.InitialClosed && (not Set.isEmpty $ fst selectedNodeIds) then
snd controls.showSidePanel $ \_ -> GET.Opened
else
pure unit
pure $ pure $
RH.div RH.div
{ id: "graph-explorer" } { id: "graph-explorer" }
...@@ -113,8 +105,20 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt ...@@ -113,8 +105,20 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
, row [ Controls.controls controls ] , row [ Controls.controls controls ]
, row [ tree (fst controls.showTree) {sessions, mCurrentRoute, frontends} (snd showLogin) , row [ tree (fst controls.showTree) {sessions, mCurrentRoute, frontends} (snd showLogin)
, RH.div { ref: graphRef, id: "graph-view", className: graphClassName controls, style: {height: "95%"} } [] -- graph container , RH.div { ref: graphRef, id: "graph-view", className: graphClassName controls, style: {height: "95%"} } [] -- graph container
, mGraph graphRef controls.sigmaRef {graphId, graph, graphStage: controls.graphStage, selectedNodeIds, selectedEdgeIds} , mGraph { controls
, mSidebar graph mMetaData {frontends, session, selectedNodeIds, showSidePanel: fst controls.showSidePanel} , elRef: graphRef
, graphId
, graph
, graphStage: controls.graphStage
, selectedEdgeIds: controls.selectedEdgeIds
, selectedNodeIds: controls.selectedNodeIds
, sigmaRef: controls.sigmaRef
}
, mSidebar graph mMetaData { frontends
, session
, selectedNodeIds: controls.selectedNodeIds
, showSidePanel: fst controls.showSidePanel
}
] ]
, row [ , row [
] ]
...@@ -146,16 +150,18 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt ...@@ -146,16 +150,18 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
RH.div {className: "col-md-2", style: {paddingTop: "60px"}} RH.div {className: "col-md-2", style: {paddingTop: "60px"}}
[forest {sessions, route, frontends, showLogin}] [forest {sessions, route, frontends, showLogin}]
mGraph :: R.Ref (Nullable Element) mGraph :: { controls :: Record Controls.Controls
-> R.Ref Sigma , elRef :: R.Ref (Nullable Element)
-> { graphId :: GraphId , graphId :: GraphId
, graph :: Maybe Graph.Graph , graph :: Maybe Graph.Graph
, graphStage :: R.State Graph.Stage , graphStage :: R.State Graph.Stage
, selectedNodeIds :: R.State SigmaxTypes.SelectedNodeIds , selectedNodeIds :: R.State SigmaxTypes.SelectedNodeIds
, selectedEdgeIds :: R.State SigmaxTypes.SelectedEdgeIds} , selectedEdgeIds :: R.State SigmaxTypes.SelectedEdgeIds
, sigmaRef :: R.Ref Sigmax.Sigma
}
-> R.Element -> R.Element
mGraph _ _ {graph: Nothing} = RH.div {} [] mGraph {graph: Nothing} = RH.div {} []
mGraph graphRef sigmaRef r@{graph: Just graph} = graphView graphRef sigmaRef $ r { graph = graph } mGraph r@{graph: Just graph} = graphView $ r { graph = graph }
mSidebar :: Maybe Graph.Graph mSidebar :: Maybe Graph.Graph
-> Maybe GET.MetaData -> Maybe GET.MetaData
...@@ -176,29 +182,36 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt ...@@ -176,29 +182,36 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
} }
type GraphProps = ( type GraphProps = (
graphId :: GraphId controls :: Record Controls.Controls
, elRef :: R.Ref (Nullable Element)
, graphId :: GraphId
, graph :: Graph.Graph , graph :: Graph.Graph
, graphStage :: R.State Graph.Stage , graphStage :: R.State Graph.Stage
, selectedNodeIds :: R.State SigmaxTypes.SelectedNodeIds , selectedNodeIds :: R.State SigmaxTypes.SelectedNodeIds
, selectedEdgeIds :: R.State SigmaxTypes.SelectedEdgeIds , selectedEdgeIds :: R.State SigmaxTypes.SelectedEdgeIds
, sigmaRef :: R.Ref Sigmax.Sigma
) )
graphView :: R.Ref (Nullable Element) -> R.Ref Sigma -> Record GraphProps -> R.Element graphView :: Record GraphProps -> R.Element
--graphView sigmaRef props = R.createElement (R.memo el memoCmp) props [] --graphView sigmaRef props = R.createElement (R.memo el memoCmp) props []
graphView elRef sigmaRef props = R.createElement el props [] graphView props = R.createElement el props []
where where
--memoCmp props1 props2 = props1.graphId == props2.graphId --memoCmp props1 props2 = props1.graphId == props2.graphId
el = R.hooksComponent "GraphView" cpt el = R.hooksComponent "GraphView" cpt
cpt {graphId, graph, selectedEdgeIds, selectedNodeIds} _children = do cpt {controls, elRef, graphId, graph, selectedEdgeIds, selectedNodeIds, sigmaRef} _children = do
-- TODO Cache this?
let transformedGraph = transformGraph controls graph
pure $ Graph.graph { pure $ Graph.graph {
elRef elRef
, forceAtlas2Settings: Graph.forceAtlas2Settings , forceAtlas2Settings: Graph.forceAtlas2Settings
, graph , graph
, selectedEdgeIds , selectedEdgeIds
, selectedNodeIds , selectedNodeIds
, sigmaRef
, sigmaSettings: Graph.sigmaSettings , sigmaSettings: Graph.sigmaSettings
, sigmaRef: sigmaRef
, stage: props.graphStage , stage: props.graphStage
, transformedGraph
} }
convert :: GET.GraphData -> Tuple (Maybe GET.MetaData) Graph.Graph convert :: GET.GraphData -> Tuple (Maybe GET.MetaData) Graph.Graph
...@@ -209,6 +222,7 @@ convert (GET.GraphData r) = Tuple r.metaData $ SigmaxTypes.Graph {nodes, edges} ...@@ -209,6 +222,7 @@ convert (GET.GraphData r) = Tuple r.metaData $ SigmaxTypes.Graph {nodes, edges}
Seq.singleton Seq.singleton
{ id : n.id_ { id : n.id_
, size : log (toNumber n.size + 1.0) , size : log (toNumber n.size + 1.0)
, hidden : false
, label : n.label , label : n.label
, x : n.x -- cos (toNumber i) , x : n.x -- cos (toNumber i)
, y : n.y -- sin (toNumber i) , y : n.y -- sin (toNumber i)
...@@ -357,3 +371,27 @@ defaultPalette = ["#5fa571","#ab9ba2","#da876d","#bdd3ff" ...@@ -357,3 +371,27 @@ defaultPalette = ["#5fa571","#ab9ba2","#da876d","#bdd3ff"
getNodes :: Session -> GraphId -> Aff GET.GraphData getNodes :: Session -> GraphId -> Aff GET.GraphData
getNodes session graphId = get session $ NodeAPI Graph (Just graphId) "" getNodes session graphId = get session $ NodeAPI Graph (Just graphId) ""
transformGraph :: Record Controls.Controls -> Graph.Graph -> Graph.Graph
transformGraph controls graph@(SigmaxTypes.Graph {nodes, edges}) = SigmaxTypes.Graph {nodes: newNodes, edges: newEdges}
where
graphEdgesMap = SigmaxTypes.edgesGraphMap graph
graphNodesMap = SigmaxTypes.nodesGraphMap graph
newNodes = nodeSizes <$> nodeMarked <$> nodes
newEdges = edgeMarked <$> edges
nodeSizes node@{ size } =
if Range.within (fst controls.nodeSize) size then
node
else
node { hidden = true }
edgeMarked edge@{ id } =
if Set.member id (fst controls.selectedEdgeIds) then
edge { color = "#ff0000" }
else
edge
nodeMarked node@{ id } =
if Set.member id (fst controls.selectedNodeIds) then
node { color = "#ff0000" }
else
node
...@@ -11,7 +11,8 @@ module Gargantext.Components.GraphExplorer.Controls ...@@ -11,7 +11,8 @@ module Gargantext.Components.GraphExplorer.Controls
) where ) where
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Tuple (fst) import Data.Set as Set
import Data.Tuple (fst, snd)
import Data.Tuple.Nested ((/\), get1) import Data.Tuple.Nested ((/\), get1)
import Effect (Effect) import Effect (Effect)
import Effect.Timer (setTimeout) import Effect.Timer (setTimeout)
...@@ -26,6 +27,7 @@ import Gargantext.Components.GraphExplorer.SlideButton (cursorSizeButton, labelS ...@@ -26,6 +27,7 @@ import Gargantext.Components.GraphExplorer.SlideButton (cursorSizeButton, labelS
import Gargantext.Components.GraphExplorer.ToggleButton (edgesToggleButton, pauseForceAtlasButton) import Gargantext.Components.GraphExplorer.ToggleButton (edgesToggleButton, pauseForceAtlasButton)
import Gargantext.Components.GraphExplorer.Types as GET import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Hooks.Sigmax as Sigmax import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax.Types as SigmaxTypes
import Gargantext.Utils.Range as Range import Gargantext.Utils.Range as Range
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
...@@ -33,6 +35,9 @@ type Controls = ...@@ -33,6 +35,9 @@ type Controls =
( cursorSize :: R.State Number ( cursorSize :: R.State Number
, graphStage :: R.State Graph.Stage , graphStage :: R.State Graph.Stage
, multiNodeSelect :: R.Ref Boolean , multiNodeSelect :: R.Ref Boolean
, nodeSize :: R.State Range.NumberRange
, selectedEdgeIds :: R.State (Set.Set String)
, selectedNodeIds :: R.State (Set.Set String)
, showControls :: R.State Boolean , showControls :: R.State Boolean
, showSidePanel :: R.State GET.SidePanelState , showSidePanel :: R.State GET.SidePanelState
, showTree :: R.State Boolean , showTree :: R.State Boolean
...@@ -45,7 +50,6 @@ controlsToSigmaSettings { cursorSize: (cursorSize /\ _)} = Graph.sigmaSettings ...@@ -45,7 +50,6 @@ controlsToSigmaSettings { cursorSize: (cursorSize /\ _)} = Graph.sigmaSettings
type LocalControls = type LocalControls =
( edgeSize :: R.State Range.NumberRange ( edgeSize :: R.State Range.NumberRange
, labelSize :: R.State Number , labelSize :: R.State Number
, nodeSize :: R.State Range.NumberRange
, pauseForceAtlas :: R.State Boolean , pauseForceAtlas :: R.State Boolean
, showEdges :: R.State Boolean , showEdges :: R.State Boolean
) )
...@@ -54,14 +58,14 @@ initialLocalControls :: R.Hooks (Record LocalControls) ...@@ -54,14 +58,14 @@ initialLocalControls :: R.Hooks (Record LocalControls)
initialLocalControls = do initialLocalControls = do
edgeSize <- R.useState' $ Range.Closed { min: 0.5, max: 1.0 } edgeSize <- R.useState' $ Range.Closed { min: 0.5, max: 1.0 }
labelSize <- R.useState' 14.0 labelSize <- R.useState' 14.0
nodeSize <- R.useState' $ Range.Closed { min: 5.0, max: 10.0 } --nodeSize <- R.useState' $ Range.Closed { min: 0.0, max: 10.0 }
pauseForceAtlas <- R.useState' true pauseForceAtlas <- R.useState' true
showEdges <- R.useState' true showEdges <- R.useState' true
pure $ { pure $ {
edgeSize edgeSize
, labelSize , labelSize
, nodeSize --, nodeSize
, pauseForceAtlas , pauseForceAtlas
, showEdges , showEdges
} }
...@@ -86,6 +90,12 @@ controlsCpt = R.hooksComponent "GraphControls" cpt ...@@ -86,6 +90,12 @@ controlsCpt = R.hooksComponent "GraphControls" cpt
R.useEffect' $ Sigmax.handleForceAtlas2Pause props.sigmaRef localControls.pauseForceAtlas (get1 localControls.showEdges) mFAPauseRef R.useEffect' $ Sigmax.handleForceAtlas2Pause props.sigmaRef localControls.pauseForceAtlas (get1 localControls.showEdges) mFAPauseRef
R.useEffect' $ do
if fst props.showSidePanel == GET.InitialClosed && (not Set.isEmpty $ fst props.selectedNodeIds) then
snd props.showSidePanel $ \_ -> GET.Opened
else
pure unit
R.useEffectOnce' $ do R.useEffectOnce' $ do
timeoutId <- setTimeout 2000 $ do timeoutId <- setTimeout 2000 $ do
let (toggled /\ setToggled) = localControls.pauseForceAtlas let (toggled /\ setToggled) = localControls.pauseForceAtlas
...@@ -114,7 +124,7 @@ controlsCpt = R.hooksComponent "GraphControls" cpt ...@@ -114,7 +124,7 @@ controlsCpt = R.hooksComponent "GraphControls" cpt
-- search topics -- search topics
, RH.li {} [ cursorSizeButton props.cursorSize ] -- cursor size: 0-100 , RH.li {} [ cursorSizeButton props.cursorSize ] -- cursor size: 0-100
, RH.li {} [ labelSizeButton props.sigmaRef localControls.labelSize ] -- labels size: 1-4 , RH.li {} [ labelSizeButton props.sigmaRef localControls.labelSize ] -- labels size: 1-4
, RH.li {} [ nodeSizeControl props.sigmaRef localControls.nodeSize ] -- node size : 5-15 , RH.li {} [ nodeSizeControl props.nodeSize ]
-- zoom: 0 -100 - calculate ratio -- zoom: 0 -100 - calculate ratio
-- toggle multi node selection -- toggle multi node selection
-- save button -- save button
...@@ -127,15 +137,21 @@ useGraphControls = do ...@@ -127,15 +137,21 @@ useGraphControls = do
cursorSize <- R.useState' 10.0 cursorSize <- R.useState' 10.0
graphStage <- R.useState' Graph.Init graphStage <- R.useState' Graph.Init
multiNodeSelect <- R.useRef false multiNodeSelect <- R.useRef false
nodeSize <- R.useState' $ Range.Closed { min: 0.0, max: 10.0 }
showTree <- R.useState' false
selectedNodeIds <- R.useState' $ Set.empty
selectedEdgeIds <- R.useState' $ Set.empty
showControls <- R.useState' false showControls <- R.useState' false
showSidePanel <- R.useState' GET.InitialClosed showSidePanel <- R.useState' GET.InitialClosed
showTree <- R.useState' false
sigma <- Sigmax.initSigma sigma <- Sigmax.initSigma
sigmaRef <- R.useRef sigma sigmaRef <- R.useRef sigma
pure { cursorSize pure { cursorSize
, graphStage , graphStage
, multiNodeSelect , multiNodeSelect
, nodeSize
, selectedEdgeIds
, selectedNodeIds
, showControls , showControls
, showSidePanel , showSidePanel
, showTree , showTree
......
...@@ -55,24 +55,24 @@ edgeSizeControl sigmaRef (state /\ setState) = ...@@ -55,24 +55,24 @@ edgeSizeControl sigmaRef (state /\ setState) =
} }
} }
nodeSizeControl :: R.Ref Sigmax.Sigma -> R.State Range.NumberRange -> R.Element nodeSizeControl :: R.State Range.NumberRange -> R.Element
nodeSizeControl sigmaRef (state /\ setState) = nodeSizeControl (state /\ setState) =
rangeControl { rangeControl {
caption: "Node Size" caption: "Node Size"
, sliderProps: { , sliderProps: {
bounds: Range.Closed { min: 5.0, max: 15.0 } bounds: Range.Closed { min: 0.0, max: 15.0 }
, initialValue: state , initialValue: state
, epsilon: 0.1 , epsilon: 0.1
, step: 1.0 , step: 1.0
, width: 10.0 , width: 10.0
, height: 5.0 , height: 5.0
, onChange: \range@(Range.Closed {min, max}) -> do , onChange: \range@(Range.Closed {min, max}) -> do
let sigma = R.readRef sigmaRef -- let sigma = R.readRef sigmaRef
Sigmax.dependOnSigma sigma "[nodeSizeControl] sigma: Nothing" $ \s -> do -- Sigmax.dependOnSigma sigma "[nodeSizeControl] sigma: Nothing" $ \s -> do
Sigma.setSettings s { -- Sigma.setSettings s {
minNodeSize: min -- minNodeSize: min
, maxNodeSize: max -- , maxNodeSize: max
} -- }
setState $ const range setState $ const range
} }
} }
...@@ -184,6 +184,31 @@ markSelectedNodes sigma selectedNodeIds graphNodes = do ...@@ -184,6 +184,31 @@ markSelectedNodes sigma selectedNodeIds graphNodes = do
Sigma.refresh sigma Sigma.refresh sigma
updateEdges :: Sigma.Sigma -> EdgesMap -> Effect Unit
updateEdges sigma edgesMap = do
Sigma.forEachNode sigma \e -> do
let mTEdge = Map.lookup e.id edgesMap
case mTEdge of
Nothing -> error $ "Edge id " <> e.id <> " not found in edgesMap"
(Just tEdge@{color: tColor}) -> do
_ <- pure $ (e .= "color") tColor
pure unit
Sigma.refresh sigma
updateNodes :: Sigma.Sigma -> NodesMap -> Effect Unit
updateNodes sigma nodesMap = do
Sigma.forEachNode sigma \n -> do
let mTNode = Map.lookup n.id nodesMap
case mTNode of
Nothing -> error $ "Node id " <> n.id <> " not found in nodesMap"
(Just tNode@{color: tColor, hidden: tHidden}) -> do
_ <- pure $ (n .= "color") tColor
_ <- pure $ (n .= "hidden") tHidden
pure unit
Sigma.refresh sigma
bindSelectedNodesClick :: R.Ref Sigma -> R.State SelectedNodeIds -> Effect Unit bindSelectedNodesClick :: R.Ref Sigma -> R.State SelectedNodeIds -> Effect Unit
bindSelectedNodesClick sigmaRef (_ /\ setSelectedNodeIds) = bindSelectedNodesClick sigmaRef (_ /\ setSelectedNodeIds) =
dependOnSigma (R.readRef sigmaRef) "[graphCpt] no sigma" $ \sigma -> do dependOnSigma (R.readRef sigmaRef) "[graphCpt] no sigma" $ \sigma -> do
......
...@@ -21,6 +21,7 @@ type Renderer = { "type" :: String, container :: Element } ...@@ -21,6 +21,7 @@ type Renderer = { "type" :: String, container :: Element }
type Node = type Node =
( id :: String ( id :: String
, label :: String , label :: String
, hidden :: Boolean
, x :: Number , x :: Number
, y :: Number , y :: Number
, size :: Number , size :: Number
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment