Commit 8d645385 authored by Alexandre Delanoë's avatar Alexandre Delanoë

Merge remote-tracking branch 'origin/683-dev-graph-explorer-legend' into dev

parents 7366fd67 2c0ecaa9
...@@ -88,6 +88,15 @@ type CloneGraphParams = ...@@ -88,6 +88,15 @@ type CloneGraphParams =
cloneGraph :: Record CloneGraphParams -> AffRESTError Int cloneGraph :: Record CloneGraphParams -> AffRESTError Int
cloneGraph { hyperdataGraph, id, session } = post session (GR.GraphAPI id $ "clone") hyperdataGraph cloneGraph { hyperdataGraph, id, session } = post session (GR.GraphAPI id $ "clone") hyperdataGraph
type UpdateLegendParams =
( graphId :: Int
, session :: Session
, legend :: Array GET.Legend
)
updateLegend :: Record UpdateLegendParams -> AffRESTError Int
updateLegend { graphId, session, legend } = post session (GR.GraphAPI graphId $ "legend") legend
----------------------------------------------- -----------------------------------------------
getNodes :: Session -> T2.Reload -> GET.GraphId -> AffRESTError GET.HyperdataGraph getNodes :: Session -> T2.Reload -> GET.GraphId -> AffRESTError GET.HyperdataGraph
......
...@@ -179,6 +179,7 @@ layoutCpt = here.component "layout" cpt where ...@@ -179,6 +179,7 @@ layoutCpt = here.component "layout" cpt where
{ frontends: defaultFrontends { frontends: defaultFrontends
, metaData , metaData
, session , session
, graphId: graphId'
} }
] ]
] ]
......
...@@ -30,7 +30,6 @@ import Gargantext.Components.GraphExplorer.Sidebar.Legend as Legend ...@@ -30,7 +30,6 @@ import Gargantext.Components.GraphExplorer.Sidebar.Legend as Legend
import Gargantext.Components.GraphExplorer.Store as GraphStore import Gargantext.Components.GraphExplorer.Store as GraphStore
import Gargantext.Components.GraphExplorer.Types as GET import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Components.GraphExplorer.Utils as GEU import Gargantext.Components.GraphExplorer.Utils as GEU
import Gargantext.Components.Lang (Lang(..))
import Gargantext.Config.REST (AffRESTError) import Gargantext.Config.REST (AffRESTError)
import Gargantext.Core.NgramsTable.Functions as NTC import Gargantext.Core.NgramsTable.Functions as NTC
import Gargantext.Core.NgramsTable.Types as CNT import Gargantext.Core.NgramsTable.Types as CNT
...@@ -56,6 +55,7 @@ type Props = ...@@ -56,6 +55,7 @@ type Props =
( metaData :: GET.MetaData ( metaData :: GET.MetaData
, session :: Session , session :: Session
, frontends :: Frontends , frontends :: Frontends
, graphId :: GET.GraphId
) )
sidebar :: R2.Leaf Props sidebar :: R2.Leaf Props
...@@ -120,7 +120,7 @@ sideTabLegend :: R2.Leaf Props ...@@ -120,7 +120,7 @@ sideTabLegend :: R2.Leaf Props
sideTabLegend = R2.leaf sideTabLegendCpt sideTabLegend = R2.leaf sideTabLegendCpt
sideTabLegendCpt :: R.Component Props sideTabLegendCpt :: R.Component Props
sideTabLegendCpt = here.component "sideTabLegend" cpt where sideTabLegendCpt = here.component "sideTabLegend" cpt where
cpt { metaData: GET.MetaData { legend } } _ = do cpt { metaData: GET.MetaData { legend }, session, graphId } _ = do
-- | States -- | States
-- | -- |
store <- GraphStore.use store <- GraphStore.use
...@@ -128,6 +128,8 @@ sideTabLegendCpt = here.component "sideTabLegend" cpt where ...@@ -128,6 +128,8 @@ sideTabLegendCpt = here.component "sideTabLegend" cpt where
hyperdataGraph hyperdataGraph
<- R2.useLive' store.hyperdataGraph <- R2.useLive' store.hyperdataGraph
legend' /\ legendBox <- R2.useBox' legend
-- | Computed -- | Computed
-- | -- |
let let
...@@ -161,15 +163,14 @@ sideTabLegendCpt = here.component "sideTabLegend" cpt where ...@@ -161,15 +163,14 @@ sideTabLegendCpt = here.component "sideTabLegend" cpt where
{ className: "graph-sidebar__legend-tab" } { className: "graph-sidebar__legend-tab" }
[ [
Legend.legend Legend.legend
{ legendSeq: Seq.fromFoldable legend { legendSeq: Seq.fromFoldable legend'
, extractedNodeList , extractedNodeList
, nodeCountList , nodeCountList
, selectedNodeIds: store.selectedNodeIds , selectedNodeIds: store.selectedNodeIds
, session
, graphId
, legendBox
} }
,
H.hr {}
,
documentation EN
] ]
------------------------------------------------------------ ------------------------------------------------------------
...@@ -770,98 +771,3 @@ sendPatch termList session (GET.MetaData metaData) node = do ...@@ -770,98 +771,3 @@ sendPatch termList session (GET.MetaData metaData) node = do
patch_list :: CNT.Replace TermList patch_list :: CNT.Replace TermList
patch_list = CNT.Replace { new: termList, old: MapTerm } patch_list = CNT.Replace { new: termList, old: MapTerm }
-----------------------------------------------------
documentation :: Lang -> R.Element
documentation _ =
H.div
{ className: "graph-documentation" }
[
H.div
{ className: "graph-documentation__text-section" }
[
H.p
{}
[
B.b_ "What is a graph? "
,
H.text "Graph is a conveniant tool to explore your documents."
]
,
H.p
{}
[
H.text $
"Nodes are terms selected in your Map List. "
<>
"Node size is proportional to the number of documents with the associated term. "
]
,
H.p
{}
[
H.text $
"Edges between nodes represent proximities of terms according to a specific distance between your documents. "
<>
"Link strength is proportional to the strenght of terms association."
]
]
,
H.div
{ className: "graph-documentation__text-section" }
[
H.ul
{}
[
H.li
{}
[
H.text $
"Click on a node to select/unselect and get its information."
]
,
H.li
{}
[
H.text $
"In case of multiple selection, the button unselect clears all selections. "
<>
"Use your mouse scroll to zoom in and out in the graph. "
]
,
H.li
{}
[
H.text $
"Use the node filter to create a subgraph with nodes of a given size "
<>
"range (e.g. display only generic terms). "
]
,
H.li
{}
[
H.text $
"Use the edge filter so create a subgraph with links in a given range (e.g. keep the strongest association)."
]
]
]
]
{-
TODO DOC
Conditional distance between the terms X and Y is the probability to have both terms X and Y in the same textual context.
Distributional distance between the terms X and Y is the probability to have same others terms in the same textual context as X or Y.
Global/local view:
The 'change level' button allows to change between global view and node centered view,
To explore the neighborhood of a selection click on the 'change level' button.
-}
...@@ -4,15 +4,24 @@ module Gargantext.Components.GraphExplorer.Sidebar.Legend ...@@ -4,15 +4,24 @@ module Gargantext.Components.GraphExplorer.Sidebar.Legend
import Prelude hiding (map) import Prelude hiding (map)
import Control.Applicative (map)
import Data.Array (fromFoldable, snoc)
import Data.Array as A import Data.Array as A
import Data.Foldable (length)
import Data.Maybe (isJust, maybe) import Data.Maybe (isJust, maybe)
import Data.Sequence (Seq) import Data.Sequence (Seq, replace)
import Data.Set as Set import Data.Set as Set
import Data.Traversable (foldMap, intercalate) import Data.Traversable (foldMap, intercalate)
import Effect (Effect)
import Effect.Aff (launchAff_)
import Effect.Class (liftEffect)
import Gargantext.Components.Bootstrap as B import Gargantext.Components.Bootstrap as B
import Gargantext.Components.GraphExplorer.API (updateLegend)
import Gargantext.Components.GraphExplorer.GraphTypes as GEGT import Gargantext.Components.GraphExplorer.GraphTypes as GEGT
import Gargantext.Components.GraphExplorer.Types as GET import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Components.Renameable (renameable)
import Gargantext.Hooks.Sigmax.Types as ST import Gargantext.Hooks.Sigmax.Types as ST
import Gargantext.Sessions (Session)
import Gargantext.Utils (getter, nbsp, (?)) import Gargantext.Utils (getter, nbsp, (?))
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Reactix as R import Reactix as R
...@@ -27,6 +36,9 @@ type Props = ...@@ -27,6 +36,9 @@ type Props =
, extractedNodeList :: Array GEGT.Node , extractedNodeList :: Array GEGT.Node
, nodeCountList :: Array GEGT.ClusterCount , nodeCountList :: Array GEGT.ClusterCount
, selectedNodeIds :: T.Box ST.NodeIds , selectedNodeIds :: T.Box ST.NodeIds
, session :: Session
, graphId :: GET.GraphId
, legendBox :: T.Box (Array GET.Legend)
) )
legend :: R2.Leaf Props legend :: R2.Leaf Props
...@@ -37,6 +49,9 @@ legendCpt = here.component "legend" cpt where ...@@ -37,6 +49,9 @@ legendCpt = here.component "legend" cpt where
, extractedNodeList , extractedNodeList
, nodeCountList , nodeCountList
, selectedNodeIds , selectedNodeIds
, session
, graphId
, legendBox
} _ = do } _ = do
-- | Hooks -- | Hooks
-- | -- |
...@@ -45,26 +60,27 @@ legendCpt = here.component "legend" cpt where ...@@ -45,26 +60,27 @@ legendCpt = here.component "legend" cpt where
-- | -- |
pure $ pure $
R.fragment
[
H.ul H.ul
{ className: "graph-legend" } { className: "graph-legend" }
[ [
flip foldMap legendSeq \(GET.Legend { id_, label }) -> flip foldMap legendSeq \(GET.Legend { id_, label, color}) ->
H.li H.li
{ className: "graph-legend__item" } { className: "graph-legend__item" }
[ [
H.div H.button
{ className: "graph-legend__code" { className: "graph-legend__code"
, style: { backgroundColor: GET.intColor id_ } , style: { backgroundColor: GET.intColor id_ }
, on: { click: \_ -> selectNodes id_}
} }
[] []
, ,
B.wad B.wad
[ "flex-grow-1" ] [ "flex-grow-1" ]
[ [
B.div' renameable { text: label, className: "graph-legend__label", onRename: \s -> rename s id_ color }
{ className: "graph-legend__title" }
label
, ,
selectedNodes selectedNodes
{ selectedNodeIds { selectedNodeIds
...@@ -75,6 +91,37 @@ legendCpt = here.component "legend" cpt where ...@@ -75,6 +91,37 @@ legendCpt = here.component "legend" cpt where
] ]
] ]
] ]
,
H.li
{ className: "graph-legend__item" }
[
H.button
{ className: "fa fa-plus"
, on: { click: \_ -> addCluster }
}
[]
]
]
where
rename :: String -> Int -> String -> Effect Unit
rename s id c = do
let newLegendSeq = replace (GET.Legend $ { id_: id, label: s, color: c}) (id - 1) legendSeq
launchAff_ do
_ <- updateLegend { legend: (fromFoldable newLegendSeq), graphId, session }
pure unit
selectNodes :: Int -> Effect Unit
selectNodes id = do
let nodes = filterByCluster id extractedNodeList
T.write_ (Set.fromFoldable $ map (\(GEGT.Node { id_ }) -> id_) nodes) selectedNodeIds
addCluster :: Effect Unit
addCluster = do
let newLegend = snoc (fromFoldable legendSeq) $ GET.Legend { id_: (length legendSeq) + 1, label: "Cluster" <> show ((length legendSeq) + 1), color: "#ffffff" }
launchAff_ do
_ <- updateLegend { legend: newLegend, graphId, session }
_ <- liftEffect $ T.write newLegend legendBox
pure unit
filterByCluster :: Int -> Array GEGT.Node -> Array GEGT.Node filterByCluster :: Int -> Array GEGT.Node -> Array GEGT.Node
filterByCluster id filterByCluster id
......
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