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 =
cloneGraph :: Record CloneGraphParams -> AffRESTError Int
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
......
......@@ -179,6 +179,7 @@ layoutCpt = here.component "layout" cpt where
{ frontends: defaultFrontends
, metaData
, session
, graphId: graphId'
}
]
]
......
......@@ -30,7 +30,6 @@ import Gargantext.Components.GraphExplorer.Sidebar.Legend as Legend
import Gargantext.Components.GraphExplorer.Store as GraphStore
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Components.GraphExplorer.Utils as GEU
import Gargantext.Components.Lang (Lang(..))
import Gargantext.Config.REST (AffRESTError)
import Gargantext.Core.NgramsTable.Functions as NTC
import Gargantext.Core.NgramsTable.Types as CNT
......@@ -56,6 +55,7 @@ type Props =
( metaData :: GET.MetaData
, session :: Session
, frontends :: Frontends
, graphId :: GET.GraphId
)
sidebar :: R2.Leaf Props
......@@ -120,7 +120,7 @@ sideTabLegend :: R2.Leaf Props
sideTabLegend = R2.leaf sideTabLegendCpt
sideTabLegendCpt :: R.Component Props
sideTabLegendCpt = here.component "sideTabLegend" cpt where
cpt { metaData: GET.MetaData { legend } } _ = do
cpt { metaData: GET.MetaData { legend }, session, graphId } _ = do
-- | States
-- |
store <- GraphStore.use
......@@ -128,6 +128,8 @@ sideTabLegendCpt = here.component "sideTabLegend" cpt where
hyperdataGraph
<- R2.useLive' store.hyperdataGraph
legend' /\ legendBox <- R2.useBox' legend
-- | Computed
-- |
let
......@@ -161,15 +163,14 @@ sideTabLegendCpt = here.component "sideTabLegend" cpt where
{ className: "graph-sidebar__legend-tab" }
[
Legend.legend
{ legendSeq: Seq.fromFoldable legend
{ legendSeq: Seq.fromFoldable legend'
, extractedNodeList
, nodeCountList
, selectedNodeIds: store.selectedNodeIds
, session
, graphId
, legendBox
}
,
H.hr {}
,
documentation EN
]
------------------------------------------------------------
......@@ -770,98 +771,3 @@ sendPatch termList session (GET.MetaData metaData) node = do
patch_list :: CNT.Replace TermList
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
import Prelude hiding (map)
import Control.Applicative (map)
import Data.Array (fromFoldable, snoc)
import Data.Array as A
import Data.Foldable (length)
import Data.Maybe (isJust, maybe)
import Data.Sequence (Seq)
import Data.Sequence (Seq, replace)
import Data.Set as Set
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.GraphExplorer.API (updateLegend)
import Gargantext.Components.GraphExplorer.GraphTypes as GEGT
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Components.Renameable (renameable)
import Gargantext.Hooks.Sigmax.Types as ST
import Gargantext.Sessions (Session)
import Gargantext.Utils (getter, nbsp, (?))
import Gargantext.Utils.Reactix as R2
import Reactix as R
......@@ -27,6 +36,9 @@ type Props =
, extractedNodeList :: Array GEGT.Node
, nodeCountList :: Array GEGT.ClusterCount
, selectedNodeIds :: T.Box ST.NodeIds
, session :: Session
, graphId :: GET.GraphId
, legendBox :: T.Box (Array GET.Legend)
)
legend :: R2.Leaf Props
......@@ -37,6 +49,9 @@ legendCpt = here.component "legend" cpt where
, extractedNodeList
, nodeCountList
, selectedNodeIds
, session
, graphId
, legendBox
} _ = do
-- | Hooks
-- |
......@@ -45,36 +60,68 @@ legendCpt = here.component "legend" cpt where
-- |
pure $
H.ul
{ className: "graph-legend" }
R.fragment
[
flip foldMap legendSeq \(GET.Legend { id_, label }) ->
H.ul
{ className: "graph-legend" }
[
flip foldMap legendSeq \(GET.Legend { id_, label, color}) ->
H.li
{ className: "graph-legend__item" }
[
H.div
{ className: "graph-legend__code"
, style: { backgroundColor: GET.intColor id_ }
}
[]
,
B.wad
[ "flex-grow-1" ]
H.li
{ className: "graph-legend__item" }
[
B.div'
{ className: "graph-legend__title" }
label
,
selectedNodes
{ selectedNodeIds
, extractedNodeList
, clusterId: id_
, nodeCount: getClusterNodeCount nodeCountList id_
H.button
{ className: "graph-legend__code"
, style: { backgroundColor: GET.intColor id_ }
, on: { click: \_ -> selectNodes id_}
}
[]
,
B.wad
[ "flex-grow-1" ]
[
renameable { text: label, className: "graph-legend__label", onRename: \s -> rename s id_ color }
,
selectedNodes
{ selectedNodeIds
, extractedNodeList
, clusterId: id_
, nodeCount: getClusterNodeCount nodeCountList id_
}
]
]
]
]
,
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 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