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
142
Issues
142
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
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
gargantext
purescript-gargantext
Commits
67593ada
Commit
67593ada
authored
Dec 20, 2019
by
Przemyslaw Kaminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Graph] graph walk functionality
I.e. neighbor badges are clickable now.
parent
79f5d45e
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
82 additions
and
40 deletions
+82
-40
Graph.css
dist/styles/Graph.css
+2
-2
Graph.sass
dist/styles/Graph.sass
+1
-1
GraphExplorer.purs
src/Gargantext/Components/GraphExplorer.purs
+12
-13
Controls.purs
src/Gargantext/Components/GraphExplorer/Controls.purs
+1
-1
Sidebar.purs
src/Gargantext/Components/GraphExplorer/Sidebar.purs
+20
-10
Array.purs
src/Gargantext/Data/Array.purs
+14
-3
Types.purs
src/Gargantext/Hooks/Sigmax/Types.purs
+32
-10
No files found.
dist/styles/Graph.css
View file @
67593ada
...
@@ -17,7 +17,7 @@
...
@@ -17,7 +17,7 @@
position
:
absolute
;
position
:
absolute
;
max-height
:
600px
;
max-height
:
600px
;
overflow-y
:
scroll
;
overflow-y
:
scroll
;
top
:
1
5
0px
;
top
:
1
7
0px
;
z-index
:
1
;
z-index
:
1
;
}
}
#graph-explorer
#graph-view
{
#graph-explorer
#graph-view
{
...
@@ -27,7 +27,7 @@
...
@@ -27,7 +27,7 @@
position
:
absolute
;
position
:
absolute
;
max-height
:
600px
;
max-height
:
600px
;
overflow-y
:
scroll
;
overflow-y
:
scroll
;
top
:
1
5
0px
;
top
:
1
7
0px
;
z-index
:
1
;
z-index
:
1
;
left
:
70%
;
left
:
70%
;
border
:
1px
white
solid
;
border
:
1px
white
solid
;
...
...
dist/styles/Graph.sass
View file @
67593ada
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
position
:
absolute
position
:
absolute
max-height
:
600px
max-height
:
600px
overflow-y
:
scroll
overflow-y
:
scroll
top
:
1
5
0px
top
:
1
7
0px
z-index
:
1
z-index
:
1
#graph-explorer
#graph-explorer
...
...
src/Gargantext/Components/GraphExplorer.purs
View file @
67593ada
...
@@ -201,7 +201,7 @@ convert :: GET.GraphData -> Tuple (Maybe GET.MetaData) SigmaxTypes.SGraph
...
@@ -201,7 +201,7 @@ convert :: GET.GraphData -> Tuple (Maybe GET.MetaData) SigmaxTypes.SGraph
convert (GET.GraphData r) = Tuple r.metaData $ SigmaxTypes.Graph {nodes, edges}
convert (GET.GraphData r) = Tuple r.metaData $ SigmaxTypes.Graph {nodes, edges}
where
where
nodes = foldMapWithIndex nodeFn r.nodes
nodes = foldMapWithIndex nodeFn r.nodes
nodeFn i (GET.Node n) =
nodeFn
_
i (GET.Node n) =
Seq.singleton
Seq.singleton
{ borderColor: color
{ borderColor: color
, color : color
, color : color
...
@@ -224,12 +224,14 @@ convert (GET.GraphData r) = Tuple r.metaData $ SigmaxTypes.Graph {nodes, edges}
...
@@ -224,12 +224,14 @@ convert (GET.GraphData r) = Tuple r.metaData $ SigmaxTypes.Graph {nodes, edges}
, hidden : false
, hidden : false
, size: 1.0
, size: 1.0
, source : e.source
, source : e.source
, sourceNode
, target : e.target
, target : e.target
, targetNode
, weight : e.weight }
, weight : e.weight }
where
where
color = case Map.lookup e.source nodesMap of
sourceNode = unsafePartial $ fromJust $ Map.lookup e.source nodesMap
Nothing -> "#000000"
targetNode = unsafePartial $ fromJust $ Map.lookup e.target nodesMap
Just node -> n
ode.color
color = sourceN
ode.color
defaultPalette :: Array String
defaultPalette :: Array String
defaultPalette = ["#5fa571","#ab9ba2","#da876d","#bdd3ff"
defaultPalette = ["#5fa571","#ab9ba2","#da876d","#bdd3ff"
...
@@ -371,16 +373,14 @@ transformGraph controls graph = SigmaxTypes.Graph {nodes: newNodes, edges: newEd
...
@@ -371,16 +373,14 @@ transformGraph controls graph = SigmaxTypes.Graph {nodes: newNodes, edges: newEd
where
where
edges = SigmaxTypes.graphEdges graph
edges = SigmaxTypes.graphEdges graph
nodes = SigmaxTypes.graphNodes graph
nodes = SigmaxTypes.graphNodes graph
graphEdgesMap = SigmaxTypes.edgesGraphMap graph
graphNodesMap = SigmaxTypes.nodesGraphMap graph
selectedEdgeIds =
selectedEdgeIds =
Set.fromFoldable
Set.fromFoldable
$ Seq.map _.id
$ Seq.map _.id
$ S
eq.filter (\e -> Set.member e.source (fst controls.selectedNodeIds)) edges
$ S
igmaxTypes.neighbouringEdges graph (fst controls.selectedNodeIds)
hasSelection = not $ Set.isEmpty (fst controls.selectedNodeIds)
hasSelection = not $ Set.isEmpty (fst controls.selectedNodeIds)
newNodes =
nodeSizeFilter <$> nodeMarked <$>
nodes
newNodes =
Seq.map (nodeSizeFilter <<< nodeMarked)
nodes
newEdges =
edgeConfluenceFilter <$> edgeWeightFilter <$> edgeShowFilter <$> edgeMarked <$>
edges
newEdges =
Seq.map (edgeConfluenceFilter <<< edgeWeightFilter <<< edgeShowFilter <<< edgeMarked)
edges
nodeSizeFilter node@{ size } =
nodeSizeFilter node@{ size } =
if Range.within (fst controls.nodeSize) size then
if Range.within (fst controls.nodeSize) size then
...
@@ -404,13 +404,12 @@ transformGraph controls graph = SigmaxTypes.Graph {nodes: newNodes, edges: newEd
...
@@ -404,13 +404,12 @@ transformGraph controls graph = SigmaxTypes.Graph {nodes: newNodes, edges: newEd
else
else
edge { hidden = true }
edge { hidden = true }
edgeMarked edge@{ id } = do
edgeMarked edge@{ id
, sourceNode
} = do
let isSelected = Set.member id selectedEdgeIds
let isSelected = Set.member id selectedEdgeIds
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" }
Tuple true true -> edge { color =
(unsafePartial $ fromJust sourceNode)
.color }
Tuple true true -> edge { color =
sourceNode
.color }
Tuple true
false -> edge { color = "#dddddd
" }
Tuple true
false -> edge { color = "rgba(221, 221, 221, 0.5)
" }
_ -> edge
_ -> edge
nodeMarked node@{ id } =
nodeMarked node@{ id } =
if Set.member id (fst controls.selectedNodeIds) then
if Set.member id (fst controls.selectedNodeIds) then
...
...
src/Gargantext/Components/GraphExplorer/Controls.purs
View file @
67593ada
...
@@ -172,7 +172,7 @@ useGraphControls graph = do
...
@@ -172,7 +172,7 @@ useGraphControls graph = do
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
selectorSize <- R.useState' 5
selectorSize <- R.useState'
1
5
showControls <- R.useState' false
showControls <- R.useState' false
showEdges <- R.useState' SigmaxTypes.EShow
showEdges <- R.useState' SigmaxTypes.EShow
showSidePanel <- R.useState' GET.InitialClosed
showSidePanel <- R.useState' GET.InitialClosed
...
...
src/Gargantext/Components/GraphExplorer/Sidebar.purs
View file @
67593ada
...
@@ -6,12 +6,12 @@ import Prelude
...
@@ -6,12 +6,12 @@ import Prelude
import Data.Array (head)
import Data.Array (head)
import Data.Map as Map
import Data.Map as Map
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
import Data.Sequence as Seq
import Data.Set as Set
import Data.Set as Set
import Data.Tuple.Nested((/\))
import Data.Tuple.Nested((/\))
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as RH
import Reactix.DOM.HTML as RH
import Gargantext.Data.Array (catMaybes)
import Gargantext.Components.RandomText (words)
import Gargantext.Components.RandomText (words)
import Gargantext.Components.Nodes.Corpus.Graph.Tabs as GT
import Gargantext.Components.Nodes.Corpus.Graph.Tabs as GT
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Components.GraphExplorer.Types as GET
...
@@ -53,11 +53,16 @@ sidebarCpt = R.hooksComponent "Sidebar" cpt
...
@@ -53,11 +53,16 @@ sidebarCpt = R.hooksComponent "Sidebar" cpt
, data: {toggle: "tab"}
, data: {toggle: "tab"}
, href: "#home"
, href: "#home"
, role: "tab"
, role: "tab"
, aria: {controls: "home", selected: "true"}}
, aria: {controls: "home", selected: "true"}
[ RH.text "Selected nodes" ] ] ]
}
[ RH.text "Selected nodes" ]
]
]
, RH.div { className: "tab-content", id: "myTabContent" }
, RH.div { className: "tab-content", id: "myTabContent" }
[ RH.div { className: "", id: "home", role: "tabpanel" }
[ RH.div { className: "", id: "home", role: "tabpanel" }
(badge <$> badges props.selectedNodeIds nodesMap) ] ]
(Seq.toUnfoldable $ (Seq.map (badge props.selectedNodeIds) (badges props.graph props.selectedNodeIds)))
]
]
{-, RH.div { className: "col-md-12", id: "horizontal-checkbox" }
{-, RH.div { className: "col-md-12", id: "horizontal-checkbox" }
[ RH.ul {}
[ RH.ul {}
[ checkbox "Pubs"
[ checkbox "Pubs"
...
@@ -74,8 +79,13 @@ sidebarCpt = R.hooksComponent "Sidebar" cpt
...
@@ -74,8 +79,13 @@ sidebarCpt = R.hooksComponent "Sidebar" cpt
]
]
]
]
]
]
badge text =
badge (_ /\ setSelectedNodeIds) {id, label} =
RH.a { className: "badge badge-light" } [ RH.text text ]
RH.a { className: "badge badge-light"
, on: { click: onClick }
} [ RH.text label ]
where
onClick e = do
setSelectedNodeIds $ const $ Set.singleton id
checkbox text =
checkbox text =
RH.li {}
RH.li {}
[ RH.span {} [ RH.text text ]
[ RH.span {} [ RH.text text ]
...
@@ -83,10 +93,10 @@ sidebarCpt = R.hooksComponent "Sidebar" cpt
...
@@ -83,10 +93,10 @@ sidebarCpt = R.hooksComponent "Sidebar" cpt
, className: "checkbox"
, className: "checkbox"
, checked: true
, checked: true
, title: "Mark as completed" } ]
, title: "Mark as completed" } ]
badges
(selectedNodeIds /\ _) nodesMap = map (\n -> n.label
)
badges
:: SigmaxTypes.SGraph -> R.State SigmaxTypes.SelectedNodeIds -> Seq.Seq (Record SigmaxTypes.Node
)
$ catMayb
es
badges graph (selectedNodeIds /\ _) = SigmaxTypes.neighbours graph selectedNod
es
$ map (\n -> Map.lookup n nodesMap)
where
$ Set.toUnfoldable
selectedNodeIds
selectedNodes = SigmaxTypes.nodesById graph
selectedNodeIds
query _ _ _ _ (selectedNodeIds /\ _) | Set.isEmpty selectedNodeIds = RH.div {} []
query _ _ _ _ (selectedNodeIds /\ _) | Set.isEmpty selectedNodeIds = RH.div {} []
query frontends (GET.MetaData metaData) session nodesMap (selectedNodeIds /\ _) =
query frontends (GET.MetaData metaData) session nodesMap (selectedNodeIds /\ _) =
...
...
src/Gargantext/Data/Array.purs
View file @
67593ada
...
@@ -3,7 +3,7 @@ module Gargantext.Data.Array
...
@@ -3,7 +3,7 @@ module Gargantext.Data.Array
import Data.Array as DA
import Data.Array as DA
import Data.Maybe
import Data.Maybe
import Data.Sequence as
DS
import Data.Sequence as
Seq
import Data.Tuple (Tuple(..))
import Data.Tuple (Tuple(..))
import Prelude (bind, flip, identity, (<<<))
import Prelude (bind, flip, identity, (<<<))
...
@@ -16,9 +16,9 @@ splitEvery n xs =
...
@@ -16,9 +16,9 @@ splitEvery n xs =
in DA.cons h (splitEvery n t)
in DA.cons h (splitEvery n t)
splitAt :: forall a. Int -> Array a -> Tuple (Array a) (Array a)
splitAt :: forall a. Int -> Array a -> Tuple (Array a) (Array a)
splitAt n ls = Tuple (
DS.toUnfoldable x) (DS
.toUnfoldable xs)
splitAt n ls = Tuple (
Seq.toUnfoldable x) (Seq
.toUnfoldable xs)
where
where
Tuple x xs =
DS.splitAt n (DS
.fromFoldable ls)
Tuple x xs =
Seq.splitAt n (Seq
.fromFoldable ls)
----------------------------------------------------------------------
----------------------------------------------------------------------
-- | Array with Maybe tools
-- | Array with Maybe tools
...
@@ -36,4 +36,15 @@ concatMap = flip bind
...
@@ -36,4 +36,15 @@ concatMap = flip bind
singleton :: forall a. a -> Array a
singleton :: forall a. a -> Array a
singleton a = [a]
singleton a = [a]
----------------------------------------------------------------------
-- | Seq with Maybe tools
seqMapMaybe :: forall a b. (a -> Maybe b) -> Seq.Seq a -> Seq.Seq b
seqMapMaybe f = seqConcatMap (maybe Seq.empty Seq.singleton <<< f)
seqCatMaybes :: forall a. Seq.Seq (Maybe a) -> Seq.Seq a
seqCatMaybes = seqMapMaybe identity
----------------------------------------------------------------------
-- | Seq misc tools
seqConcatMap :: forall a b. (a -> Seq.Seq b) -> Seq.Seq a -> Seq.Seq b
seqConcatMap = flip bind
src/Gargantext/Hooks/Sigmax/Types.purs
View file @
67593ada
module Gargantext.Hooks.Sigmax.Types where
module Gargantext.Hooks.Sigmax.Types where
import
Prelude (map, ($), (&&), (==), class Eq, class Ord, class Show, Ordering, compare
)
import
DOM.Simple.Types (Element
)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Eq (genericEq)
import Data.Generic.Rep.Eq (genericEq)
import Data.Generic.Rep.Show (genericShow)
import Data.Generic.Rep.Show (genericShow)
import Data.Map as Map
import Data.Map as Map
import Data.Sequence
(Seq)
import Data.Sequence
as Seq
import Data.Set as Set
import Data.Set as Set
import Data.Tuple (Tuple(..))
import Data.Tuple (Tuple(..))
import
DOM.Simple.Types (Element
)
import
Prelude (map, ($), (&&), (||), (==), class Eq, class Ord, class Show, Ordering, compare
)
newtype Graph n e = Graph { nodes :: Seq
{|n}, edges ::
Seq {|e} }
newtype Graph n e = Graph { nodes :: Seq
.Seq {|n}, edges :: Seq.
Seq {|e} }
--derive instance eqGraph :: Eq Graph
--derive instance eqGraph :: Eq Graph
...
@@ -40,7 +40,9 @@ type Edge =
...
@@ -40,7 +40,9 @@ type Edge =
, hidden :: Boolean
, hidden :: Boolean
, size :: Number
, size :: Number
, source :: String
, source :: String
, sourceNode :: Record Node
, target :: String
, target :: String
, targetNode :: Record Node
, weight :: Number )
, weight :: Number )
type SelectedNodeIds = Set.Set String
type SelectedNodeIds = Set.Set String
...
@@ -50,24 +52,44 @@ type NodesMap = Map.Map String (Record Node)
...
@@ -50,24 +52,44 @@ type NodesMap = Map.Map String (Record Node)
type SGraph = Graph Node Edge
type SGraph = Graph Node Edge
graphEdges :: SGraph -> Seq (Record Edge)
graphEdges :: SGraph -> Seq
.Seq
(Record Edge)
graphEdges (Graph {edges}) = edges
graphEdges (Graph {edges}) = edges
graphNodes :: SGraph -> Seq (Record Node)
graphNodes :: SGraph -> Seq
.Seq
(Record Node)
graphNodes (Graph {nodes}) = nodes
graphNodes (Graph {nodes}) = nodes
edgesGraphMap ::
Graph Node Edge
-> EdgesMap
edgesGraphMap ::
SGraph
-> EdgesMap
edgesGraphMap graph =
edgesGraphMap graph =
Map.fromFoldable $ map (\e -> Tuple e.id e) $ graphEdges graph
Map.fromFoldable $ map (\e -> Tuple e.id e) $ graphEdges graph
nodesMap :: Seq (Record Node) -> NodesMap
edgesById :: SGraph -> SelectedEdgeIds -> Seq.Seq (Record Edge)
edgesById g edgeIds = Seq.filter (\e -> Set.member e.id edgeIds) $ graphEdges g
nodesMap :: Seq.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 ::
SGraph
-> NodesMap
nodesGraphMap graph =
nodesGraphMap graph =
nodesMap $ graphNodes graph
nodesMap $ graphNodes graph
eqGraph :: (Graph Node Edge) -> (Graph Node Edge) -> Boolean
nodesById :: SGraph -> SelectedNodeIds -> Seq.Seq (Record Node)
nodesById g nodeIds = Seq.filter (\n -> Set.member n.id nodeIds) $ graphNodes g
neighbours :: SGraph -> Seq.Seq (Record Node) -> Seq.Seq (Record Node)
neighbours g nodes = Seq.fromFoldable $ Set.unions [Set.fromFoldable nodes, sources, targets]
where
nMap = nodesMap $ graphNodes g
nodeIds = Set.fromFoldable $ Seq.map _.id nodes
selectedEdges = neighbouringEdges g nodeIds
sources = Set.fromFoldable $ nodesById g $ Set.fromFoldable $ Seq.map _.source selectedEdges
targets = Set.fromFoldable $ nodesById g $ Set.fromFoldable $ Seq.map _.target selectedEdges
neighbouringEdges :: SGraph -> SelectedNodeIds -> Seq.Seq (Record Edge)
neighbouringEdges g nodeIds = Seq.filter condition $ graphEdges g
where
condition {source, target} = (Set.member source nodeIds) || (Set.member target nodeIds)
eqGraph :: SGraph -> SGraph -> 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