Commit 4c0bca05 authored by Przemyslaw Kaminski's avatar Przemyslaw Kaminski

[Graph] use local settings

These don't refersh the whole graph, only change sigma settings.
parent 26de4b9d
...@@ -7,10 +7,7 @@ module Gargantext.Components.GraphExplorer.Controls ...@@ -7,10 +7,7 @@ module Gargantext.Components.GraphExplorer.Controls
, getShowTree, setShowTree , getShowTree, setShowTree
, getShowControls, setShowControls , getShowControls, setShowControls
, getShowSidePanel, setShowSidePanel , getShowSidePanel, setShowSidePanel
, getShowEdges, setShowEdges
, getCursorSize, setCursorSize , getCursorSize, setCursorSize
, getLabelSize, setLabelSize
, getNodeSize, setNodeSize
, getMultiNodeSelect, setMultiNodeSelect , getMultiNodeSelect, setMultiNodeSelect
) where ) where
...@@ -33,43 +30,38 @@ import Gargantext.Utils.Reactix as R2 ...@@ -33,43 +30,38 @@ import Gargantext.Utils.Reactix as R2
type Controls = type Controls =
( cursorSize :: R.State Number ( cursorSize :: R.State Number
, edgeSize :: R.State Range.NumberRange
, labelSize :: R.State Number
, nodeSize :: R.State Range.NumberRange
, multiNodeSelect :: R.Ref Boolean , multiNodeSelect :: R.Ref Boolean
, showControls :: R.State Boolean , showControls :: R.State Boolean
, showEdges :: R.State Boolean
, showSidePanel :: R.State Boolean , showSidePanel :: R.State Boolean
, showTree :: R.State Boolean , showTree :: R.State Boolean
, sigmaRef :: R.Ref (Maybe Sigmax.Sigma) , sigmaRef :: R.Ref (Maybe Sigmax.Sigma)
) )
controlsToSigmaSettings :: Record Controls -> Record Graph.SigmaSettings controlsToSigmaSettings :: Record Controls -> Record Graph.SigmaSettings
controlsToSigmaSettings { cursorSize: (cursorSize /\ _) controlsToSigmaSettings { cursorSize: (cursorSize /\ _)} = Graph.sigmaSettings
, edgeSize: (Range.Closed { min: edgeSizeMin, max: edgeSizeMax } /\ _)
, labelSize: (labelSize /\ _)
, nodeSize: (Range.Closed { min: nodeSizeMin, max: nodeSizeMax } /\ _)
, showEdges: (showEdges /\ _)} = Graph.sigmaSettings {
defaultLabelSize = labelSize
, drawEdges = showEdges
, drawEdgeLabels = showEdges
, hideEdgesOnMove = not showEdges
, minEdgeSize = if showEdges then edgeSizeMin else 0.0
, maxEdgeSize = if showEdges then edgeSizeMax else 0.0
, minNodeSize = nodeSizeMin
, maxNodeSize = nodeSizeMax
}
type LocalControls = type LocalControls =
( pauseForceAtlas :: R.State Boolean ( edgeSize :: R.State Range.NumberRange
, labelSize :: R.State Number
, nodeSize :: R.State Range.NumberRange
, pauseForceAtlas :: R.State Boolean
, showEdges :: R.State Boolean
) )
initialLocalControls :: R.Hooks (Record LocalControls) initialLocalControls :: R.Hooks (Record LocalControls)
initialLocalControls = do initialLocalControls = do
edgeSize <- R.useState' $ Range.Closed { min: 0.5, max: 1.0 }
labelSize <- R.useState' 3.0
nodeSize <- R.useState' $ Range.Closed { min: 5.0, max: 10.0 }
pauseForceAtlas <- R.useState' true pauseForceAtlas <- R.useState' true
showEdges <- R.useState' true
pure $ { pure $ {
pauseForceAtlas edgeSize
, labelSize
, nodeSize
, pauseForceAtlas
, showEdges
} }
controls :: Record Controls -> R.Element controls :: Record Controls -> R.Element
...@@ -88,16 +80,16 @@ controlsCpt = R.hooksComponent "GraphControls" cpt ...@@ -88,16 +80,16 @@ controlsCpt = R.hooksComponent "GraphControls" cpt
[ RH.ul {} [ RH.ul {}
[ -- change type button (?) [ -- change type button (?)
RH.li {} [ pauseForceAtlasButton props.sigmaRef localControls.pauseForceAtlas ] -- spatialization (pause ForceAtlas2) RH.li {} [ pauseForceAtlasButton props.sigmaRef localControls.pauseForceAtlas ] -- spatialization (pause ForceAtlas2)
, RH.li {} [ edgesToggleButton props.showEdges ] , RH.li {} [ edgesToggleButton props.sigmaRef localControls.showEdges ]
, RH.li {} [ edgeSizeControl props.edgeSize ] -- edge size : 0-3 , RH.li {} [ edgeSizeControl props.sigmaRef localControls.edgeSize ] -- edge size : 0-3
-- change level -- change level
-- file upload -- file upload
-- run demo -- run demo
-- search button -- search button
-- 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.labelSize ] -- labels size: 1-4 , RH.li {} [ labelSizeButton props.sigmaRef localControls.labelSize ] -- labels size: 1-4
, RH.li {} [ nodeSizeControl props.nodeSize ] -- node size : 5-15 , RH.li {} [ nodeSizeControl props.sigmaRef localControls.nodeSize ] -- node size : 5-15
-- zoom: 0 -100 - calculate ratio -- zoom: 0 -100 - calculate ratio
-- toggle multi node selection -- toggle multi node selection
-- save button -- save button
...@@ -108,24 +100,16 @@ controlsCpt = R.hooksComponent "GraphControls" cpt ...@@ -108,24 +100,16 @@ controlsCpt = R.hooksComponent "GraphControls" cpt
useGraphControls :: R.Hooks (Record Controls) useGraphControls :: R.Hooks (Record Controls)
useGraphControls = do useGraphControls = do
cursorSize <- R.useState' 10.0 cursorSize <- R.useState' 10.0
edgeSize <- R.useState' $ Range.Closed { min: 0.5, max: 1.0 }
labelSize <- R.useState' 3.0
nodeSize <- R.useState' $ Range.Closed { min: 5.0, max: 10.0 }
multiNodeSelect <- R.useRef false multiNodeSelect <- R.useRef false
showControls <- R.useState' false showControls <- R.useState' false
showEdges <- R.useState' true
showSidePanel <- R.useState' false showSidePanel <- R.useState' false
showTree <- R.useState' false showTree <- R.useState' false
sigmaRef <- R.useRef Nothing sigmaRef <- R.useRef Nothing
pure { pure {
cursorSize cursorSize
, edgeSize
, labelSize
, multiNodeSelect , multiNodeSelect
, nodeSize
, showControls , showControls
, showEdges
, showSidePanel , showSidePanel
, showTree , showTree
, sigmaRef , sigmaRef
...@@ -140,18 +124,9 @@ getShowSidePanel { showSidePanel: ( should /\ _ ) } = should ...@@ -140,18 +124,9 @@ getShowSidePanel { showSidePanel: ( should /\ _ ) } = should
getShowTree :: Record Controls -> Boolean getShowTree :: Record Controls -> Boolean
getShowTree { showTree: ( should /\ _ ) } = should getShowTree { showTree: ( should /\ _ ) } = should
getShowEdges :: Record Controls -> Boolean
getShowEdges { showEdges: ( should /\ _ ) } = should
getCursorSize :: Record Controls -> Number getCursorSize :: Record Controls -> Number
getCursorSize { cursorSize: ( size /\ _ ) } = size getCursorSize { cursorSize: ( size /\ _ ) } = size
getLabelSize :: Record Controls -> Number
getLabelSize { labelSize: ( size /\ _ ) } = size
getNodeSize :: Record Controls -> Range.NumberRange
getNodeSize { nodeSize: ( size /\ _ ) } = size
getMultiNodeSelect :: Record Controls -> Boolean getMultiNodeSelect :: Record Controls -> Boolean
getMultiNodeSelect { multiNodeSelect } = R.readRef multiNodeSelect getMultiNodeSelect { multiNodeSelect } = R.readRef multiNodeSelect
...@@ -164,17 +139,8 @@ setShowSidePanel { showSidePanel: ( _ /\ set ) } v = set $ const v ...@@ -164,17 +139,8 @@ setShowSidePanel { showSidePanel: ( _ /\ set ) } v = set $ const v
setShowTree :: Record Controls -> Boolean -> Effect Unit setShowTree :: Record Controls -> Boolean -> Effect Unit
setShowTree { showTree: ( _ /\ set ) } v = set $ const v setShowTree { showTree: ( _ /\ set ) } v = set $ const v
setShowEdges :: Record Controls -> Boolean -> Effect Unit
setShowEdges { showEdges: ( _ /\ set ) } v = set $ const v
setCursorSize :: Record Controls -> Number -> Effect Unit setCursorSize :: Record Controls -> Number -> Effect Unit
setCursorSize { cursorSize: ( _ /\ setSize ) } v = setSize $ const v setCursorSize { cursorSize: ( _ /\ setSize ) } v = setSize $ const v
setLabelSize :: Record Controls -> Number -> Effect Unit
setLabelSize { labelSize: ( _ /\ setSize) } v = setSize $ const v
setNodeSize :: Record Controls -> Range.NumberRange -> Effect Unit
setNodeSize { nodeSize: ( _ /\ setSize ) } v = setSize $ const v
setMultiNodeSelect :: Record Controls -> Boolean -> Effect Unit setMultiNodeSelect :: Record Controls -> Boolean -> Effect Unit
setMultiNodeSelect { multiNodeSelect } = R.setRef multiNodeSelect setMultiNodeSelect { multiNodeSelect } = R.setRef multiNodeSelect
...@@ -6,11 +6,14 @@ module Gargantext.Components.GraphExplorer.RangeControl ...@@ -6,11 +6,14 @@ module Gargantext.Components.GraphExplorer.RangeControl
) where ) where
import Prelude import Prelude
import Data.Maybe (Maybe(..))
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Gargantext.Components.RangeSlider as RS import Gargantext.Components.RangeSlider as RS
import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Utils.Range as Range import Gargantext.Utils.Range as Range
type Props = ( type Props = (
...@@ -31,8 +34,8 @@ rangeControlCpt = R.hooksComponent "RangeButton" cpt ...@@ -31,8 +34,8 @@ rangeControlCpt = R.hooksComponent "RangeButton" cpt
, RS.rangeSlider sliderProps , RS.rangeSlider sliderProps
] ]
edgeSizeControl :: R.State Range.NumberRange -> R.Element edgeSizeControl :: R.Ref (Maybe Sigmax.Sigma) -> R.State Range.NumberRange -> R.Element
edgeSizeControl (state /\ setState) = edgeSizeControl sigmaRef (state /\ setState) =
rangeControl { rangeControl {
caption: "Edge Size" caption: "Edge Size"
, sliderProps: { , sliderProps: {
...@@ -42,12 +45,20 @@ edgeSizeControl (state /\ setState) = ...@@ -42,12 +45,20 @@ edgeSizeControl (state /\ setState) =
, step: 1.0 , step: 1.0
, width: 10.0 , width: 10.0
, height: 5.0 , height: 5.0
, onChange: setState <<< const , onChange: \range@(Range.Closed {min, max}) -> do
let mSigma = Sigmax.readSigma <$> R.readRef sigmaRef
case mSigma of
Just (Just s) -> Sigma.setSettings s {
minEdgeSize: min
, maxEdgeSize: max
}
_ -> pure unit
setState $ const range
} }
} }
nodeSizeControl :: R.State Range.NumberRange -> R.Element nodeSizeControl :: R.Ref (Maybe Sigmax.Sigma) -> R.State Range.NumberRange -> R.Element
nodeSizeControl (state /\ setState) = nodeSizeControl sigmaRef (state /\ setState) =
rangeControl { rangeControl {
caption: "Node Size" caption: "Node Size"
, sliderProps: { , sliderProps: {
...@@ -57,6 +68,14 @@ nodeSizeControl (state /\ setState) = ...@@ -57,6 +68,14 @@ nodeSizeControl (state /\ setState) =
, step: 1.0 , step: 1.0
, width: 10.0 , width: 10.0
, height: 5.0 , height: 5.0
, onChange: setState <<< const , onChange: \range@(Range.Closed {min, max}) -> do
let mSigma = Sigmax.readSigma <$> R.readRef sigmaRef
case mSigma of
Just (Just s) -> Sigma.setSettings s {
minNodeSize: min
, maxNodeSize: max
}
_ -> pure unit
setState $ const range
} }
} }
...@@ -7,13 +7,24 @@ module Gargantext.Components.GraphExplorer.SlideButton ...@@ -7,13 +7,24 @@ module Gargantext.Components.GraphExplorer.SlideButton
import Global (readFloat) import Global (readFloat)
import Prelude import Prelude
import Data.Maybe (Maybe(..))
import Data.Tuple (snd)
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
type Props = ( state :: R.State Number, caption :: String, min :: Number, max :: Number ) type Props = (
state :: R.State Number
, caption :: String
, min :: Number
, max :: Number
, onChange :: forall e. e -> Effect Unit
)
sizeButton :: Record Props -> R.Element sizeButton :: Record Props -> R.Element
sizeButton props = R.createElement sizeButtonCpt props [] sizeButton props = R.createElement sizeButtonCpt props []
...@@ -21,7 +32,7 @@ sizeButton props = R.createElement sizeButtonCpt props [] ...@@ -21,7 +32,7 @@ sizeButton props = R.createElement sizeButtonCpt props []
sizeButtonCpt :: R.Component Props sizeButtonCpt :: R.Component Props
sizeButtonCpt = R.hooksComponent "SizeButton" cpt sizeButtonCpt = R.hooksComponent "SizeButton" cpt
where where
cpt {state, caption, min, max} _ = do cpt {state, caption, min, max, onChange} _ = do
let (value /\ setValue) = state let (value /\ setValue) = state
pure $ pure $
H.span {} H.span {}
...@@ -31,14 +42,35 @@ sizeButtonCpt = R.hooksComponent "SizeButton" cpt ...@@ -31,14 +42,35 @@ sizeButtonCpt = R.hooksComponent "SizeButton" cpt
, min: show min , min: show min
, max: show max , max: show max
, defaultValue: value , defaultValue: value
, on: {input: \e -> setValue $ const $ readFloat $ R2.unsafeEventValue e } , on: {input: onChange}
} }
] ]
cursorSizeButton :: R.State Number -> R.Element cursorSizeButton :: R.State Number -> R.Element
cursorSizeButton state = cursorSizeButton state =
sizeButton { state: state, caption: "Cursor Size", min: 1.0, max: 4.0 } sizeButton {
state: state
, caption: "Cursor Size"
, min: 1.0
, max: 4.0
, onChange: \e -> snd state $ const $ readFloat $ R2.unsafeEventValue e
}
labelSizeButton :: R.State Number -> R.Element labelSizeButton :: R.Ref (Maybe Sigmax.Sigma) -> R.State Number -> R.Element
labelSizeButton state = labelSizeButton sigmaRef state =
sizeButton { state: state, caption: "Label Size", min: 1.0, max: 4.0 } sizeButton {
state: state
, caption: "Label Size"
, min: 1.0
, max: 4.0
, onChange: \e -> do
let mSigma = Sigmax.readSigma <$> R.readRef sigmaRef
let newValue = readFloat $ R2.unsafeEventValue e
let (value /\ setValue) = state
case mSigma of
Just (Just s) -> Sigma.setSettings s {
defaultLabelSize: newValue
}
_ -> pure unit
setValue $ const newValue
}
...@@ -10,20 +10,23 @@ module Gargantext.Components.GraphExplorer.ToggleButton ...@@ -10,20 +10,23 @@ module Gargantext.Components.GraphExplorer.ToggleButton
import Prelude import Prelude
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Tuple (snd)
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
import DOM.Simple.Console (log2) import DOM.Simple.Console (log2)
import Effect (Effect)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Gargantext.Hooks.Sigmax as Sigmax import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax.Sigma (restartForceAtlas2, stopForceAtlas2) import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
type Props = ( type Props = (
state :: R.State Boolean state :: R.State Boolean
, onMessage :: String , onMessage :: String
, offMessage :: String , offMessage :: String
, onClick :: forall e. e -> Effect Unit
) )
toggleButton :: Record Props -> R.Element toggleButton :: Record Props -> R.Element
...@@ -32,13 +35,13 @@ toggleButton props = R.createElement toggleButtonCpt props [] ...@@ -32,13 +35,13 @@ toggleButton props = R.createElement toggleButtonCpt props []
toggleButtonCpt :: R.Component Props toggleButtonCpt :: R.Component Props
toggleButtonCpt = R.hooksComponent "ToggleButton" cpt toggleButtonCpt = R.hooksComponent "ToggleButton" cpt
where where
cpt {state, onMessage, offMessage} _ = do cpt {state, onMessage, offMessage, onClick} _ = do
let (toggled /\ setToggled) = state let (toggled /\ _) = state
pure $ pure $
H.span {} H.span {}
[ [
H.button H.button
{ className: "btn btn-primary", on: {click: \_ -> setToggled not} } { className: "btn btn-primary", on: {click: onClick} }
[ H.text (text onMessage offMessage toggled) ] [ H.text (text onMessage offMessage toggled) ]
] ]
text on _off true = on text on _off true = on
...@@ -50,51 +53,47 @@ controlsToggleButton state = ...@@ -50,51 +53,47 @@ controlsToggleButton state =
state: state state: state
, onMessage: "Hide Controls" , onMessage: "Hide Controls"
, offMessage: "Show Controls" , offMessage: "Show Controls"
, onClick: \_ -> snd state not
} }
edgesToggleButton :: R.State Boolean -> R.Element edgesToggleButton :: R.Ref (Maybe Sigmax.Sigma) -> R.State Boolean -> R.Element
edgesToggleButton state = edgesToggleButton sigmaRef state =
toggleButton { toggleButton {
state: state state: state
, onMessage: "Hide Edges" , onMessage: "Hide Edges"
, offMessage: "Show Edges" , offMessage: "Show Edges"
, onClick: \_ -> do
let mSigma = Sigmax.readSigma <$> R.readRef sigmaRef
let (toggled /\ setToggled) = state
case mSigma of
Just (Just s) -> do
let settings = {
drawEdges: toggled
, drawEdgeLabels: toggled
, hideEdgesOnMove: not toggled
}
Sigma.setSettings s settings
_ -> pure unit
setToggled not
} }
pauseForceAtlasButton :: R.Ref (Maybe Sigmax.Sigma) -> R.State Boolean -> R.Element pauseForceAtlasButton :: R.Ref (Maybe Sigmax.Sigma) -> R.State Boolean -> R.Element
pauseForceAtlasButton sigmaRef state = R.createElement el props [] pauseForceAtlasButton sigmaRef state =
where toggleButton {
props = { state: state
state , onMessage: "Pause Force Atlas"
, onMessage: "Pause Force Atlas" , offMessage: "Start Force Atlas"
, offMessage: "Start Force Atlas" , onClick: \_ -> do
} let mSigma = Sigmax.readSigma <$> R.readRef sigmaRef
el = R.hooksComponent "ForceAtlasButton" cpt
cpt {state, onMessage, offMessage} _ = do
let (toggled /\ setToggled) = state let (toggled /\ setToggled) = state
pure $ case mSigma of
H.span {} Just (Just s) -> if toggled then
[ Sigma.stopForceAtlas2 s
H.button else
{ className: "btn btn-primary" Sigma.restartForceAtlas2 s
, on: {click: \_ -> do _ -> pure unit
let mSigma = R.readRef sigmaRef setToggled not
case mSigma of }
Nothing -> pure unit
Just sigma -> do
let rSigma = Sigmax.readSigma sigma
case rSigma of
Nothing -> pure unit
Just s -> if toggled then
stopForceAtlas2 s
else
restartForceAtlas2 s
setToggled not
}
}
[ H.text (text onMessage offMessage toggled) ]
]
text on _off true = on
text _on off false = off
treeToggleButton :: R.State Boolean -> R.Element treeToggleButton :: R.State Boolean -> R.Element
treeToggleButton state = treeToggleButton state =
...@@ -102,6 +101,7 @@ treeToggleButton state = ...@@ -102,6 +101,7 @@ treeToggleButton state =
state: state state: state
, onMessage: "Hide Tree" , onMessage: "Hide Tree"
, offMessage: "Show Tree" , offMessage: "Show Tree"
, onClick: \_ -> snd state not
} }
sidebarToggleButton :: R.State Boolean -> R.Element sidebarToggleButton :: R.State Boolean -> R.Element
...@@ -110,4 +110,5 @@ sidebarToggleButton state = ...@@ -110,4 +110,5 @@ sidebarToggleButton state =
state: state state: state
, onMessage: "Hide Sidebar" , onMessage: "Hide Sidebar"
, offMessage: "Show Sidebar" , offMessage: "Show Sidebar"
, onClick: \_ -> snd state not
} }
...@@ -49,6 +49,7 @@ function killSigma(left, right, sigma) { ...@@ -49,6 +49,7 @@ function killSigma(left, right, sigma) {
} }
function clear(sigma) { sigma.graph.clear(); } function clear(sigma) { sigma.graph.clear(); }
function bind(sigma, event, handler) { sigma.bind(event, handler); } function bind(sigma, event, handler) { sigma.bind(event, handler); }
function setSettings(sigma, settings) { sigma.settings(settings); }
function startForceAtlas2(sigma, settings) { sigma.startForceAtlas2(settings); } function startForceAtlas2(sigma, settings) { sigma.startForceAtlas2(settings); }
function stopForceAtlas2(sigma) { sigma.stopForceAtlas2(); } function stopForceAtlas2(sigma) { sigma.stopForceAtlas2(); }
function killForceAtlas2(sigma) { sigma.killForceAtlas2(); } function killForceAtlas2(sigma) { sigma.killForceAtlas2(); }
...@@ -62,6 +63,7 @@ exports._killRenderer = killRenderer; ...@@ -62,6 +63,7 @@ exports._killRenderer = killRenderer;
exports._killSigma = killSigma exports._killSigma = killSigma
exports._clear = clear; exports._clear = clear;
exports._bind = bind; exports._bind = bind;
exports._setSettings = setSettings;
exports._startForceAtlas2 = startForceAtlas2; exports._startForceAtlas2 = startForceAtlas2;
exports._stopForceAtlas2 = stopForceAtlas2; exports._stopForceAtlas2 = stopForceAtlas2;
exports._killForceAtlas2 = killForceAtlas2; exports._killForceAtlas2 = killForceAtlas2;
......
...@@ -96,6 +96,11 @@ bind_ s e h = runEffectFn3 _bind s e (mkEffectFn1 h) ...@@ -96,6 +96,11 @@ bind_ s e h = runEffectFn3 _bind s e (mkEffectFn1 h)
foreign import _bind :: forall e. EffectFn3 Sigma String (EffectFn1 e Unit) Unit foreign import _bind :: forall e. EffectFn3 Sigma String (EffectFn1 e Unit) Unit
setSettings :: forall settings. Sigma -> settings -> Effect Unit
setSettings = runEffectFn2 _setSettings
foreign import _setSettings :: forall settings. EffectFn2 Sigma settings Unit
startForceAtlas2 :: forall settings. Sigma -> settings -> Effect Unit startForceAtlas2 :: forall settings. Sigma -> settings -> Effect Unit
startForceAtlas2 = runEffectFn2 _startForceAtlas2 startForceAtlas2 = runEffectFn2 _startForceAtlas2
......
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