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
89d1033b
Commit
89d1033b
authored
Apr 20, 2022
by
arturo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
>>> continue (store)
parent
b8befd87
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
902 additions
and
860 deletions
+902
-860
Data.purs
src/Gargantext/Components/App/Data.purs
+0
-4
Layout.purs
src/Gargantext/Components/GraphExplorer/Layout.purs
+109
-104
Resources.purs
src/Gargantext/Components/GraphExplorer/Resources.purs
+140
-125
Sidebar.purs
src/Gargantext/Components/GraphExplorer/Sidebar/Sidebar.purs
+183
-180
Types.purs
src/Gargantext/Components/GraphExplorer/Sidebar/Types.purs
+0
-81
Store.purs
src/Gargantext/Components/GraphExplorer/Store.purs
+122
-0
Controls.purs
...Gargantext/Components/GraphExplorer/Toolbar/Controls.purs
+209
-289
TopBar.purs
src/Gargantext/Components/GraphExplorer/Topbar/TopBar.purs
+16
-22
Types.purs
src/Gargantext/Components/GraphExplorer/Types.purs
+8
-5
Graph.purs
src/Gargantext/Components/Nodes/Graph.purs
+57
-50
Reactix.purs
src/Gargantext/Utils/Reactix.purs
+2
-0
Stores.purs
src/Gargantext/Utils/Stores.purs
+56
-0
No files found.
src/Gargantext/Components/App/Data.purs
View file @
89d1033b
...
...
@@ -6,7 +6,6 @@ import Gargantext.Prelude
import Data.Maybe (Maybe(..))
import Data.Set as Set
import Gargantext.AsyncTasks as GAT
import Gargantext.Components.GraphExplorer.Sidebar.Types as GEST
import Gargantext.Components.Lang as Lang
import Gargantext.Components.Nodes.Lists.Types as ListsT
import Gargantext.Components.Nodes.Texts.Types as TextsT
...
...
@@ -36,7 +35,6 @@ type App =
, showCorpus :: Boolean
, showLogin :: Boolean
, showTree :: Boolean
, sidePanelGraph :: Maybe (Record GEST.SidePanel)
, sidePanelLists :: Maybe (Record ListsT.SidePanel)
, sidePanelTexts :: Maybe (Record TextsT.SidePanel)
, sidePanelState :: SidePanelState
...
...
@@ -63,7 +61,6 @@ emptyApp =
, showCorpus : false
, showLogin : false
, showTree : true
, sidePanelGraph : GEST.initialSidePanel
, sidePanelLists : ListsT.initialSidePanel
, sidePanelTexts : TextsT.initialSidePanel
, sidePanelState : InitialClosed
...
...
@@ -89,7 +86,6 @@ type Boxes =
, showCorpus :: T.Box Boolean
, showLogin :: T.Box Boolean
, showTree :: T.Box Boolean
, sidePanelGraph :: T.Box (Maybe (Record GEST.SidePanel))
, sidePanelLists :: T.Box (Maybe (Record ListsT.SidePanel))
, sidePanelTexts :: T.Box (Maybe (Record TextsT.SidePanel))
, sidePanelState :: T.Box SidePanelState
...
...
src/Gargantext/Components/GraphExplorer/Layout.purs
View file @
89d1033b
...
...
@@ -7,7 +7,7 @@ import Data.Array as A
import Data.FoldableWithIndex (foldMapWithIndex)
import Data.Int (toNumber)
import Data.Map as Map
import Data.Maybe (Maybe(..), fromJust
, maybe
)
import Data.Maybe (Maybe(..), fromJust)
import Data.Nullable (null, Nullable)
import Data.Sequence as Seq
import Data.Set as Set
...
...
@@ -16,13 +16,13 @@ import Gargantext.Components.App.Data (Boxes)
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.GraphExplorer.Resources as Graph
import Gargantext.Components.GraphExplorer.Sidebar as GES
import Gargantext.Components.GraphExplorer.Sidebar.Types as GEST
import Gargantext.Components.GraphExplorer.Toolbar.Controls (Controls)
import Gargantext.Components.GraphExplorer.Store as GraphStore
import Gargantext.Components.GraphExplorer.Toolbar.Controls as Controls
import Gargantext.Components.GraphExplorer.TopBar as GETB
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Config (defaultFrontends)
import Gargantext.Data.Louvain as Louvain
import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax.Types as SigmaxT
import Gargantext.Sessions (Session)
import Gargantext.Types as GT
...
...
@@ -30,71 +30,63 @@ import Gargantext.Types as Types
import Gargantext.Utils ((?))
import Gargantext.Utils.Range as Range
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Stores as Stores
import Math as Math
import Partial.Unsafe (unsafePartial)
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
here :: R2.Here
here = R2.here "Gargantext.Components.GraphExplorer.Layout"
type Props =
( mMetaData' :: Maybe GET.MetaData
, graph :: SigmaxT.SGraph
, hyperdataGraph :: GET.HyperdataGraph
, session :: Session
( session :: Session
, boxes :: Boxes
, sigmaRef :: R.Ref Sigmax.Sigma
, graphId :: GET.GraphId
, controls :: Record Controls
)
here :: R2.Here
here = R2.here "Gargantext.Components.GraphExplorer.Layout"
layout :: R2.Leaf Props
layout = R2.leaf layoutCpt
layoutCpt :: R.Memo Props
layoutCpt = R.memo' $ here.component "explorerWriteGraph" cpt where
cpt props@{ boxes
, graph
, mMetaData'
, graphId
, session
,
hyperdataGraph
,
controls
,
sigmaRef
,
graphId
} _ = do
--
Computed
-----------------
-- |
Computed
-- |
let
topBarPortalKey = "portal-topbar::" <> show graphId
--
States
-----------------
-- |
States
-- |
{ mMetaData: mMetaDataBox
, showSidebar
{ showSidebar
, showDoc
} <- GEST.focusedSidePanel boxes.sidePanelGraph
, mMetaData
, showControls
} <- Stores.useStore GraphStore.context
_graphVersion' <- T.useLive T.unequal boxes.graphVersion
showSidebar' <- R2.useLive' showSidebar
showDoc' <- R2.useLive' showDoc
mMetaData' <- R2.useLive' mMetaData
showControls' <- R2.useLive' showControls
-- _dataRef <- R.useRef graph
graphRef <- R.useRef null
--
Hooks
-----------------
-- |
Hooks
-- |
mTopBarHost <- R.unsafeHooksEffect $ R2.getElementById "portal-topbar"
showControls' <- R2.useLive' controls.showControls
-- graphVersionRef <- R.useRef graphVersion'
-- R.useEffect' $ do
...
...
@@ -116,8 +108,8 @@ layoutCpt = R.memo' $ here.component "explorerWriteGraph" cpt where
-- T.write_ Graph.Init controls.graphStage
-- T.write_ Types.InitialClosed controls.sidePanelState
--
Render
-----------------
-- |
Render
-- |
pure $
...
...
@@ -130,7 +122,7 @@ layoutCpt = R.memo' $ here.component "explorerWriteGraph" cpt where
R2.fragmentWithKey topBarPortalKey
[
GETB.topBar
{
sidePanelGraph: props.boxes.sidePanelGraph
}
{}
]
]
,
...
...
@@ -173,8 +165,6 @@ layoutCpt = R.memo' $ here.component "explorerWriteGraph" cpt where
GES.sidebar
{ boxes
, frontends: defaultFrontends
, graph
, graphId
, metaData
, session
}
...
...
@@ -190,7 +180,11 @@ layoutCpt = R.memo' $ here.component "explorerWriteGraph" cpt where
, style: { display: showControls' ? "block" $ "none" }
}
[
Controls.controls controls []
Controls.controls
{ reloadForest: boxes.reloadForest
, session
, sigmaRef
}
]
,
-- Content
...
...
@@ -201,11 +195,8 @@ layoutCpt = R.memo' $ here.component "explorerWriteGraph" cpt where
[
graphView
{ boxes: props.boxes
, controls
, elRef: graphRef
, graph
, hyperdataGraph
, mMetaData: mMetaDataBox
, sigmaRef
}
]
]
...
...
@@ -214,70 +205,84 @@ layoutCpt = R.memo' $ here.component "explorerWriteGraph" cpt where
type GraphProps =
( boxes :: Boxes
, controls :: Record Controls.Controls
, elRef :: R.Ref (Nullable Element)
, graph :: SigmaxT.SGraph
, hyperdataGraph :: GET.HyperdataGraph
, mMetaData :: T.Box (Maybe GET.MetaData)
, sigmaRef :: R.Ref Sigmax.Sigma
)
graphView :: R2.Leaf GraphProps
graphView = R2.leaf graphViewCpt
graphViewCpt :: R.Memo GraphProps
graphViewCpt = R.memo' $ here.component "graphView" cpt
where
graphViewCpt = R.memo' $ here.component "graphView" cpt where
cpt { boxes
, controls
, elRef
, sigmaRef
} _ = do
-- | States
-- |
{ edgeConfluence
, edgeWeight
, multiSelectEnabled
, nodeSize
, removedNodeIds
, selectedNodeIds
, showEdges
, showLouvain
, hyperdataGraph
, graph
, hyperdataGraph: GET.HyperdataGraph { mCamera }
, mMetaData } _ = do
edgeConfluence' <- T.useLive T.unequal controls.edgeConfluence
edgeWeight' <- T.useLive T.unequal controls.edgeWeight
mMetaData' <- T.useLive T.unequal mMetaData
multiSelectEnabled' <- T.useLive T.unequal controls.multiSelectEnabled
nodeSize' <- T.useLive T.unequal controls.nodeSize
removedNodeIds' <- T.useLive T.unequal controls.removedNodeIds
selectedNodeIds' <- T.useLive T.unequal controls.selectedNodeIds
showEdges' <- T.useLive T.unequal controls.showEdges
showLouvain' <- T.useLive T.unequal controls.showLouvain
} <- Stores.useStore GraphStore.context
edgeConfluence' <- R2.useLive' edgeConfluence
edgeWeight' <- R2.useLive' edgeWeight
multiSelectEnabled' <- R2.useLive' multiSelectEnabled
nodeSize' <- R2.useLive' nodeSize
removedNodeIds' <- R2.useLive' removedNodeIds
selectedNodeIds' <- R2.useLive' selectedNodeIds
showEdges' <- R2.useLive' showEdges
showLouvain' <- R2.useLive' showLouvain
hyperdataGraph' <- R2.useLive' hyperdataGraph
graph' <- R2.useLive' graph
multiSelectEnabledRef <- R.useRef multiSelectEnabled'
-- | Computed
-- |
-- TODO Cache this?
let louvainGraph =
if showLouvain' then
let louvain = Louvain.louvain unit in
let cluster = Louvain.init louvain (SigmaxT.louvainNodes graph) (SigmaxT.louvainEdges graph
) in
SigmaxT.louvainGraph graph
cluster
let cluster = Louvain.init louvain (SigmaxT.louvainNodes graph') (SigmaxT.louvainEdges graph'
) in
SigmaxT.louvainGraph graph'
cluster
else
graph
graph'
let transformedGraph = transformGraph louvainGraph { edgeConfluence'
, edgeWeight'
, nodeSize'
, removedNodeIds'
, selectedNodeIds'
, showEdges' }
let startForceAtlas = maybe true (\(GET.MetaData { startForceAtlas: sfa }) -> sfa) mMetaData'
let mCamera' (GET.HyperdataGraph { mCamera }) = mCamera
-- | Hooks
-- |
R.useEffect1' multiSelectEnabled' $ do
R.setRef multiSelectEnabledRef multiSelectEnabled'
-- | Render
-- |
pure $
Graph.g
raph
Graph.drawG
raph
{ boxes
, elRef
, forceAtlas2Settings: Graph.forceAtlas2Settings
, graph
, mCamera
, mCamera: mCamera' hyperdataGraph'
, multiSelectEnabledRef
, selectedNodeIds: controls.selectedNodeIds
, showEdges: controls.showEdges
, sigmaRef: controls.sigmaRef
, sigmaRef
, sigmaSettings: Graph.sigmaSettings
, stage: controls.graphStage
, startForceAtlas
, transformedGraph
}
...
...
src/Gargantext/Components/GraphExplorer/Resources.purs
View file @
89d1033b
module Gargantext.Components.GraphExplorer.Resources
-- ( graph, graphCpt
-- , sigmaSettings, SigmaSettings
, SigmaOptionalSettings
-- , forceAtlas2Settings, ForceAtlas2Settings
, ForceAtlas2OptionalSettings
--
)
( drawGraph
, sigmaSettings, SigmaSettings--
, SigmaOptionalSettings
, forceAtlas2Settings, ForceAtlas2Settings--
, ForceAtlas2OptionalSettings
)
where
import Gargantext.Prelude
...
...
@@ -10,10 +10,10 @@ import Gargantext.Prelude
import DOM.Simple (window)
import DOM.Simple.Types (Element)
import Data.Either (Either(..))
import Data.Generic.Rep (class Generic)
import Data.Maybe (Maybe(..))
import Data.Nullable (Nullable)
import Gargantext.Components.App.Data (Boxes)
import Gargantext.Components.GraphExplorer.Store as GraphStore
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Components.Themes (darksterTheme)
import Gargantext.Components.Themes as Themes
...
...
@@ -21,6 +21,7 @@ import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Hooks.Sigmax.Types as SigmaxTypes
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Stores as Stores
import Reactix as R
import Reactix.DOM.HTML as RH
import Record (merge)
...
...
@@ -30,41 +31,53 @@ import Toestand as T
here :: R2.Here
here = R2.here "Gargantext.Components.Graph"
data Stage = Init | Ready | Cleanup
derive instance Generic Stage _
derive instance Eq Stage
type Props sigma forceatlas2 =
( boxes :: Boxes
, elRef :: R.Ref (Nullable Element)
, forceAtlas2Settings :: forceatlas2
, graph :: SigmaxTypes.SGraph
, mCamera :: Maybe GET.Camera
, multiSelectEnabledRef :: R.Ref Boolean
, selectedNodeIds :: T.Box SigmaxTypes.NodeIds
, showEdges :: T.Box SigmaxTypes.ShowEdgesState
, sigmaRef :: R.Ref Sigmax.Sigma
, sigmaSettings :: sigma
, stage :: T.Box Stage
, startForceAtlas :: Boolean
, transformedGraph :: SigmaxTypes.SGraph
)
g
raph :: forall s fa2. R2.Leaf (Props s fa2)
graph = R2.leaf g
raphCpt
drawG
raph :: forall s fa2. R2.Leaf (Props s fa2)
drawGraph = R2.leaf drawG
raphCpt
graphCpt :: forall s fa2. R.Memo (Props s fa2)
graphCpt = R.memo' $ here.component "graph" cpt where
drawGraphCpt :: forall s fa2. R.Memo (Props s fa2)
drawGraphCpt = R.memo' $ here.component "graph" cpt where
-- | Component
-- |
cpt props@{ elRef
, showEdges
, sigmaRef
, stage } _ = do
showEdges' <- T.useLive T.unequal showEdges
stage' <- T.useLive T.unequal stage
} _ = do
stageHooks (Record.merge { showEdges', stage' } props)
{ showEdges
, graphStage
, graph
, startForceAtlas
, selectedNodeIds
} <- Stores.useStore GraphStore.context
showEdges' <- R2.useLive' showEdges
graphStage' <- R2.useLive' graphStage
graph' <- R2.useLive' graph
startForceAtlas' <- R2.useLive' startForceAtlas
stageHooks
-- @WIP: record merge
(
Record.merge
{ showEdges'
, graphStage'
, selectedNodeIds
, graphStage
, startForceAtlas'
, graph'
}
props
)
R.useEffectOnce $ do
pure $ do
...
...
@@ -82,16 +95,18 @@ graphCpt = R.memo' $ here.component "graph" cpt where
Nothing -> RH.div {} []
Just el -> R.createPortal [] el
-- | Stage Hooks
-- |
stageHooks { elRef
, mCamera
, multiSelectEnabledRef
, selectedNodeIds
, forceAtlas2Settings: fa2
, graph:
graph'
,
graph'
, sigmaRef
, s
tage
, stage':
Init
, startForceAtlas
, graphS
tage
, graphStage': GET.
Init
, startForceAtlas'
, boxes
} = do
R.useEffectOnce' $ do
...
...
@@ -125,7 +140,7 @@ graphCpt = R.memo' $ here.component "graph" cpt where
Sigmax.setEdges sig false
-- here.log2 "[graph] startForceAtlas" startForceAtlas
if startForceAtlas
then
if startForceAtlas'
then
Sigma.startForceAtlas2 sig fa2
else
Sigma.stopForceAtlas2 sig
...
...
@@ -147,12 +162,12 @@ graphCpt = R.memo' $ here.component "graph" cpt where
Just _sig -> do
pure unit
T.write Ready s
tage
T.write GET.Ready graphS
tage
stageHooks { showEdges'
, sigmaRef
, stage':
Ready
, graphStage': GET.
Ready
, transformedGraph
} = do
let tEdgesMap = SigmaxTypes.edgesGraphMap transformedGraph
...
...
src/Gargantext/Components/GraphExplorer/Sidebar/Sidebar.purs
View file @
89d1033b
module Gargantext.Components.GraphExplorer.Sidebar
( Props, sidebar
, Common
( sidebar
) where
import Gargantext.Prelude
...
...
@@ -25,7 +24,7 @@ import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap.Types (ButtonVariant(..), Variant(..))
import Gargantext.Components.GraphExplorer.Sidebar.DocList (docList)
import Gargantext.Components.GraphExplorer.Sidebar.Legend as Legend
import Gargantext.Components.GraphExplorer.S
idebar.Types as GEST
import Gargantext.Components.GraphExplorer.S
tore as GraphStore
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Components.Lang (Lang(..))
import Gargantext.Components.NgramsTable.Core as NTC
...
...
@@ -39,42 +38,36 @@ import Gargantext.Sessions (Session)
import Gargantext.Types (CTabNgramType, FrontendError(..), NodeID, TabSubType(..), TabType(..), TermList(..), ListId, modeTabType)
import Gargantext.Utils (nbsp)
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Stores as Stores
import Gargantext.Utils.Toestand as T2
import Math as Math
import Partial.Unsafe (unsafePartial)
import Reactix as R
import Reactix.DOM.HTML as H
import Record as Record
import Record.Extra as RX
import Toestand as T
here :: R2.Here
here = R2.here "Gargantext.Components.GraphExplorer.Sidebar"
type
Common
=
type
Props
=
( boxes :: Boxes
, graphId :: NodeID
, metaData :: GET.MetaData
, session :: Session
)
type Props =
( frontends :: Frontends
, graph :: SigmaxT.SGraph
| Common
, frontends :: Frontends
)
sidebar :: R2.Leaf Props
sidebar = R2.leaf sidebarCpt
sidebarCpt :: R.Component Props
sidebarCpt = here.component "sidebar" cpt
where
cpt props@{ boxes: { sidePanelGraph } } _ = do
sidebarCpt = here.component "sidebar" cpt where
cpt props _ = do
-- States
{ sideTab
} <- GEST.focusedSidePanel sidePanelGraph
} <- Stores.useStore GraphStore.context
sideTab' <- T.useLive T.unequal
sideTab
sideTab' <- R2.useLive'
sideTab
-- Computed
let
...
...
@@ -84,8 +77,6 @@ sidebarCpt = here.component "sidebar" cpt
, GET.SideTabCommunity
]
sideTabProps = (RX.pick props :: Record Props)
-- Render
pure $
...
...
@@ -100,15 +91,16 @@ sidebarCpt = here.component "sidebar" cpt
}
,
case sideTab' of
GET.SideTabLegend -> sideTabLegend sideTabP
rops
GET.SideTabData -> sideTabData sideTabP
rops
GET.SideTabCommunity -> sideTabCommunity sideTabP
rops
GET.SideTabLegend -> sideTabLegend p
rops
GET.SideTabData -> sideTabData p
rops
GET.SideTabCommunity -> sideTabCommunity p
rops
]
------------------------------------------------------------
sideTabLegend :: R2.Leaf Props
sideTabLegend = R2.leaf sideTabLegendCpt
sideTabLegendCpt :: R.Component Props
sideTabLegendCpt = here.component "sideTabLegend" cpt
where
...
...
@@ -129,16 +121,18 @@ sideTabLegendCpt = here.component "sideTabLegend" cpt
sideTabData :: R2.Leaf Props
sideTabData = R2.leaf sideTabDataCpt
sideTabDataCpt :: R.Component Props
sideTabDataCpt = here.component "sideTabData" cpt
where
cpt props@{ boxes: { sidePanelGraph } } _ = do
sideTabDataCpt = here.component "sideTabData" cpt where
cpt props _ = do
-- States
{ selectedNodeIds
, showDoc
} <- GEST.focusedSidePanel sidePanelGraph
, graph
} <- Stores.useStore GraphStore.context
selectedNodeIds' <- T.useLive T.unequal selectedNodeIds
selectedNodeIds' <- R2.useLive' selectedNodeIds
graph' <- R2.useLive' graph
-- Computed
let
...
...
@@ -167,20 +161,20 @@ sideTabDataCpt = here.component "sideTabData" cpt
R.fragment
[
selectedNodes $
{ nodesMap: SigmaxT.nodesGraphMap props.graph
{ nodesMap: SigmaxT.nodesGraphMap graph'
} `Record.merge` props
,
sideBarTabSeparator
,
neighborhood
props
{}
,
sideBarTabSeparator
,
docListWrapper
{ frontends: props.frontends
, metaData: props.metaData
, nodesMap: SigmaxT.nodesGraphMap props.graph
, nodesMap: SigmaxT.nodesGraphMap graph'
, searchType: SearchDoc
, selectedNodeIds: selectedNodeIds'
, session: props.session
...
...
@@ -193,16 +187,18 @@ sideTabDataCpt = here.component "sideTabData" cpt
sideTabCommunity :: R2.Leaf Props
sideTabCommunity = R2.leaf sideTabCommunityCpt
sideTabCommunityCpt :: R.Component Props
sideTabCommunityCpt = here.component "sideTabCommunity" cpt
where
cpt props@{ boxes: { sidePanelGraph }
, frontends } _ = do
sideTabCommunityCpt = here.component "sideTabCommunity" cpt where
cpt props@{ frontends } _ = do
-- States
{ selectedNodeIds
, showDoc
} <- GEST.focusedSidePanel sidePanelGraph
selectedNodeIds' <- T.useLive T.unequal selectedNodeIds
, graph
} <- Stores.useStore GraphStore.context
selectedNodeIds' <- R2.useLive' selectedNodeIds
graph' <- R2.useLive' graph
-- Computed
let
...
...
@@ -231,20 +227,20 @@ sideTabCommunityCpt = here.component "sideTabCommunity" cpt
R.fragment
[
selectedNodes $
{ nodesMap: SigmaxT.nodesGraphMap props.graph
{ nodesMap: SigmaxT.nodesGraphMap graph'
} `Record.merge` props
,
sideBarTabSeparator
,
neighborhood
props
{}
,
sideBarTabSeparator
,
docListWrapper
{ frontends
, metaData: props.metaData
, nodesMap: SigmaxT.nodesGraphMap props.graph
, nodesMap: SigmaxT.nodesGraphMap graph'
, searchType: SearchContact
, selectedNodeIds: selectedNodeIds'
, session: props.session
...
...
@@ -275,18 +271,17 @@ type SelectedNodesProps =
selectedNodes :: R2.Leaf SelectedNodesProps
selectedNodes = R2.leaf selectedNodesCpt
selectedNodesCpt :: R.Component SelectedNodesProps
selectedNodesCpt = here.component "selectedNodes" cpt where
cpt props@{ boxes: { sidePanelGraph }
, graph
, nodesMap } _ = do
cpt props _ = do
-- States
{ selectedNodeIds } <- GEST.focusedSidePanel sidePanelGraph
selectedNodeIds' <- T.useLive T.unequal selectedNodeIds
{ selectedNodeIds
, graph
} <- Stores.useStore GraphStore.context
-- Computed
let
commonProps = RX.pick props :: Record Common
selectedNodeIds' <- R2.useLive' selectedNodeIds
graph' <- R2.useLive' graph
-- Behaviors
let
...
...
@@ -309,7 +304,7 @@ selectedNodesCpt = here.component "selectedNodes" cpt where
{} $
Seq.toUnfoldable $
flip Seq.map (badges graph selectedNodeIds') \node ->
flip Seq.map (badges graph
'
selectedNodeIds') \node ->
H.li
{ className: "graph-selected-nodes__item" }
...
...
@@ -334,18 +329,16 @@ selectedNodesCpt = here.component "selectedNodes" cpt where
}
[
updateTermButton
(
commonP
rops `Record.merge`
(
p
rops `Record.merge`
{ variant: ButtonVariant Secondary
, rType: CandidateTerm
, nodesMap
}
)
[ H.text "Move as candidate" ]
,
updateTermButton
(
commonP
rops `Record.merge`
(
p
rops `Record.merge`
{ variant: ButtonVariant Danger
, nodesMap
, rType: StopTerm
}
)
...
...
@@ -355,19 +348,22 @@ selectedNodesCpt = here.component "selectedNodes" cpt where
---------------------------------------------------------
neighborhood :: R2.Leaf
Props
neighborhood :: R2.Leaf
()
neighborhood = R2.leaf neighborhoodCpt
neighborhoodCpt :: R.Memo Props
neighborhoodCpt :: R.Memo ()
neighborhoodCpt = R.memo' $ here.component "neighborhood" cpt where
cpt { boxes: { sidePanelGraph }
, graph
} _ = do
cpt _ _ = do
-- States
{ selectedNodeIds } <-
GEST.focusedSidePanel sidePanelGraph
{ selectedNodeIds
, graph
} <- Stores.useStore GraphStore.context
selectedNodeIds' <-
T.useLive T.unequal selectedNodeIds
R2.useLive' selectedNodeIds
graph' <-
R2.useLive' graph
showMore /\ showMoreBox <-
R2.useBox' false
...
...
@@ -380,9 +376,9 @@ neighborhoodCpt = R.memo' $ here.component "neighborhood" cpt where
-- Computed
let
minSize = F.foldl Math.min 0.0 (Seq.map _.size (SigmaxT.graphNodes graph))
minSize = F.foldl Math.min 0.0 (Seq.map _.size (SigmaxT.graphNodes graph
'
))
maxSize = F.foldl Math.max 0.0 (Seq.map _.size (SigmaxT.graphNodes graph))
maxSize = F.foldl Math.max 0.0 (Seq.map _.size (SigmaxT.graphNodes graph
'
))
maxTruncateResult = 5
...
...
@@ -395,7 +391,7 @@ neighborhoodCpt = R.memo' $ here.component "neighborhood" cpt where
-- Effects
R.useEffect1' selectedNodeIds' do
let refreshed = neighbourBadges graph selectedNodeIds'
let refreshed = neighbourBadges graph
'
selectedNodeIds'
let count = Seq.length refreshed
let ordered = A.sortWith (\n -> -n.size) $ Seq.toUnfoldable refreshed
T.write_ count termCountBox
...
...
@@ -482,26 +478,32 @@ type UpdateTermButtonProps =
( variant :: ButtonVariant
, nodesMap :: SigmaxT.NodesMap
, rType :: TermList
|
Common
|
Props
)
updateTermButton :: R2.Component UpdateTermButtonProps
updateTermButton = R2.component updateTermButtonCpt
updateTermButtonCpt :: R.Component UpdateTermButtonProps
updateTermButtonCpt = here.component "updateTermButton" cpt where
cpt { boxes: { errors
cpt { boxes:
{ errors
, reloadForest
, sidePanelGraph
}
}
, variant
, graphId
, metaData
, nodesMap
, rType
, session
} children = do
-- States
{ removedNodeIds, selectedNodeIds } <- GEST.focusedSidePanel sidePanelGraph
selectedNodeIds' <- T.useLive T.unequal selectedNodeIds
{ removedNodeIds
, selectedNodeIds
, graphId
} <- Stores.useStore GraphStore.context
selectedNodeIds' <- R2.useLive' selectedNodeIds
graphId' <- R2.useLive' graphId
-- Behaviors
let
...
...
@@ -509,12 +511,13 @@ updateTermButtonCpt = here.component "updateTermButton" cpt where
let nodes = mapMaybe (\id -> Map.lookup id nodesMap)
$ Set.toUnfoldable selectedNodeIds'
sendPatches { errors
, graphId: graphId
, graphId: graphId
'
, metaData: metaData
, nodes
, session: session
, termList: rType
, reloadForest }
, reloadForest
}
T.write_ selectedNodeIds' removedNodeIds
T.write_ SigmaxT.emptyNodeIds selectedNodeIds
...
...
src/Gargantext/Components/GraphExplorer/Sidebar/Types.purs
deleted
100644 → 0
View file @
b8befd87
module Gargantext.Components.GraphExplorer.Sidebar.Types where
import Gargantext.Prelude
import Data.Maybe (Maybe(..), maybe)
import Data.Set as Set
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Hooks.Sigmax.Types as SigmaxT
import Gargantext.Types as GT
import Reactix as R
import Toestand as T
type SidePanel =
(
mGraph :: Maybe SigmaxT.SGraph
, mMetaData :: Maybe GET.MetaData
, multiSelectEnabled :: Boolean
, removedNodeIds :: SigmaxT.NodeIds
, selectedNodeIds :: SigmaxT.NodeIds
, showControls :: Boolean
, sideTab :: GET.SideTab
, showSidebar :: GT.SidePanelState
, showDoc :: Maybe GT.ListId
)
initialSidePanel :: Maybe (Record SidePanel)
initialSidePanel = Nothing
focusedSidePanel :: T.Box (Maybe (Record SidePanel))
-> R.Hooks { mGraph :: T.Box (Maybe SigmaxT.SGraph)
, mMetaData :: T.Box (Maybe GET.MetaData)
, multiSelectEnabled :: T.Box Boolean
, removedNodeIds :: T.Box SigmaxT.NodeIds
, selectedNodeIds :: T.Box SigmaxT.NodeIds
, showControls :: T.Box Boolean
, sideTab :: T.Box GET.SideTab
, showSidebar :: T.Box GT.SidePanelState
, showDoc :: T.Box (Maybe GT.ListId)
}
focusedSidePanel sidePanel = do
mGraph <- T.useFocused
(maybe Nothing _.mGraph)
(\val -> maybe Nothing (\sp -> Just $ sp { mGraph = val })) sidePanel
mMetaData <- T.useFocused
(maybe Nothing _.mMetaData)
(\val -> maybe Nothing (\sp -> Just $ sp { mMetaData = val })) sidePanel
multiSelectEnabled <- T.useFocused
(maybe false _.multiSelectEnabled)
(\val -> maybe Nothing (\sp -> Just $ sp { multiSelectEnabled = val })) sidePanel
removedNodeIds <- T.useFocused
(maybe Set.empty _.removedNodeIds)
(\val -> maybe Nothing (\sp -> Just $ sp { removedNodeIds = val })) sidePanel
selectedNodeIds <- T.useFocused
(maybe Set.empty _.selectedNodeIds)
(\val -> maybe Nothing (\sp -> Just $ sp { selectedNodeIds = val })) sidePanel
showControls <- T.useFocused
(maybe false _.showControls)
(\val -> maybe Nothing (\sp -> Just $ sp { showControls = val })) sidePanel
sideTab <- T.useFocused
(maybe GET.SideTabLegend _.sideTab)
(\val -> maybe Nothing (\sp -> Just $ sp { sideTab = val })) sidePanel
showSidebar <- T.useFocused
(maybe GT.InitialClosed _.showSidebar)
(\val -> maybe Nothing (\sp -> Just $ sp { showSidebar = val })) sidePanel
showDoc <- T.useFocused
(maybe Nothing _.showDoc)
(\val -> maybe Nothing (\sp -> Just $ sp { showDoc = val }
)) sidePanel
pure $ {
mGraph
, mMetaData
, multiSelectEnabled
, removedNodeIds
, selectedNodeIds
, showControls
, sideTab
, showSidebar
, showDoc
}
src/Gargantext/Components/GraphExplorer/Store.purs
0 → 100644
View file @
89d1033b
module Gargantext.Components.GraphExplorer.Store
( Store
, State
, options
, context
, provide
) where
import Gargantext.Prelude
import Data.Maybe (Maybe(..))
import Data.Set as Set
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Hooks.Sigmax.Types as SigmaxT
import Gargantext.Types as GT
import Gargantext.Utils.Range as Range
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Stores as Stores
import Reactix as R
import Toestand as T
import Unsafe.Coerce (unsafeCoerce)
here :: R2.Here
here = R2.here "Gargantext.Components.GraphExplorer.Store"
type Store =
-- Data
( graph :: T.Box SigmaxT.SGraph
, graphId :: T.Box GET.GraphId
, mMetaData :: T.Box (Maybe GET.MetaData)
, hyperdataGraph :: T.Box GET.HyperdataGraph
-- Layout
, showControls :: T.Box Boolean
, sideTab :: T.Box GET.SideTab
, showSidebar :: T.Box GT.SidePanelState
, showDoc :: T.Box (Maybe GT.ListId)
-- Controls
, multiSelectEnabled :: T.Box Boolean
, edgeConfluence :: T.Box Range.NumberRange
, edgeWeight :: T.Box Range.NumberRange
, forceAtlasState :: T.Box SigmaxT.ForceAtlasState
, graphStage :: T.Box GET.Stage
, nodeSize :: T.Box Range.NumberRange
, showEdges :: T.Box SigmaxT.ShowEdgesState
, showLouvain :: T.Box Boolean
, labelSize :: T.Box Number
, mouseSelectorSize :: T.Box Number
, startForceAtlas :: T.Box Boolean
-- Terms update
, removedNodeIds :: T.Box SigmaxT.NodeIds
, selectedNodeIds :: T.Box SigmaxT.NodeIds
)
type State =
-- Data
( graph :: SigmaxT.SGraph
, graphId :: GET.GraphId
, mMetaData :: Maybe GET.MetaData
, hyperdataGraph :: GET.HyperdataGraph
-- Layout
, showControls :: Boolean
, sideTab :: GET.SideTab
, showSidebar :: GT.SidePanelState
, showDoc :: Maybe GT.ListId
-- Controls
, multiSelectEnabled :: Boolean
, edgeConfluence :: Range.NumberRange
, edgeWeight :: Range.NumberRange
, forceAtlasState :: SigmaxT.ForceAtlasState
, graphStage :: GET.Stage
, nodeSize :: Range.NumberRange
, showEdges :: SigmaxT.ShowEdgesState
, showLouvain :: Boolean
, labelSize :: Number
, mouseSelectorSize :: Number
, startForceAtlas :: Boolean
-- Terms update
, removedNodeIds :: SigmaxT.NodeIds
, selectedNodeIds :: SigmaxT.NodeIds
)
options ::
{ labelSize :: Number
, mouseSelectorSize :: Number
, multiSelectEnabled :: Boolean
, removedNodeIds :: SigmaxT.NodeIds
, selectedNodeIds :: SigmaxT.NodeIds
, showControls :: Boolean
, showDoc :: Maybe GT.ListId
, showSidebar :: GT.SidePanelState
, sideTab :: GET.SideTab
, edgeConfluence :: Range.NumberRange
, graphStage :: GET.Stage
, nodeSize :: Range.NumberRange
, showLouvain :: Boolean
, showEdges :: SigmaxT.ShowEdgesState
}
options =
-- Layout
{ showControls : false
, sideTab : GET.SideTabLegend
, showSidebar : GT.InitialClosed
, showDoc : Nothing
-- Controls
, multiSelectEnabled : false
, labelSize : 14.0
, mouseSelectorSize : 15.0
, edgeConfluence : Range.Closed { min: 0.0, max: 1.0 }
, graphStage : GET.Init
, nodeSize : Range.Closed { min: 0.0, max: 100.0 }
, showLouvain : false
, showEdges : SigmaxT.EShow
-- Terms update
, removedNodeIds : Set.empty
, selectedNodeIds : Set.empty
}
context :: R.Context (Record Store)
context = R.createContext $ unsafeCoerce unit
provide :: Record State -> Array R.Element -> R.Element
provide values = Stores.provideStore here.name values context
src/Gargantext/Components/GraphExplorer/Toolbar/Controls.purs
View file @
89d1033b
module Gargantext.Components.GraphExplorer.Toolbar.Controls
( Controls
, useGraphControls
, controls
, controlsCpt
( controls
) where
import Prelude
...
...
@@ -15,10 +12,10 @@ import Data.Sequence as Seq
import Data.Set as Set
import Effect.Timer (setTimeout)
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.GraphExplorer.Resources as Graph
import Gargantext.Components.GraphExplorer.Store as GraphStore
import Gargantext.Components.GraphExplorer.Toolbar.Buttons (centerButton, cameraButton, edgesToggleButton, louvainToggleButton, pauseForceAtlasButton, multiSelectEnabledButton)
import Gargantext.Components.GraphExplorer.Toolbar.RangeControl (edgeConfluenceControl, edgeWeightControl, nodeSizeControl)
import Gargantext.Components.GraphExplorer.Resources as Graph
import Gargantext.Components.GraphExplorer.Sidebar.Types as GEST
import Gargantext.Components.GraphExplorer.Toolbar.SlideButton (labelSizeButton, mouseSelectorSizeButton)
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Hooks.Sigmax as Sigmax
...
...
@@ -27,6 +24,7 @@ import Gargantext.Sessions (Session)
import Gargantext.Types as GT
import Gargantext.Utils.Range as Range
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Stores as Stores
import Gargantext.Utils.Toestand as T2
import Reactix as R
import Reactix.DOM.HTML as H
...
...
@@ -36,41 +34,23 @@ here :: R2.Here
here = R2.here "Gargantext.Components.GraphExplorer.Toolbar.Controls"
type Controls =
( edgeConfluence :: T.Box Range.NumberRange
, edgeWeight :: T.Box Range.NumberRange
, forceAtlasState :: T.Box SigmaxT.ForceAtlasState
, graph :: SigmaxT.SGraph
, graphId :: GET.GraphId
, graphStage :: T.Box Graph.Stage
, hyperdataGraph :: GET.HyperdataGraph
, multiSelectEnabled :: T.Box Boolean
, nodeSize :: T.Box Range.NumberRange
, reloadForest :: T2.ReloadS
, removedNodeIds :: T.Box SigmaxT.NodeIds
, selectedNodeIds :: T.Box SigmaxT.NodeIds
( reloadForest :: T2.ReloadS
, session :: Session
, showControls :: T.Box Boolean
, showEdges :: T.Box SigmaxT.ShowEdgesState
, showLouvain :: T.Box Boolean
, showSidebar :: T.Box GT.SidePanelState
, sideTab :: T.Box GET.SideTab
, sigmaRef :: R.Ref Sigmax.Sigma
)
type LocalControls = ( labelSize :: T.Box Number, mouseSelectorSize :: T.Box Number )
initialLocalControls :: R.Hooks (Record LocalControls)
initialLocalControls = do
labelSize <- T.useBox 14.0
mouseSelectorSize <- T.useBox 15.0
pure $ { labelSize, mouseSelectorSize }
controls :: R2.Leaf Controls
controls = R2.leaf controlsCpt
controls :: R2.Component Controls
controls = R.createElement controlsCpt
controlsCpt :: R.Component Controls
controlsCpt = here.component "controls" cpt
where
cpt { edgeConfluence
controlsCpt :: R.Memo Controls
controlsCpt = R.memo' $ here.component "controls" cpt where
cpt { reloadForest
, session
, sigmaRef
} _ = do
-- | States
-- |
{ edgeConfluence
, edgeWeight
, forceAtlasState
, graph
...
...
@@ -79,37 +59,36 @@ controlsCpt = here.component "controls" cpt
, hyperdataGraph
, multiSelectEnabled
, nodeSize
, reloadForest
, selectedNodeIds
, session
, showEdges
, showLouvain
, showSidebar
, sideTab
, sigmaRef } _ = do
-- | States
-- |
, mouseSelectorSize
, labelSize
} <- Stores.useStore GraphStore.context
forceAtlasState' <- T.useLive T.unequal forceAtlasState
graphStage' <- T.useLive T.unequal graphStage
selectedNodeIds' <- T.useLive T.unequal selectedNodeIds
showSidebar' <- T.useLive T.unequal showSidebar
forceAtlasState' <- R2.useLive' forceAtlasState
graph' <- R2.useLive' graph
graphId' <- R2.useLive' graphId
graphStage' <- R2.useLive' graphStage
hyperdataGraph' <- R2.useLive' hyperdataGraph
selectedNodeIds' <- R2.useLive' selectedNodeIds
showSidebar' <- R2.useLive' showSidebar
localControls <- initialLocalControls
-- ref to track automatic FA pausing
-- If user pauses FA before auto is triggered, clear the timeoutId
mFAPauseRef <- R.useRef Nothing
--
| Effects
--
|
--
| Effects
--
|
-- When graph is changed, cleanup the mFAPauseRef so that forceAtlas
-- timeout is retriggered.
R.useEffect' $ do
case graphStage' of
Graph
.Init -> R.setRef mFAPauseRef Nothing
GET
.Init -> R.setRef mFAPauseRef Nothing
_ -> pure unit
-- Handle case when FA is paused from outside events, eg. the automatic timer.
...
...
@@ -145,10 +124,10 @@ controlsCpt = here.component "controls" cpt
pure unit
--
| Computed
--
|
--
| Computed
--
|
let edgesConfluenceSorted = A.sortWith (_.confluence) $ Seq.toUnfoldable $ SigmaxT.graphEdges graph
let edgesConfluenceSorted = A.sortWith (_.confluence) $ Seq.toUnfoldable $ SigmaxT.graphEdges graph'
let edgeConfluenceMin = maybe 0.0 _.confluence $ A.head edgesConfluenceSorted
let edgeConfluenceMax = maybe 100.0 _.confluence $ A.last edgesConfluenceSorted
let edgeConfluenceRange = Range.Closed { min: edgeConfluenceMin, max: edgeConfluenceMax }
...
...
@@ -159,18 +138,18 @@ controlsCpt = here.component "controls" cpt
--let edgeWeightRange = Range.Closed { min: edgeWeightMin, max: edgeWeightMax }
let edgeWeightRange = Range.Closed {
min: 0.0
, max: I.toNumber $ Seq.length $ SigmaxT.graphEdges graph
, max: I.toNumber $ Seq.length $ SigmaxT.graphEdges graph'
}
let nodesSorted = A.sortWith (_.size) $ Seq.toUnfoldable $ SigmaxT.graphNodes graph
let nodesSorted = A.sortWith (_.size) $ Seq.toUnfoldable $ SigmaxT.graphNodes graph'
let nodeSizeMin = maybe 0.0 _.size $ A.head nodesSorted
let nodeSizeMax = maybe 100.0 _.size $ A.last nodesSorted
let nodeSizeRange = Range.Closed { min: nodeSizeMin, max: nodeSizeMax }
let gap = H.span { className: "graph-toolbar__gap" } []
--
| Render
--
|
--
| Render
--
|
pure $
...
...
@@ -216,8 +195,8 @@ controlsCpt = here.component "controls" cpt
gap
,
cameraButton
{ id: graphId
, hyperdataGraph: hyperdataGraph
{ id: graphId'
, hyperdataGraph: hyperdataGraph'
, session: session
, sigmaRef: sigmaRef
, reloadForest
...
...
@@ -241,7 +220,7 @@ controlsCpt = here.component "controls" cpt
,
-- toggle multi node selection
-- save button
mouseSelectorSizeButton sigmaRef localControls.
mouseSelectorSize
mouseSelectorSizeButton sigmaRef
mouseSelectorSize
]
]
,
...
...
@@ -275,7 +254,7 @@ controlsCpt = here.component "controls" cpt
-- run demo
-- search button
-- search topics
labelSizeButton sigmaRef localControls.
labelSize
labelSizeButton sigmaRef
labelSize
,
-- labels size: 1-4
nodeSizeControl
...
...
@@ -314,62 +293,3 @@ controlsCpt = here.component "controls" cpt
-- , reloadForest: reloadForest } ]
-- ]
-- ]
useGraphControls :: { forceAtlasS :: SigmaxT.ForceAtlasState
, graph :: SigmaxT.SGraph
, graphId :: GET.GraphId
, hyperdataGraph :: GET.HyperdataGraph
, reloadForest :: T2.ReloadS
, session :: Session
, sidePanel :: T.Box (Maybe (Record GEST.SidePanel))
}
-> R.Hooks (Record Controls)
useGraphControls { forceAtlasS
, graph
, graphId
, hyperdataGraph
, reloadForest
, session
, sidePanel
} = do
edgeConfluence <- T.useBox $ Range.Closed { min: 0.0, max: 1.0 }
edgeWeight <- T.useBox $ Range.Closed {
min: 0.0
, max: I.toNumber $ Seq.length $ SigmaxT.graphEdges graph
}
forceAtlasState <- T.useBox forceAtlasS
graphStage <- T.useBox Graph.Init
nodeSize <- T.useBox $ Range.Closed { min: 0.0, max: 100.0 }
showEdges <- T.useBox SigmaxT.EShow
showLouvain <- T.useBox false
sigma <- Sigmax.initSigma
sigmaRef <- R.useRef sigma
{ multiSelectEnabled
, removedNodeIds
, selectedNodeIds
, showControls
, sideTab
, showSidebar
} <- GEST.focusedSidePanel sidePanel
pure { edgeConfluence
, edgeWeight
, forceAtlasState
, graph
, graphId
, graphStage
, hyperdataGraph
, multiSelectEnabled
, nodeSize
, removedNodeIds
, selectedNodeIds
, session
, showControls
, showEdges
, showLouvain
, showSidebar
, sideTab
, sigmaRef
, reloadForest
}
src/Gargantext/Components/GraphExplorer/Topbar/TopBar.purs
View file @
89d1033b
...
...
@@ -2,40 +2,36 @@ module Gargantext.Components.GraphExplorer.TopBar (topBar) where
import Gargantext.Prelude hiding (max, min)
import Data.Maybe (Maybe)
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap.Types (ButtonVariant(..), Variant(..))
import Gargantext.Components.GraphExplorer.Store as GraphStore
import Gargantext.Components.GraphExplorer.Topbar.Search (nodeSearchControl)
import Gargantext.Components.GraphExplorer.Sidebar.Types as GEST
import Gargantext.Types as GT
import Gargantext.Utils ((?))
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Stores as Stores
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
type Props =
( sidePanelGraph :: T.Box (Maybe (Record GEST.SidePanel))
)
here :: R2.Here
here = R2.here "Gargantext.Components.GraphExplorer.TopBar"
topBar :: R2.Leaf
Props
topBar :: R2.Leaf
()
topBar = R2.leaf component
component :: R.Component
Props
component :: R.Component
()
component = here.component "topBar" cpt where
cpt
{ sidePanelGraph }
_ = do
cpt
_
_ = do
-- States
{
mG
raph
{
g
raph
, multiSelectEnabled
, selectedNodeIds
, showControls
, showSidebar
} <-
GEST.focusedSidePanel sidePanelGraph
} <-
Stores.useStore GraphStore.context
mGraph' <- R2.useLive' mG
raph
graph' <- R2.useLive' g
raph
showControls' <- R2.useLive' showControls
showSidebar' <- R2.useLive' showSidebar
...
...
@@ -73,10 +69,8 @@ component = here.component "topBar" cpt where
]
,
-- Search
R2.fromMaybe_ mGraph' \graph ->
nodeSearchControl
{ graph
{ graph: graph'
, multiSelectEnabled
, selectedNodeIds
, className: "graph-topbar__search"
...
...
src/Gargantext/Components/GraphExplorer/Types.purs
View file @
89d1033b
module Gargantext.Components.GraphExplorer.Types where
import Gargantext.Prelude
import Data.Array ((!!), length)
import Data.Generic.Rep (class Generic)
import Data.Eq.Generic (genericEq)
import Data.Maybe (Maybe(..), fromJust)
import Data.Newtype (class Newtype)
import Data.Ord
import Data.Ord.Generic (genericCompare)
import Data.Symbol (SProxy(..))
import Partial.Unsafe (unsafePartial)
import Record as Record
import Simple.JSON as JSON
import Gargantext.Prelude
type GraphId = Int
newtype Node = Node {
...
...
@@ -164,7 +163,7 @@ instance Ord SelectedNode where compare = genericCompare
instance Show SelectedNode where show (SelectedNode node) = node.label
type State = (
--
type State = (
-- corpusId :: R.State Int
--, filePath :: R.State String
--, graphData :: R.State GraphData
...
...
@@ -177,7 +176,7 @@ type State = (
--, sigmaGraphData :: R.State (Maybe SigmaxTypes.SGraph)
--, sigmaSettings :: R.State ({|Graph.SigmaSettings})
--treeId :: R.State (Maybe TreeId)
)
--
)
initialGraphData :: GraphData
initialGraphData = GraphData {
...
...
@@ -255,3 +254,7 @@ instance JSON.ReadForeign HyperdataGraph where
pure $ HyperdataGraph $ Record.rename cameraP mCameraP inst
instance JSON.WriteForeign HyperdataGraph where
writeImpl (HyperdataGraph c) = JSON.writeImpl $ Record.rename mCameraP cameraP c
data Stage = Init | Ready | Cleanup
derive instance Generic Stage _
derive instance Eq Stage
src/Gargantext/Components/Nodes/Graph.purs
View file @
89d1033b
...
...
@@ -5,21 +5,24 @@ module Gargantext.Components.Nodes.Corpus.Graph
import Gargantext.Prelude
import DOM.Simple (document, querySelector)
import Data.Int as I
import Data.Maybe (Maybe(..), isJust, maybe)
import Data.Se
t as Set
import Data.Se
quence as Seq
import Data.Tuple (Tuple(..))
import Data.Tuple.Nested ((/\))
import Gargantext.Components.App.Data (Boxes)
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.GraphExplorer.Layout (convert, layout)
import Gargantext.Components.GraphExplorer.
Toolbar.Controls as Controls
import Gargantext.Components.GraphExplorer.
Store as GraphStore
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Config.REST (AffRESTError, logRESTError)
import Gargantext.Hooks.Loader (useLoaderEffect)
import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax.Types as SigmaxT
import Gargantext.Routes (SessionRoute(NodeAPI))
import Gargantext.Sessions (Session, get)
import Gargantext.Types as Types
import Gargantext.Utils.Range as Range
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Toestand as T2
import Reactix as R
...
...
@@ -123,18 +126,18 @@ graphLayoutCpt = here.component "explorerLayout" cpt where
handler loaded@(GET.HyperdataGraph { graph: hyperdataGraph }) =
content { graph
, hyperdataGraph: loaded
, mMetaData
'
, mMetaData
, session
, boxes: props.boxes
, graphId
}
where
Tuple mMetaData
'
graph = convert hyperdataGraph
Tuple mMetaData graph = convert hyperdataGraph
--------------------------------------------------------
type ContentProps =
( mMetaData
'
:: Maybe GET.MetaData
( mMetaData
:: Maybe GET.MetaData
, graph :: SigmaxT.SGraph
, hyperdataGraph :: GET.HyperdataGraph
, session :: Session
...
...
@@ -147,8 +150,8 @@ content = R2.leaf contentCpt
contentCpt :: R.Component ContentProps
contentCpt = here.component "content" cpt where
cpt
props@
{ boxes
, mMetaData'
cpt { boxes
, mMetaData
, graph
, graphId
, session
...
...
@@ -158,48 +161,52 @@ contentCpt = here.component "content" cpt where
-- |
let
startForceAtlas = maybe true
(\(GET.MetaData { startForceAtlas: sfa }) -> sfa) mMetaData
'
(\(GET.MetaData { startForceAtlas: sfa }) -> sfa) mMetaData
forceAtlasS = if startForceAtlas
forceAtlasState
= if startForceAtlas
then SigmaxT.InitialRunning
else SigmaxT.InitialStopped
-- | Hooks
-- |
-- Hydrate controls
controls <- Controls.useGraphControls
{ forceAtlasS
, graph
-- Hydrate GraphStore
state :: Record GraphStore.State
state =
-- Data
{ graph
, graphId
, mMetaData
, hyperdataGraph
, reloadForest: boxes.reloadForest
, session
, sidePanel: boxes.sidePanelGraph
-- Controls
, startForceAtlas
, forceAtlasState
, edgeWeight: Range.Closed
{ min: 0.0
, max: I.toNumber $ Seq.length $ SigmaxT.graphEdges graph
}
-- (default options)
-- @WIP: testing order of Record.merge
} `Record.merge` GraphStore.options
-- Hydrate Boxes
R.useEffectOnce' $
flip T.write_ boxes.sidePanelGraph $ Just
{ mGraph: Just graph
, mMetaData: mMetaData'
, multiSelectEnabled: false
, removedNodeIds: Set.empty
, selectedNodeIds: Set.empty
, showControls: false
, sideTab: GET.SideTabLegend
, showSidebar: Types.InitialClosed
, showDoc: Nothing
}
-- | Hooks
-- |
sigmaRef <- Sigmax.initSigma >>= R.useRef
-- | Render
-- |
pure $
layout $
{ controls
} `Record.merge` props
GraphStore.provide
state
[
layout
{ session
, boxes
, sigmaRef
, graphId
}
]
--------------------------------------------------------------
...
...
src/Gargantext/Utils/Reactix.purs
View file @
89d1033b
...
...
@@ -91,6 +91,7 @@ type Module = String
type Here =
{ component :: forall p. String -> R.HooksComponent p -> R.Component p
, ntComponent :: forall p. String -> NTHooksComponent p -> NTComponent p
, name :: Module
| RowConsole
}
...
...
@@ -98,6 +99,7 @@ here :: Module -> Here
here mod =
{ component : R.hooksComponentWithModule mod
, ntComponent : ntHooksComponentWithModule mod
, name : mod
, log : Console.print Console.Main mod Console.Log
, log2 : Console.print2 Console.Main mod Console.Log
, log3 : Console.print3 Console.Main mod Console.Log
...
...
src/Gargantext/Utils/Stores.purs
0 → 100644
View file @
89d1033b
module Gargantext.Utils.Stores
( createStore
, provideStore
, useStore
) where
import Gargantext.Prelude
import Prim.RowList (class RowToList)
import Reactix as R
import Toestand as T
import Toestand.Records as TR
-- StoreFactory: R.Hook (Record Store) → create focus boxes, hydrate box values
-- StoreProvider: R.Hooks (Record Store) → provide context with previous boxes
-- ↓
-- StoreHook: R.Hooks (Record Store) → use context
-- | From state values to focused boxes
createStore :: forall boxes l state.
RowToList state l
=> TR.UseFocusedFields l boxes () (T.Box (Record state))
=> Record state
-> R.Hooks (Record boxes)
createStore = T.useBox >=> flip T.useFocusedFields {}
-- | Set <Store.Provider> bearing Stores as a Context
-- |
-- | (!) do not use store binds in this specific component (eg. `useStores`)
provideStore :: forall boxes l state.
RowToList state l
=> TR.UseFocusedFields l boxes () (T.Box (Record state))
=> String
-> Record state
-> R.Context (Record boxes)
-> Array R.Element
-> R.Element
provideStore name state context
= R.createElement (R.hooksComponent name cpt) {}
where
cpt _ children = do
store <- createStore state
pure $ R.provideContext context store $ children
-- | (?) As we use "React Provide API", we just want to rely on its Global
-- | Reference (and not as Mutable State thanks to "Consumer API")
-- | Hence the "unsafeCoerce" used on every provided context, avoiding
-- | unwanted computing at each import
-- |
-- | It also implies that every call to the proxy reference (made thanks to
-- | below <Store.Provider> are made AFTER first mount of this very,
-- | component, otherwise, every call will return the empty `unit`)
useStore :: forall boxes.
R.Context (Record boxes)
-> R.Hooks (Record boxes)
useStore = R.useContext
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