Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
purescript-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Grégoire Locqueville
purescript-gargantext
Commits
85a9a63a
Commit
85a9a63a
authored
Dec 11, 2019
by
Przemyslaw Kaminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Graph] more multiselect work
parent
5d91a271
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
110 additions
and
83 deletions
+110
-83
Login.css
dist/styles/Login.css
+5
-12
range-slider.css
dist/styles/range-slider.css
+2
-0
range-slider.sass
dist/styles/range-slider.sass
+2
-0
Graph.purs
src/Gargantext/Components/Graph.purs
+16
-14
GraphExplorer.purs
src/Gargantext/Components/GraphExplorer.purs
+26
-17
Controls.purs
src/Gargantext/Components/GraphExplorer/Controls.purs
+5
-15
Search.purs
src/Gargantext/Components/GraphExplorer/Search.purs
+11
-7
ToggleButton.purs
src/Gargantext/Components/GraphExplorer/ToggleButton.purs
+13
-1
Sigmax.purs
src/Gargantext/Hooks/Sigmax.purs
+23
-11
Sigma.purs
src/Gargantext/Hooks/Sigmax/Sigma.purs
+3
-0
Types.purs
src/Gargantext/Hooks/Sigmax/Types.purs
+4
-6
No files found.
dist/styles/Login.css
View file @
85a9a63a
...
@@ -79,18 +79,6 @@ li#rename #rename-a {
...
@@ -79,18 +79,6 @@ li#rename #rename-a {
width
:
1300px
;
width
:
1300px
;
}
}
#search-popup-tooltip
{
position
:
absolute
;
left
:
300px
;
top
:
-300px
;
background-color
:
white
;
z-index
:
1000
;
}
#search-popup-tooltip
:hover
{
border
:
none
;
text-decoration
:
none
;
}
#create-node-tooltip
{
#create-node-tooltip
{
position
:
absolute
;
position
:
absolute
;
left
:
96px
;
left
:
96px
;
...
@@ -216,6 +204,11 @@ li:hover a#rename-leaf {
...
@@ -216,6 +204,11 @@ li:hover a#rename-leaf {
justify-content
:
center
;
justify-content
:
center
;
}
}
.flex-center
{
display
:
flex
;
justify-content
:
space-between
;
}
a
:focus
,
a
:hover
{
a
:focus
,
a
:hover
{
cursor
:
pointer
;
cursor
:
pointer
;
}
}
...
...
dist/styles/range-slider.css
View file @
85a9a63a
.range
{
.range
{
width
:
400px
;
width
:
400px
;
/* some space for the right knob */
padding-right
:
30px
;
}
}
.range
.range-slider
{
.range
.range-slider
{
position
:
relative
;
position
:
relative
;
...
...
dist/styles/range-slider.sass
View file @
85a9a63a
.range
.range
width
:
400px
width
:
400px
/* some space for the right knob */
padding-right
:
30px
.range-slider
.range-slider
position
:
relative
position
:
relative
...
...
src/Gargantext/Components/Graph.purs
View file @
85a9a63a
...
@@ -4,10 +4,13 @@ module Gargantext.Components.Graph
...
@@ -4,10 +4,13 @@ module Gargantext.Components.Graph
-- , forceAtlas2Settings, ForceAtlas2Settings, ForceAtlas2OptionalSettings
-- , forceAtlas2Settings, ForceAtlas2Settings, ForceAtlas2OptionalSettings
-- )
-- )
where
where
import Prelude (bind, const, discard, pure, ($), unit)
import Prelude (bind, const, discard, pure, ($), unit, map)
import Data.Array as A
import Data.Either (Either(..))
import Data.Either (Either(..))
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
import Data.Nullable (Nullable)
import Data.Nullable (Nullable)
import Data.Tuple (fst)
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import DOM.Simple.Console (log, log2)
import DOM.Simple.Console (log, log2)
import DOM.Simple.Types (Element)
import DOM.Simple.Types (Element)
...
@@ -27,7 +30,7 @@ type Props sigma forceatlas2 =
...
@@ -27,7 +30,7 @@ type Props sigma forceatlas2 =
( elRef :: R.Ref (Nullable Element)
( elRef :: R.Ref (Nullable Element)
, forceAtlas2Settings :: forceatlas2
, forceAtlas2Settings :: forceatlas2
, graph :: SigmaxTypes.SGraph
, graph :: SigmaxTypes.SGraph
,
selectedEdgeIds :: R.State SigmaxTypes.SelectedEdgeIds
,
multiSelectEnabledRef :: R.Ref Boolean
, selectedNodeIds :: R.State SigmaxTypes.SelectedNodeIds
, selectedNodeIds :: R.State SigmaxTypes.SelectedNodeIds
, sigmaRef :: R.Ref Sigmax.Sigma
, sigmaRef :: R.Ref Sigmax.Sigma
, sigmaSettings :: sigma
, sigmaSettings :: sigma
...
@@ -51,9 +54,8 @@ graphCpt = R.hooksComponent "Graph" cpt
...
@@ -51,9 +54,8 @@ graphCpt = R.hooksComponent "Graph" cpt
Nothing -> RH.div {} []
Nothing -> RH.div {} []
Just el -> R.createPortal [] el
Just el -> R.createPortal [] el
stageHooks props@{stage: (Init /\ setStage)} = do
stageHooks props@{
multiSelectEnabledRef, selectedNodeIds, sigmaRef,
stage: (Init /\ setStage)} = do
R.useEffectOnce $ do
R.useEffectOnce $ do
log "[graphCpt] effect once"
let rSigma = R.readRef props.sigmaRef
let rSigma = R.readRef props.sigmaRef
case Sigmax.readSigma rSigma of
case Sigmax.readSigma rSigma of
...
@@ -64,7 +66,7 @@ graphCpt = R.hooksComponent "Graph" cpt
...
@@ -64,7 +66,7 @@ graphCpt = R.hooksComponent "Graph" cpt
Right sig -> do
Right sig -> do
Sigmax.writeSigma rSigma $ Just sig
Sigmax.writeSigma rSigma $ Just sig
Sigmax.dependOnContainer props.elRef "[graphCpt] container not found" $ \c -> do
Sigmax.dependOnContainer props.elRef "[graphCpt
(Ready)
] container not found" $ \c -> do
_ <- Sigma.addRenderer sig {
_ <- Sigma.addRenderer sig {
"type": "canvas"
"type": "canvas"
, container: c
, container: c
...
@@ -73,28 +75,28 @@ graphCpt = R.hooksComponent "Graph" cpt
...
@@ -73,28 +75,28 @@ graphCpt = R.hooksComponent "Graph" cpt
Sigmax.refreshData sig $ Sigmax.sigmafy props.graph
Sigmax.refreshData sig $ Sigmax.sigmafy props.graph
Sigmax.dependOnSigma (R.readRef sigmaRef) "[graphCpt (Ready)] no sigma" $ \sigma -> do
-- bind the click event only initially, when ref was empty
Sigmax.bindSelectedNodesClick sigma selectedNodeIds multiSelectEnabledRef
Sigmax.setEdges sig false
Sigmax.setEdges sig false
Sigma.startForceAtlas2 sig props.forceAtlas2Settings
Sigma.startForceAtlas2 sig props.forceAtlas2Settings
-- bind the click event only initially, when ref was empty
Sigmax.bindSelectedNodesClick props.sigmaRef props.selectedNodeIds props.selectedEdgeIds props.graph
--Sigmax.bindSelectedEdgesClick props.sigmaRef props.selectedEdgeIds
Just sig -> do
Just sig -> do
pure unit
pure unit
setStage $ const
$
Ready
setStage $ const Ready
delay unit $ \_ -> do
delay unit $ \_ -> do
log "[graphCpt] cleanup"
log "[graphCpt] cleanup"
pure $ pure unit
pure $ pure unit
stageHooks props@{s
tage: (Ready /\ setStage)
} = do
stageHooks props@{s
igmaRef, stage: (Ready /\ setStage), transformedGraph
} = do
let tEdgesMap = SigmaxTypes.edgesGraphMap
props.
transformedGraph
let tEdgesMap = SigmaxTypes.edgesGraphMap transformedGraph
let tNodesMap = SigmaxTypes.nodesGraphMap
props.
transformedGraph
let tNodesMap = SigmaxTypes.nodesGraphMap 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
sigmaRef) "[graphCpt (Ready)
] no sigma" $ \sigma -> do
Sigmax.updateEdges sigma tEdgesMap
Sigmax.updateEdges sigma tEdgesMap
Sigmax.updateNodes sigma tNodesMap
Sigmax.updateNodes sigma tNodesMap
...
...
src/Gargantext/Components/GraphExplorer.purs
View file @
85a9a63a
...
@@ -2,6 +2,7 @@ module Gargantext.Components.GraphExplorer where
...
@@ -2,6 +2,7 @@ module Gargantext.Components.GraphExplorer where
import Gargantext.Prelude hiding (max,min)
import Gargantext.Prelude hiding (max,min)
import Data.Array as A
import Data.FoldableWithIndex (foldMapWithIndex)
import Data.FoldableWithIndex (foldMapWithIndex)
import Data.Foldable (foldMap)
import Data.Foldable (foldMap)
import Data.Int (toNumber)
import Data.Int (toNumber)
...
@@ -12,7 +13,7 @@ import Data.Sequence as Seq
...
@@ -12,7 +13,7 @@ import Data.Sequence as Seq
import Data.Set as Set
import Data.Set as Set
import Data.Tuple (fst, snd, Tuple(..))
import Data.Tuple (fst, snd, Tuple(..))
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
--
import DOM.Simple.Console (log2)
import DOM.Simple.Console (log2)
import DOM.Simple.Types (Element)
import DOM.Simple.Types (Element)
import Effect.Aff (Aff)
import Effect.Aff (Aff)
import Math (log)
import Math (log)
...
@@ -88,7 +89,6 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
...
@@ -88,7 +89,6 @@ 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 controls.selectedEdgeIds $ const Set.empty
snd controls.selectedNodeIds $ const Set.empty
snd controls.selectedNodeIds $ const Set.empty
snd controls.graphStage $ const Graph.Init
snd controls.graphStage $ const Graph.Init
...
@@ -110,10 +110,6 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
...
@@ -110,10 +110,6 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
, elRef: graphRef
, elRef: graphRef
, graphId
, graphId
, graph
, graph
, graphStage: controls.graphStage
, selectedEdgeIds: controls.selectedEdgeIds
, selectedNodeIds: controls.selectedNodeIds
, sigmaRef: controls.sigmaRef
}
}
, mSidebar graph mMetaData { frontends
, mSidebar graph mMetaData { frontends
, session
, session
...
@@ -173,10 +169,6 @@ type GraphProps = (
...
@@ -173,10 +169,6 @@ type GraphProps = (
, elRef :: R.Ref (Nullable Element)
, elRef :: R.Ref (Nullable Element)
, graphId :: GraphId
, graphId :: GraphId
, graph :: SigmaxTypes.SGraph
, graph :: SigmaxTypes.SGraph
, graphStage :: R.State Graph.Stage
, selectedNodeIds :: R.State SigmaxTypes.SelectedNodeIds
, selectedEdgeIds :: R.State SigmaxTypes.SelectedEdgeIds
, sigmaRef :: R.Ref Sigmax.Sigma
)
)
graphView :: Record GraphProps -> R.Element
graphView :: Record GraphProps -> R.Element
...
@@ -185,19 +177,30 @@ graphView props = R.createElement el props []
...
@@ -185,19 +177,30 @@ 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 {controls, elRef, graphId, graph
, selectedEdgeIds, selectedNodeIds, sigmaRef
} _children = do
cpt {controls, elRef, graphId, graph} _children = do
-- TODO Cache this?
-- TODO Cache this?
let transformedGraph = transformGraph controls graph
let transformedGraph = transformGraph controls graph
multiSelectEnabledRef <- R.useRef $ fst controls.multiSelectEnabled
R.useEffect' $ do
let nodeColor {id, color} = [id, color]
let onlySelected g = Seq.filter (\n -> Set.member n.id (fst controls.selectedNodeIds)) $ SigmaxTypes.graphNodes g
log2 "[graphView] selectedNodeIds" $ A.fromFoldable $ fst controls.selectedNodeIds
log2 "[graphView] transformedGraph.nodes" $ A.fromFoldable $ map nodeColor $ onlySelected transformedGraph
log2 "[graphView] graph.nodes" $ A.fromFoldable $ map nodeColor $ onlySelected graph
R.setRef multiSelectEnabledRef $ fst controls.multiSelectEnabled
pure $ Graph.graph {
pure $ Graph.graph {
elRef
elRef
, forceAtlas2Settings: Graph.forceAtlas2Settings
, forceAtlas2Settings: Graph.forceAtlas2Settings
, graph
, graph
,
selectedEdgeIds
,
multiSelectEnabledRef
, selectedNodeIds
, selectedNodeIds
: controls.selectedNodeIds
, sigmaRef
, sigmaRef
: controls.sigmaRef
, sigmaSettings: Graph.sigmaSettings
, sigmaSettings: Graph.sigmaSettings
, stage:
prop
s.graphStage
, stage:
control
s.graphStage
, transformedGraph
, transformedGraph
}
}
...
@@ -367,16 +370,22 @@ transformGraph controls graph = SigmaxTypes.Graph {nodes: newNodes, edges: newEd
...
@@ -367,16 +370,22 @@ transformGraph controls graph = SigmaxTypes.Graph {nodes: newNodes, edges: newEd
nodes = SigmaxTypes.graphNodes graph
nodes = SigmaxTypes.graphNodes graph
graphEdgesMap = SigmaxTypes.edgesGraphMap graph
graphEdgesMap = SigmaxTypes.edgesGraphMap graph
graphNodesMap = SigmaxTypes.nodesGraphMap graph
graphNodesMap = SigmaxTypes.nodesGraphMap graph
selectedEdgeIds =
Set.fromFoldable
$ Seq.map _.id
$ Seq.filter (\e -> Set.member e.source (fst controls.selectedNodeIds)) edges
hasSelection = not $ Set.isEmpty (fst controls.selectedNodeIds)
newNodes = nodeSizes <$> nodeMarked <$> nodes
newNodes = nodeSizes <$> nodeMarked <$> nodes
newEdges = edgeMarked <$> edges
newEdges = edgeMarked <$> edges
hasSelection = not $ Set.isEmpty (fst controls.selectedNodeIds)
nodeSizes node@{ size } =
nodeSizes node@{ size } =
if Range.within (fst controls.nodeSize) size then
if Range.within (fst controls.nodeSize) size then
node
node
else
else
node { hidden = true }
node { hidden = true }
edgeMarked edge@{ id } = do
edgeMarked edge@{ id } = do
let isSelected = Set.member id
(fst controls.selectedEdgeIds)
let isSelected = Set.member id
selectedEdgeIds
let sourceNode = Map.lookup edge.source graphNodesMap
let sourceNode = Map.lookup edge.source graphNodesMap
case Tuple hasSelection isSelected of
case Tuple hasSelection isSelected of
Tuple false true -> edge { color = "#ff0000" }
Tuple false true -> edge { color = "#ff0000" }
...
...
src/Gargantext/Components/GraphExplorer/Controls.purs
View file @
85a9a63a
...
@@ -7,7 +7,6 @@ module Gargantext.Components.GraphExplorer.Controls
...
@@ -7,7 +7,6 @@ module Gargantext.Components.GraphExplorer.Controls
, getShowTree, setShowTree
, getShowTree, setShowTree
, getShowControls, setShowControls
, getShowControls, setShowControls
, getCursorSize, setCursorSize
, getCursorSize, setCursorSize
, getMultiNodeSelect, setMultiNodeSelect
) where
) where
import Data.Array as A
import Data.Array as A
...
@@ -27,7 +26,7 @@ import Gargantext.Components.GraphExplorer.Button (centerButton)
...
@@ -27,7 +26,7 @@ import Gargantext.Components.GraphExplorer.Button (centerButton)
import Gargantext.Components.GraphExplorer.RangeControl (edgeSizeControl, nodeSizeControl)
import Gargantext.Components.GraphExplorer.RangeControl (edgeSizeControl, nodeSizeControl)
import Gargantext.Components.GraphExplorer.Search (nodeSearchControl)
import Gargantext.Components.GraphExplorer.Search (nodeSearchControl)
import Gargantext.Components.GraphExplorer.SlideButton (cursorSizeButton, labelSizeButton)
import Gargantext.Components.GraphExplorer.SlideButton (cursorSizeButton, labelSizeButton)
import Gargantext.Components.GraphExplorer.ToggleButton (edgesToggleButton, pauseForceAtlasButton)
import Gargantext.Components.GraphExplorer.ToggleButton (
multiSelectEnabledButton,
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.Hooks.Sigmax.Types as SigmaxTypes
...
@@ -38,9 +37,8 @@ type Controls =
...
@@ -38,9 +37,8 @@ type Controls =
( cursorSize :: R.State Number
( cursorSize :: R.State Number
, graph :: SigmaxTypes.SGraph
, graph :: SigmaxTypes.SGraph
, graphStage :: R.State Graph.Stage
, graphStage :: R.State Graph.Stage
, multi
NodeSelect :: R.Ref
Boolean
, multi
SelectEnabled :: R.State
Boolean
, nodeSize :: R.State Range.NumberRange
, nodeSize :: R.State Range.NumberRange
, selectedEdgeIds :: R.State SigmaxTypes.SelectedEdgeIds
, selectedNodeIds :: R.State SigmaxTypes.SelectedNodeIds
, selectedNodeIds :: R.State SigmaxTypes.SelectedNodeIds
, showControls :: R.State Boolean
, showControls :: R.State Boolean
, showSidePanel :: R.State GET.SidePanelState
, showSidePanel :: R.State GET.SidePanelState
...
@@ -136,7 +134,7 @@ controlsCpt = R.hooksComponent "GraphControls" cpt
...
@@ -136,7 +134,7 @@ controlsCpt = R.hooksComponent "GraphControls" cpt
, 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 nodeSizeRange props.nodeSize ]
, RH.li {} [ nodeSizeControl nodeSizeRange props.nodeSize ]
-- zoom: 0 -100 - calculate ratio
-- zoom: 0 -100 - calculate ratio
-- toggle multi node selection
, RH.li {} [ multiSelectEnabledButton props.multiSelectEnabled ]
-- toggle multi node selection
-- save button
-- save button
, RH.li {} [ nodeSearchControl { selectedNodeIds: props.selectedNodeIds } ]
, RH.li {} [ nodeSearchControl { selectedNodeIds: props.selectedNodeIds } ]
]
]
...
@@ -150,11 +148,10 @@ useGraphControls graph = do
...
@@ -150,11 +148,10 @@ useGraphControls graph = do
cursorSize <- R.useState' 10.0
cursorSize <- R.useState' 10.0
graphStage <- R.useState' Graph.Init
graphStage <- R.useState' Graph.Init
multi
NodeSelect <- R.useRef fals
e
multi
SelectEnabled <- R.useState' tru
e
nodeSize <- R.useState' $ Range.Closed { min: 0.0, max: 100.0 }
nodeSize <- R.useState' $ Range.Closed { min: 0.0, max: 100.0 }
showTree <- R.useState' false
showTree <- R.useState' false
selectedNodeIds <- R.useState' $ Set.empty
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
sigma <- Sigmax.initSigma
sigma <- Sigmax.initSigma
...
@@ -163,9 +160,8 @@ useGraphControls graph = do
...
@@ -163,9 +160,8 @@ useGraphControls graph = do
pure { cursorSize
pure { cursorSize
, graph
, graph
, graphStage
, graphStage
, multi
NodeSelect
, multi
SelectEnabled
, nodeSize
, nodeSize
, selectedEdgeIds
, selectedNodeIds
, selectedNodeIds
, showControls
, showControls
, showSidePanel
, showSidePanel
...
@@ -182,9 +178,6 @@ getShowTree { showTree: ( should /\ _ ) } = should
...
@@ -182,9 +178,6 @@ getShowTree { showTree: ( should /\ _ ) } = should
getCursorSize :: Record Controls -> Number
getCursorSize :: Record Controls -> Number
getCursorSize { cursorSize: ( size /\ _ ) } = size
getCursorSize { cursorSize: ( size /\ _ ) } = size
getMultiNodeSelect :: Record Controls -> Boolean
getMultiNodeSelect { multiNodeSelect } = R.readRef multiNodeSelect
setShowControls :: Record Controls -> Boolean -> Effect Unit
setShowControls :: Record Controls -> Boolean -> Effect Unit
setShowControls { showControls: ( _ /\ set ) } v = set $ const v
setShowControls { showControls: ( _ /\ set ) } v = set $ const v
...
@@ -193,6 +186,3 @@ setShowTree { showTree: ( _ /\ set ) } v = set $ not <<< const v
...
@@ -193,6 +186,3 @@ setShowTree { showTree: ( _ /\ set ) } v = set $ not <<< 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
setMultiNodeSelect :: Record Controls -> Boolean -> Effect Unit
setMultiNodeSelect { multiNodeSelect } = R.setRef multiNodeSelect
src/Gargantext/Components/GraphExplorer/Search.purs
View file @
85a9a63a
...
@@ -33,14 +33,18 @@ sizeButtonCpt = R.hooksComponent "NodeSearchControl" cpt
...
@@ -33,14 +33,18 @@ sizeButtonCpt = R.hooksComponent "NodeSearchControl" cpt
(search /\ setSearch) <- R.useState' ""
(search /\ setSearch) <- R.useState' ""
pure $
pure $
H.span {}
H.div { className: "form-group" }
[ H.div { className: "input-group" }
[ H.input { type: "text"
[ H.input { type: "text"
, className: "form-control"
, className: "form-control"
, defaultValue: search
, defaultValue: search
, on: { input: \e -> setSearch $ const $ e .. "target" .. "value" }
, on: { input: \e -> setSearch $ const $ e .. "target" .. "value" }
}
}
, H.button { className: "btn btn-primary"
, H.div { className: "btn input-group-addon"
, on: { click: \_ -> log2 "[sizeButtonCpt] search" search }} [ H.text "Search" ]
, on: { click: \_ -> log2 "[sizeButtonCpt] search" search }
}
[ H.span { className: "fa fa-search" } [] ]
]
]
]
-- TODO Wherefrom do I get graph nodes?
-- TODO Wherefrom do I get graph nodes?
...
...
src/Gargantext/Components/GraphExplorer/ToggleButton.purs
View file @
85a9a63a
module Gargantext.Components.GraphExplorer.ToggleButton
module Gargantext.Components.GraphExplorer.ToggleButton
( Props, toggleButton, toggleButtonCpt
( Props
, toggleButton
, toggleButtonCpt
, multiSelectEnabledButton
, controlsToggleButton
, controlsToggleButton
, edgesToggleButton
, edgesToggleButton
, sidebarToggleButton
, sidebarToggleButton
...
@@ -66,6 +69,15 @@ edgesToggleButton sigmaRef state =
...
@@ -66,6 +69,15 @@ edgesToggleButton sigmaRef state =
setToggled not
setToggled not
}
}
multiSelectEnabledButton :: R.State Boolean -> R.Element
multiSelectEnabledButton state =
toggleButton {
state: state
, onMessage: "Single-node"
, offMessage: "Multi-node"
, onClick: \_ -> snd state not
}
pauseForceAtlasButton :: R.Ref Sigmax.Sigma -> R.State Boolean -> R.Element
pauseForceAtlasButton :: R.Ref Sigmax.Sigma -> R.State Boolean -> R.Element
pauseForceAtlasButton sigmaRef state =
pauseForceAtlasButton sigmaRef state =
toggleButton {
toggleButton {
...
...
src/Gargantext/Hooks/Sigmax.purs
View file @
85a9a63a
...
@@ -5,7 +5,7 @@ import Prelude (Unit, bind, discard, flip, pure, unit, ($), (*>), (<<<), (<>), (
...
@@ -5,7 +5,7 @@ import Prelude (Unit, bind, discard, flip, pure, unit, ($), (*>), (<<<), (<>), (
import Data.Array as A
import Data.Array as A
import Data.Either (either)
import Data.Either (either)
import Data.Foldable (sequence_)
import Data.Foldable (sequence_
, foldl
)
import Data.Map as Map
import Data.Map as Map
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
import Data.Nullable (Nullable)
import Data.Nullable (Nullable)
...
@@ -22,7 +22,7 @@ import Effect.Class.Console (error)
...
@@ -22,7 +22,7 @@ import Effect.Class.Console (error)
import Effect.Timer (TimeoutId, clearTimeout)
import Effect.Timer (TimeoutId, clearTimeout)
import FFI.Simple ((.=))
import FFI.Simple ((.=))
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Hooks.Sigmax.Types (Graph(..), SGraph, EdgesMap, NodesMap, SelectedNodeIds, SelectedEdgeIds)
import Gargantext.Hooks.Sigmax.Types (Graph(..), SGraph, EdgesMap, NodesMap, SelectedNodeIds, SelectedEdgeIds
, graphEdges
)
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix as R
...
@@ -210,16 +210,28 @@ updateNodes sigma nodesMap = do
...
@@ -210,16 +210,28 @@ updateNodes sigma nodesMap = do
Sigma.refresh sigma
Sigma.refresh sigma
bindSelectedNodesClick :: R.Ref Sigma -> R.State SelectedNodeIds -> R.State SelectedEdgeIds -> SGraph -> Effect Unit
-- | Toggles item visibility in the selected set
bindSelectedNodesClick sigmaRef (_ /\ setSelectedNodeIds) (_ /\ setSelectedEdgeIds) (Graph {edges, nodes}) =
multiSelectUpdate :: SelectedNodeIds -> SelectedNodeIds -> SelectedNodeIds
dependOnSigma (R.readRef sigmaRef) "[graphCpt] no sigma" $ \sigma -> do
multiSelectUpdate new selected = foldl fld selected new
where
fld selectedAcc item =
if Set.member item selectedAcc then
Set.delete item selectedAcc
else
Set.insert item selectedAcc
bindSelectedNodesClick :: Sigma.Sigma -> R.State SelectedNodeIds -> R.Ref Boolean -> Effect Unit
bindSelectedNodesClick sigma (_ /\ setSelectedNodeIds) multiSelectEnabledRef =
Sigma.bindClickNodes sigma $ \nodes -> do
Sigma.bindClickNodes sigma $ \nodes -> do
log2 "[bindSelectedNodesClick] nodes" nodes
let multiSelectEnabled = R.readRef multiSelectEnabledRef
log2 "[bindSelectedNodesClick] multiSelectEnabled" multiSelectEnabled
let nodeIds = Set.fromFoldable $ map _.id nodes
let nodeIds = Set.fromFoldable $ map _.id nodes
if multiSelectEnabled then
setSelectedNodeIds $ multiSelectUpdate nodeIds
else
setSelectedNodeIds $ const nodeIds
setSelectedNodeIds $ const nodeIds
setSelectedEdgeIds \_ ->
Set.fromFoldable
$ Seq.map _.id
$ Seq.filter (\e -> Set.member e.source nodeIds) edges
bindSelectedEdgesClick :: R.Ref Sigma -> R.State SelectedEdgeIds -> Effect Unit
bindSelectedEdgesClick :: R.Ref Sigma -> R.State SelectedEdgeIds -> Effect Unit
bindSelectedEdgesClick sigmaRef (_ /\ setSelectedEdgeIds) =
bindSelectedEdgesClick sigmaRef (_ /\ setSelectedEdgeIds) =
...
...
src/Gargantext/Hooks/Sigmax/Sigma.purs
View file @
85a9a63a
...
@@ -147,6 +147,9 @@ bindClickNodes s f = bind_ s "clickNodes" $ \e -> do
...
@@ -147,6 +147,9 @@ bindClickNodes s f = bind_ s "clickNodes" $ \e -> do
let nodes = e .. "data" .. "node" :: Array (Record Types.Node)
let nodes = e .. "data" .. "node" :: Array (Record Types.Node)
f nodes
f nodes
unbindClickNodes :: Sigma -> Effect Unit
unbindClickNodes s = unbind_ s "clickNodes"
bindOverNode :: Sigma -> (Record Types.Node -> Effect Unit) -> Effect Unit
bindOverNode :: Sigma -> (Record Types.Node -> Effect Unit) -> Effect Unit
bindOverNode s f = bind_ s "overNode" $ \e -> do
bindOverNode s f = bind_ s "overNode" $ \e -> do
let node = e .. "data" .. "node" :: Record Types.Node
let node = e .. "data" .. "node" :: Record Types.Node
...
...
src/Gargantext/Hooks/Sigmax/Types.purs
View file @
85a9a63a
...
@@ -48,17 +48,15 @@ graphNodes :: SGraph -> Seq (Record Node)
...
@@ -48,17 +48,15 @@ graphNodes :: SGraph -> Seq (Record Node)
graphNodes (Graph {nodes}) = nodes
graphNodes (Graph {nodes}) = nodes
edgesGraphMap :: Graph Node Edge -> EdgesMap
edgesGraphMap :: Graph Node Edge -> EdgesMap
edgesGraphMap graph = do
edgesGraphMap graph =
let (Graph {edges}) = graph
Map.fromFoldable $ map (\e -> Tuple e.id e) $ graphEdges graph
Map.fromFoldable $ map (\e -> Tuple e.id e) edges
nodesMap :: Seq (Record Node) -> NodesMap
nodesMap :: Seq (Record Node) -> NodesMap
nodesMap nodes = Map.fromFoldable $ map (\n -> Tuple n.id n) nodes
nodesMap nodes = Map.fromFoldable $ map (\n -> Tuple n.id n) nodes
nodesGraphMap :: Graph Node Edge -> NodesMap
nodesGraphMap :: Graph Node Edge -> NodesMap
nodesGraphMap graph = do
nodesGraphMap graph =
let (Graph {nodes}) = graph
nodesMap $ graphNodes graph
nodesMap nodes
eqGraph :: (Graph Node Edge) -> (Graph Node Edge) -> Boolean
eqGraph :: (Graph Node Edge) -> (Graph Node Edge) -> Boolean
eqGraph (Graph {nodes: n1, edges: e1}) (Graph {nodes: n2, edges: e2}) = (n1 == n2) && (e1 == e2)
eqGraph (Graph {nodes: n1, edges: e1}) (Graph {nodes: n2, edges: e2}) = (n1 == n2) && (e1 == e2)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment