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
565d20c5
Commit
565d20c5
authored
Nov 10, 2022
by
Alexandre Delanoë
Browse files
Options
Browse Files
Download
Plain Diff
[MERGE]
parents
1688f15f
9f1d85a7
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
294 additions
and
155 deletions
+294
-155
bootstrap-darkster.css
dist/styles/bootstrap-darkster.css
+4
-0
bootstrap-default.css
dist/styles/bootstrap-default.css
+4
-0
bootstrap-greyson.css
dist/styles/bootstrap-greyson.css
+4
-0
bootstrap-herbie.css
dist/styles/bootstrap-herbie.css
+4
-0
bootstrap-monotony.css
dist/styles/bootstrap-monotony.css
+4
-0
GraphTypes.purs
src/Gargantext/Components/GraphExplorer/GraphTypes.purs
+1
-1
Layout.purs
src/Gargantext/Components/GraphExplorer/Layout.purs
+8
-4
Sidebar.purs
src/Gargantext/Components/GraphExplorer/Sidebar.purs
+6
-5
Controls.purs
...Gargantext/Components/GraphExplorer/Toolbar/Controls.purs
+104
-120
SlideButton.purs
...gantext/Components/GraphExplorer/Toolbar/SlideButton.purs
+26
-5
Utils.purs
src/Gargantext/Components/GraphExplorer/Utils.purs
+18
-5
Graph.purs
src/Gargantext/Components/Nodes/Graph.purs
+6
-6
Graphology.js
src/Gargantext/Hooks/Sigmax/Graphology.js
+7
-0
Graphology.purs
src/Gargantext/Hooks/Sigmax/Graphology.purs
+2
-3
Sigma.js
src/Gargantext/Hooks/Sigmax/Sigma.js
+10
-1
Types.purs
src/Gargantext/Hooks/Sigmax/Types.purs
+7
-5
sigmajs-circle-with-contour.js
src/external-deps/sigmajs-circle-with-contour.js
+76
-0
_graph.sass
src/sass/_legacy/_graph.sass
+3
-0
No files found.
dist/styles/bootstrap-darkster.css
View file @
565d20c5
...
@@ -9495,6 +9495,10 @@ input[type=range]:-moz-focusring {
...
@@ -9495,6 +9495,10 @@ input[type=range]:-moz-focusring {
margin-bottom
:
12px
;
margin-bottom
:
12px
;
}
}
.graph-selected-nodes__item
{
display
:
inline-block
;
padding
:
2px
;
}
.graph-selected-nodes__item
:not
(
:last-child
)
{
.graph-selected-nodes__item
:not
(
:last-child
)
{
margin-bottom
:
4px
;
margin-bottom
:
4px
;
}
}
...
...
dist/styles/bootstrap-default.css
View file @
565d20c5
...
@@ -9448,6 +9448,10 @@ input[type=range]:-moz-focusring {
...
@@ -9448,6 +9448,10 @@ input[type=range]:-moz-focusring {
margin-bottom
:
12px
;
margin-bottom
:
12px
;
}
}
.graph-selected-nodes__item
{
display
:
inline-block
;
padding
:
2px
;
}
.graph-selected-nodes__item
:not
(
:last-child
)
{
.graph-selected-nodes__item
:not
(
:last-child
)
{
margin-bottom
:
4px
;
margin-bottom
:
4px
;
}
}
...
...
dist/styles/bootstrap-greyson.css
View file @
565d20c5
...
@@ -9204,6 +9204,10 @@ input[type=range]:-moz-focusring {
...
@@ -9204,6 +9204,10 @@ input[type=range]:-moz-focusring {
margin-bottom
:
12px
;
margin-bottom
:
12px
;
}
}
.graph-selected-nodes__item
{
display
:
inline-block
;
padding
:
2px
;
}
.graph-selected-nodes__item
:not
(
:last-child
)
{
.graph-selected-nodes__item
:not
(
:last-child
)
{
margin-bottom
:
4px
;
margin-bottom
:
4px
;
}
}
...
...
dist/styles/bootstrap-herbie.css
View file @
565d20c5
...
@@ -9452,6 +9452,10 @@ input[type=range]:-moz-focusring {
...
@@ -9452,6 +9452,10 @@ input[type=range]:-moz-focusring {
margin-bottom
:
12px
;
margin-bottom
:
12px
;
}
}
.graph-selected-nodes__item
{
display
:
inline-block
;
padding
:
2px
;
}
.graph-selected-nodes__item
:not
(
:last-child
)
{
.graph-selected-nodes__item
:not
(
:last-child
)
{
margin-bottom
:
4px
;
margin-bottom
:
4px
;
}
}
...
...
dist/styles/bootstrap-monotony.css
View file @
565d20c5
...
@@ -9453,6 +9453,10 @@ input[type=range]:-moz-focusring {
...
@@ -9453,6 +9453,10 @@ input[type=range]:-moz-focusring {
margin-bottom
:
12px
;
margin-bottom
:
12px
;
}
}
.graph-selected-nodes__item
{
display
:
inline-block
;
padding
:
2px
;
}
.graph-selected-nodes__item
:not
(
:last-child
)
{
.graph-selected-nodes__item
:not
(
:last-child
)
{
margin-bottom
:
4px
;
margin-bottom
:
4px
;
}
}
...
...
src/Gargantext/Components/GraphExplorer/GraphTypes.purs
View file @
565d20c5
...
@@ -39,7 +39,7 @@ newtype Node = Node {
...
@@ -39,7 +39,7 @@ newtype Node = Node {
, children :: Array String
, children :: Array String
, id_ :: String
, id_ :: String
, label :: String
, label :: String
, size ::
Int
, size ::
Number
, type_ :: String
, type_ :: String
, x :: Number
, x :: Number
, y :: Number
, y :: Number
...
...
src/Gargantext/Components/GraphExplorer/Layout.purs
View file @
565d20c5
...
@@ -9,7 +9,6 @@ import Data.Int (toNumber)
...
@@ -9,7 +9,6 @@ import Data.Int (toNumber)
import Data.Map as Map
import Data.Map as Map
import Data.Maybe (Maybe(..), fromJust)
import Data.Maybe (Maybe(..), fromJust)
import Data.Nullable (null, Nullable)
import Data.Nullable (null, Nullable)
import Data.Number as DN
import Data.Sequence as Seq
import Data.Sequence as Seq
import Data.Set as Set
import Data.Set as Set
import Data.Tuple (Tuple(..))
import Data.Tuple (Tuple(..))
...
@@ -290,7 +289,11 @@ graphViewCpt = R.memo' $ here.component "graphView" cpt where
...
@@ -290,7 +289,11 @@ graphViewCpt = R.memo' $ here.component "graphView" cpt where
convert :: GET.GraphData -> Tuple (Maybe GET.MetaData) SigmaxT.SGraph
convert :: GET.GraphData -> Tuple (Maybe GET.MetaData) SigmaxT.SGraph
convert (GET.GraphData r) = Tuple r.metaData $ SigmaxT.Graph {nodes, edges}
convert (GET.GraphData r) = Tuple r.metaData $ SigmaxT.Graph {nodes, edges}
where
where
nodes = foldMapWithIndex nodeFn $ GEU.normalizeNodeSize 1 10000 r.nodes
normalizedNodes :: Array GEGT.Node
normalizedNodes = GEGT.Node <$> (GEU.normalizeNodeSizeDefault $ (\(GEGT.Node n) -> n) <$> r.nodes)
nodes :: Seq.Seq (Record SigmaxT.Node)
nodes = foldMapWithIndex nodeFn normalizedNodes
nodeFn :: Int -> GEGT.Node -> Seq.Seq (Record SigmaxT.Node)
nodeFn _i nn@(GEGT.Node n) =
nodeFn _i nn@(GEGT.Node n) =
Seq.singleton {
Seq.singleton {
borderColor: color
borderColor: color
...
@@ -302,7 +305,7 @@ convert (GET.GraphData r) = Tuple r.metaData $ SigmaxT.Graph {nodes, edges}
...
@@ -302,7 +305,7 @@ convert (GET.GraphData r) = Tuple r.metaData $ SigmaxT.Graph {nodes, edges}
, highlighted: false
, highlighted: false
, id : n.id_
, id : n.id_
, label : n.label
, label : n.label
, size :
DN.log (toNumber n.size + 1.0)
, size :
n.size
--, size: toNumber n.size
--, size: toNumber n.size
, type : modeGraphType gargType
, type : modeGraphType gargType
, x : n.x -- cos (toNumber i)
, x : n.x -- cos (toNumber i)
...
@@ -343,7 +346,8 @@ modeGraphType Types.Authors = "square"
...
@@ -343,7 +346,8 @@ modeGraphType Types.Authors = "square"
modeGraphType Types.Institutes = "equilateral"
modeGraphType Types.Institutes = "equilateral"
modeGraphType Types.Sources = "star"
modeGraphType Types.Sources = "star"
--modeGraphType Types.Terms = "def"
--modeGraphType Types.Terms = "def"
modeGraphType Types.Terms = "circle"
--modeGraphType Types.Terms = "circle"
modeGraphType Types.Terms = "ccircle"
--------------------------------------------------------------
--------------------------------------------------------------
...
...
src/Gargantext/Components/GraphExplorer/Sidebar.purs
View file @
565d20c5
...
@@ -509,7 +509,7 @@ neighborhoodCpt = R.memo' $ here.component "neighborhood" cpt where
...
@@ -509,7 +509,7 @@ neighborhoodCpt = R.memo' $ here.component "neighborhood" cpt where
[ "text-info", "d-inline" ] $
[ "text-info", "d-inline" ] $
show termCount
show termCount
,
,
H.text $ nbsp 1 <> "terms"
H.text $ nbsp 1 <> "
related
terms"
,
,
-- Expand word cloud
-- Expand word cloud
B.iconButton
B.iconButton
...
@@ -643,11 +643,12 @@ updateTermButtonCpt = here.component "updateTermButton" cpt where
...
@@ -643,11 +643,12 @@ updateTermButtonCpt = here.component "updateTermButton" cpt where
badgeSize :: Number -> Number -> Number -> String
badgeSize :: Number -> Number -> Number -> String
badgeSize minSize maxSize size =
badgeSize minSize maxSize size =
let
let
minFontSize =
10
.0
minFontSize =
7
.0
maxFontSize = 2
4
.0
maxFontSize = 2
8
.0
sizeScaled = (size - minSize) / (maxSize - minSize) -- in [0; 1] range
sizeScaled = (size - minSize) / (maxSize - minSize) -- in [0; 1] range
scale' = DN.log (sizeScaled + 1.0) / (DN.log 2.0) -- in [0; 1] range
--scale' = DN.log (sizeScaled + 1.0) / (DN.log 2.0) -- in [0; 1] range
scale = minFontSize + scale' * (maxFontSize - minFontSize)
--scale = minFontSize + scale' * (maxFontSize - minFontSize)
scale = minFontSize + sizeScaled * (maxFontSize - minFontSize)
in
in
show scale <> "px"
show scale <> "px"
...
...
src/Gargantext/Components/GraphExplorer/Toolbar/Controls.purs
View file @
565d20c5
...
@@ -165,51 +165,54 @@ controlsCpt = R.memo' $ here.component "controls" cpt where
...
@@ -165,51 +165,54 @@ controlsCpt = R.memo' $ here.component "controls" cpt where
H.nav
H.nav
{ className: "graph-toolbar" }
{ className: "graph-toolbar" }
[
[
B.wad
H.div
[ "flex-shrink-0" ]
{ className: "flex-shrink-0" }
[
[
B.wad
H.div
[ "d-flex" ]
{ className: "d-flex" }
[
[
-- Actions
B.fieldset
{ className: "graph-toolbar__section"
, titleSlot: H.text "Actions"
}
[
-- resetForceAtlasButton { forceAtlasState, sigmaRef }
pauseForceAtlasButton { state: forceAtlasState }
,
gap
{- ,
cameraButton
{ id: graphId'
, forceAtlasState
, hyperdataGraph: hyperdataGraph'
, reloadForest
, session: session
, sigmaRef: sigmaRef
}
-}
]
,
-- View Settings
-- View Settings
B.fieldset
B.fieldset
{ className: "graph-toolbar__section"
{ className: "graph-toolbar__section"
, titleSlot: H.text "View settings"
, titleSlot: H.text "View settings"
}
}
[
[
B.wad
centerButton { forceAtlasState
[ "d-flex", "justify-content-space-between" ]
, sigmaRef }
[
,
B.wad
gap
[]
,
[
edgesToggleButton
-- resetForceAtlasButton { forceAtlasState, sigmaRef }
{ state: showEdges
pauseForceAtlasButton { state: forceAtlasState }
, stateAtlas: forceAtlasState
]
}
,
,
B.wad
gap
[]
,
[
louvainToggleButton { forceAtlasState
centerButton
, state: showLouvain }
{ forceAtlasState
, sigmaRef
}
,
gap
,
edgesToggleButton
{ state: showEdges
, stateAtlas: forceAtlasState
}
,
gap
,
louvainToggleButton
{ forceAtlasState
, state: showLouvain
}
]
]
]
]
]
]
,
,
...
@@ -223,20 +226,16 @@ controlsCpt = R.memo' $ here.component "controls" cpt where
...
@@ -223,20 +226,16 @@ controlsCpt = R.memo' $ here.component "controls" cpt where
}
}
[
[
-- zoom: 0 -100 - calculate ratio
-- zoom: 0 -100 - calculate ratio
multiSelectEnabledButton
multiSelectEnabledButton { forceAtlasState
{ forceAtlasState
, state: multiSelectEnabled }
, state: multiSelectEnabled
}
,
,
gap
gap
,
,
-- toggle multi node selection
-- toggle multi node selection
-- save button
-- save button
mouseSelectorSizeSlider
mouseSelectorSizeSlider { forceAtlasState
{ forceAtlasState
, sigmaRef
, sigmaRef
, state: mouseSelectorSize }
, state: mouseSelectorSize
}
]
]
]
]
,
,
...
@@ -245,86 +244,71 @@ controlsCpt = R.memo' $ here.component "controls" cpt where
...
@@ -245,86 +244,71 @@ controlsCpt = R.memo' $ here.component "controls" cpt where
{ className: intercalate " "
{ className: intercalate " "
[ "graph-toolbar__section"
[ "graph-toolbar__section"
, "graph-toolbar__section--controls"
, "graph-toolbar__section--controls"
, "flex-grow-1
", "
flex-shrink-1"
, "flex-grow-1
flex-shrink-1"
]
]
, titleSlot: H.text "Controls"
, titleSlot: H.text "Controls"
}
}
[
[
B.wad
H.div
[ "d-flex", "gap-2" ]
{ className: "d-flex justify-content-between mb-3" }
[
[
B.wad
edgeConfluenceControl
[ "flex-grow-1", "px-2", "mb-2" ]
{ forceAtlasState
[
, range: edgeConfluenceRange
B.wad
, state: edgeConfluence }
[ "d-flex", "justify-content-between", "mb-6" ]
{- ,
[
edgeWeightControl
edgeConfluenceControl
{ forceAtlasState
{ forceAtlasState
, range: edgeWeightRange
, range: edgeConfluenceRange
, state: edgeWeight }
, state: edgeConfluence
-}
}
{- ,
edgeWeightControl
{ forceAtlasState
, range: edgeWeightRange
, state: edgeWeight
}
-}
]
,
B.wad
[ "d-flex", "justify-content-between" ]
[
-- change level
-- file upload
-- run demo
-- search button
-- search topics
labelSizeButton
{ forceAtlasState
, sigmaRef
, state: labelSize
}
]
]
,
B.wad
[ "flex-grow-1", "px-2", "mb-2" ]
[
B.wad
[ "d-flex", "justify-content-between", "mb-6" ]
[
-- labels size: 1-4
nodeSizeControl
{ forceAtlasState
, range: nodeSizeRange
, state: nodeSize
}
]
,
B.wad
[ "d-flex", "justify-content-between" ]
[
-- change level
-- file upload
-- run demo
-- search button
-- search topics
labelRenderedSizeThresholdButton
{ forceAtlasState
, sigmaRef
, state: labelRenderedSizeThreshold
}
-- ,
-- -- labels size: 1-4
-- nodeSizeControl
-- { range: nodeSizeRange
-- , state: nodeSize
-- }
]
]
]
]
,
H.div
{ className: "d-flex justify-content-between" }
[
-- change level
-- file upload
-- run demo
-- search button
-- search topics
labelSizeButton { forceAtlasState
, graph
, sigmaRef
, state: labelSize }
]
,
H.div
{ className: "d-flex justify-content-between" }
[
-- labels size: 1-4
nodeSizeControl
{ forceAtlasState
, range: nodeSizeRange
, state: nodeSize }
]
,
H.div
{ className: "d-flex justify-content-between" }
[
-- change level
-- file upload
-- run demo
-- search button
-- search topics
labelRenderedSizeThresholdButton { forceAtlasState
, sigmaRef
, state: labelRenderedSizeThreshold }
-- ,
-- -- labels size: 1-4
-- nodeSizeControl
-- { range: nodeSizeRange
-- , state: nodeSize }
]
]
]
]
]
...
...
src/Gargantext/Components/GraphExplorer/Toolbar/SlideButton.purs
View file @
565d20c5
...
@@ -6,6 +6,8 @@ module Gargantext.Components.GraphExplorer.Toolbar.SlideButton
...
@@ -6,6 +6,8 @@ module Gargantext.Components.GraphExplorer.Toolbar.SlideButton
, mouseSelectorSizeSlider
, mouseSelectorSizeSlider
) where
) where
import Data.Array as A
import Data.Map as Map
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
import Data.Number as DN
import Data.Number as DN
import Prelude
import Prelude
...
@@ -15,7 +17,10 @@ import Reactix.DOM.HTML as H
...
@@ -15,7 +17,10 @@ import Reactix.DOM.HTML as H
import Toestand as T
import Toestand as T
import Gargantext.Components.Bootstrap.Types (ComponentStatus(Disabled))
import Gargantext.Components.Bootstrap.Types (ComponentStatus(Disabled))
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Components.GraphExplorer.Utils as GEU
import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax.Graphology as Graphology
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Hooks.Sigmax.Types as SigmaxTypes
import Gargantext.Hooks.Sigmax.Types as SigmaxTypes
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
...
@@ -68,6 +73,7 @@ sizeButtonCpt = here.component "sizeButton" cpt where
...
@@ -68,6 +73,7 @@ sizeButtonCpt = here.component "sizeButton" cpt where
type LabelSizeButtonProps =
type LabelSizeButtonProps =
( forceAtlasState :: T.Box SigmaxTypes.ForceAtlasState
( forceAtlasState :: T.Box SigmaxTypes.ForceAtlasState
, graph :: T.Box SigmaxTypes.SGraph
, sigmaRef :: R.Ref Sigmax.Sigma
, sigmaRef :: R.Ref Sigmax.Sigma
, state :: T.Box Number)
, state :: T.Box Number)
...
@@ -76,13 +82,19 @@ labelSizeButton = R2.leaf labelSizeButtonCpt
...
@@ -76,13 +82,19 @@ labelSizeButton = R2.leaf labelSizeButtonCpt
labelSizeButtonCpt :: R.Component LabelSizeButtonProps
labelSizeButtonCpt :: R.Component LabelSizeButtonProps
labelSizeButtonCpt = here.component "labelSizeButton" cpt
labelSizeButtonCpt = here.component "labelSizeButton" cpt
where
where
cpt { forceAtlasState, sigmaRef, state} _ = do
cpt { forceAtlasState, graph, sigmaRef, state} _ = do
graph' <- T.useLive T.unequal graph
let minLabelSize = 1.0
let maxLabelSize = 30.0
let defaultLabelSize = 14.0
pure $ sizeButton {
pure $ sizeButton {
state
state
, caption: "Label size"
, caption: "Label size"
, forceAtlasState
, forceAtlasState
, min:
1.0
, min:
minLabelSize
, max:
30.0
, max:
maxLabelSize
, onChange: \e -> do
, onChange: \e -> do
let sigma = R.readRef sigmaRef
let sigma = R.readRef sigmaRef
let newValue' = DN.fromString $ R.unsafeEventValue e
let newValue' = DN.fromString $ R.unsafeEventValue e
...
@@ -90,11 +102,20 @@ labelSizeButtonCpt = here.component "labelSizeButton" cpt
...
@@ -90,11 +102,20 @@ labelSizeButtonCpt = here.component "labelSizeButton" cpt
Nothing -> pure unit
Nothing -> pure unit
Just newValue ->
Just newValue ->
Sigmax.dependOnSigma sigma "[labelSizeButton] sigma: Nothing" $ \s -> do
Sigmax.dependOnSigma sigma "[labelSizeButton] sigma: Nothing" $ \s -> do
let ratio = (newValue - minLabelSize) / (defaultLabelSize - minLabelSize)
let nodes = SigmaxTypes.graphNodes graph'
let nodesResized = (\n@{ size } -> n { size = size * ratio }) <$> nodes
let nodesMap = SigmaxTypes.idMap nodesResized
Graphology.forEachNode (Sigma.graph s) $ \{ id } -> do
case Map.lookup id nodesMap of
Nothing -> pure unit
Just { size } -> Graphology.mergeNodeAttributes (Sigma.graph s) id { size }
Sigma.setSettings s {
Sigma.setSettings s {
defaultLabelSize: newValue
defaultLabelSize: newValue
, drawLabels: true
, drawLabels: true
, labelSize: newValue
, labelSize: newValue
, maxNodeSize: newValue / 2.5
--
, maxNodeSize: newValue / 2.5
--, labelSizeRatio: newValue / 2.5
--, labelSizeRatio: newValue / 2.5
}
}
T.write_ newValue state
T.write_ newValue state
...
@@ -145,7 +166,7 @@ mouseSelectorSizeSliderCpt = here.component "mouseSelectorSizeSlider" cpt
...
@@ -145,7 +166,7 @@ mouseSelectorSizeSliderCpt = here.component "mouseSelectorSizeSlider" cpt
caption: "Selector size (Shift + wheel)"
caption: "Selector size (Shift + wheel)"
, forceAtlasState
, forceAtlasState
, min: 1.0
, min: 1.0
, max:
5
0.0
, max:
10
0.0
, onChange: \e -> do
, onChange: \e -> do
let sigma = R.readRef sigmaRef
let sigma = R.readRef sigmaRef
let newValue' = DN.fromString $ R.unsafeEventValue e
let newValue' = DN.fromString $ R.unsafeEventValue e
...
...
src/Gargantext/Components/GraphExplorer/Utils.purs
View file @
565d20c5
module Gargantext.Components.GraphExplorer.Utils
module Gargantext.Components.GraphExplorer.Utils
( stEdgeToGET, stNodeToGET
( stEdgeToGET, stNodeToGET
, normalizeNodes
, normalizeNodes
, normalizeNodeSizeDefault
, normalizeNodeSize
, normalizeNodeSize
, takeGreatestNodeByCluster, countNodeByCluster
, takeGreatestNodeByCluster, countNodeByCluster
) where
) where
...
@@ -13,6 +14,7 @@ import Data.Lens (Lens', lens, over, traversed, (^.))
...
@@ -13,6 +14,7 @@ import Data.Lens (Lens', lens, over, traversed, (^.))
import Data.Int (floor, toNumber)
import Data.Int (floor, toNumber)
import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.Newtype (wrap)
import Data.Newtype (wrap)
import Data.Number as DN
import Data.Sequence as Seq
import Data.Sequence as Seq
import Data.Traversable (class Traversable)
import Data.Traversable (class Traversable)
import Gargantext.Components.GraphExplorer.GraphTypes as GEGT
import Gargantext.Components.GraphExplorer.GraphTypes as GEGT
...
@@ -49,8 +51,16 @@ normalizeNodes ns = GUL.normalizeLens xLens $ GUL.normalizeLens yLens ns
...
@@ -49,8 +51,16 @@ normalizeNodes ns = GUL.normalizeLens xLens $ GUL.normalizeLens yLens ns
yLens :: Lens' GEGT.Node Number
yLens :: Lens' GEGT.Node Number
yLens = lens (\(GEGT.Node { y }) -> y) $ (\(GEGT.Node n) val -> GEGT.Node (n { y = val }))
yLens = lens (\(GEGT.Node { y }) -> y) $ (\(GEGT.Node n) val -> GEGT.Node (n { y = val }))
normalizeNodeSize :: forall t. Traversable t => Int -> Int -> t GEGT.Node -> t GEGT.Node
type NodeSize r = { size :: Number | r }
normalizeNodeSize minSize maxSize ns = over traversed (over sizeLens (\s -> toNumber minSize + (s - sizeMin') * quotient)) ns
normalizeNodeSizeDefault :: forall t r. Traversable t => t (NodeSize r) -> t (NodeSize r)
normalizeNodeSizeDefault ns = logSize <$> normalizeNodeSize 50.0 100000.0 ns
where
logSize (n@{ size }) = n { size = DN.log (size + 1.0) }
normalizeNodeSize :: forall t r. Traversable t =>
Number -> Number -> t (NodeSize r) -> t (NodeSize r)
normalizeNodeSize minSize maxSize ns = over traversed (over sizeLens (\s -> minSize + (s - sizeMin') * quotient)) ns
where
where
sizes = over traversed (_ ^. sizeLens) ns
sizes = over traversed (_ ^. sizeLens) ns
sizeMin = minimum sizes
sizeMin = minimum sizes
...
@@ -62,9 +72,12 @@ normalizeNodeSize minSize maxSize ns = over traversed (over sizeLens (\s -> toNu
...
@@ -62,9 +72,12 @@ normalizeNodeSize minSize maxSize ns = over traversed (over sizeLens (\s -> toNu
sizeMin' = fromMaybe 0.0 sizeMin
sizeMin' = fromMaybe 0.0 sizeMin
divisor = maybe 1.0 (\r -> 1.0 / r) range
divisor = maybe 1.0 (\r -> 1.0 / r) range
quotient :: Number
quotient :: Number
quotient = (toNumber $ maxSize - minSize) * divisor
quotient = (maxSize - minSize) * divisor
sizeLens :: Lens' GEGT.Node Number
--quotient = (toNumber $ maxSize - minSize) * divisor
sizeLens = lens (\(GEGT.Node { size }) -> toNumber size) $ (\(GEGT.Node n) val -> GEGT.Node (n { size = floor val }))
--sizeLens :: Lens' GEGT.Node Number
--sizeLens = lens (\(GEGT.Node { size }) -> size) $ (\(GEGT.Node n) val -> GEGT.Node (n { size = val }))
sizeLens :: Lens' { size :: Number | r } Number
sizeLens = lens (\{ size } -> size) $ \n val -> (n { size = val })
------------------------------------------------------------------------
------------------------------------------------------------------------
...
...
src/Gargantext/Components/Nodes/Graph.purs
View file @
565d20c5
...
@@ -98,22 +98,22 @@ nodeCpt = here.component "node" cpt where
...
@@ -98,22 +98,22 @@ nodeCpt = here.component "node" cpt where
Tuple mMetaData graph = convert hyperdataGraph
Tuple mMetaData graph = convert hyperdataGraph
in
in
hydrateStore
hydrateStore
{ graph
{ cacheParams: cache'
, graph
, graphId
, hyperdataGraph: loaded
, hyperdataGraph: loaded
, mMetaData
, mMetaData
, graphId
, cacheParams: cache'
}
}
}
}
--------------------------------------------------------
--------------------------------------------------------
type HydrateStoreProps =
type HydrateStoreProps =
(
mMetaData :: Maybe GET.MetaData
(
cacheParams :: GET.CacheParams
, graph :: SigmaxT.SGraph
, graph :: SigmaxT.SGraph
, hyperdataGraph :: GET.HyperdataGraph
, graphId :: GET.GraphId
, graphId :: GET.GraphId
, cacheParams :: GET.CacheParams
, hyperdataGraph :: GET.HyperdataGraph
, mMetaData :: Maybe GET.MetaData
)
)
hydrateStore :: R2.Leaf HydrateStoreProps
hydrateStore :: R2.Leaf HydrateStoreProps
...
...
src/Gargantext/Hooks/Sigmax/Graphology.js
View file @
565d20c5
...
@@ -18,6 +18,13 @@ export function _mergeNodeAttributes(g, name, attrs) {
...
@@ -18,6 +18,13 @@ export function _mergeNodeAttributes(g, name, attrs) {
return
g
.
mergeNodeAttributes
(
name
,
attrs
);
return
g
.
mergeNodeAttributes
(
name
,
attrs
);
}
}
export
function
_forEachNode
(
g
,
fn
)
{
return
g
.
forEachNode
(
function
(
_name
,
attrs
)
{
// NOTE: fn is an effectful function, it wraps `do` in a separate function
return
fn
(
attrs
)();
})
}
export
function
_addEdge
(
g
,
source
,
target
,
e
)
{
export
function
_addEdge
(
g
,
source
,
target
,
e
)
{
//return g.addEdge(source, target, e);
//return g.addEdge(source, target, e);
...
...
src/Gargantext/Hooks/Sigmax/Graphology.purs
View file @
565d20c5
...
@@ -27,6 +27,7 @@ foreign import _addNode :: EffectFn3 Graph String (Record Types.Node) String
...
@@ -27,6 +27,7 @@ foreign import _addNode :: EffectFn3 Graph String (Record Types.Node) String
foreign import _updateNode :: EffectFn3 Graph String (Record Types.Node -> Record Types.Node) Unit
foreign import _updateNode :: EffectFn3 Graph String (Record Types.Node -> Record Types.Node) Unit
foreign import _addEdge :: EffectFn4 Graph String String (Record Types.Edge) String
foreign import _addEdge :: EffectFn4 Graph String String (Record Types.Edge) String
foreign import _mergeNodeAttributes :: forall a. EffectFn3 Graph String a Unit
foreign import _mergeNodeAttributes :: forall a. EffectFn3 Graph String a Unit
foreign import _forEachNode :: EffectFn2 Graph (Record Types.Node -> Effect Unit) Unit
--foreign import _updateEdge :: EffectFn4 Graph String String (Record Types.Edge) String
--foreign import _updateEdge :: EffectFn4 Graph String String (Record Types.Edge) String
foreign import _mapNodes :: forall a. Fn2 Graph (Record Types.Node -> a) (Array a)
foreign import _mapNodes :: forall a. Fn2 Graph (Record Types.Node -> a) (Array a)
foreign import _filterNodes :: Fn2 Graph (Record Types.Node -> Boolean) (Array Types.NodeId)
foreign import _filterNodes :: Fn2 Graph (Record Types.Node -> Boolean) (Array Types.NodeId)
...
@@ -65,9 +66,7 @@ updateNode g node@{ id, borderColor, color, equilateral, hidden, highlighted, ty
...
@@ -65,9 +66,7 @@ updateNode g node@{ id, borderColor, color, equilateral, hidden, highlighted, ty
mergeNodeAttributes :: forall a. Graph -> Types.NodeId -> a -> Effect Unit
mergeNodeAttributes :: forall a. Graph -> Types.NodeId -> a -> Effect Unit
mergeNodeAttributes = runEffectFn3 _mergeNodeAttributes
mergeNodeAttributes = runEffectFn3 _mergeNodeAttributes
forEachNode :: Graph -> (Record Types.Node -> Effect Unit) -> Effect Unit
forEachNode :: Graph -> (Record Types.Node -> Effect Unit) -> Effect Unit
-- TODO Check this: how does FFI translate function of two arguments
forEachNode = runEffectFn2 _forEachNode
-- into PS \x y ?
forEachNode g fn = pure $ g ... "forEachNode" $ [\_ n -> fn n]
mapNodes :: forall a. Graph -> (Record Types.Node -> a) -> Array a
mapNodes :: forall a. Graph -> (Record Types.Node -> a) -> Array a
mapNodes = runFn2 _mapNodes
mapNodes = runFn2 _mapNodes
filterNodes :: Graph -> (Record Types.Node -> Boolean) -> Array Types.NodeId
filterNodes :: Graph -> (Record Types.Node -> Boolean) -> Array Types.NodeId
...
...
src/Gargantext/Hooks/Sigmax/Sigma.js
View file @
565d20c5
...
@@ -3,6 +3,8 @@
...
@@ -3,6 +3,8 @@
import
Graph
from
'graphology'
;
import
Graph
from
'graphology'
;
import
Sigma
from
'sigma'
;
import
Sigma
from
'sigma'
;
import
{
takeScreenshot
}
from
'../../src/external-deps/sigmajs-screenshot.js'
;
import
{
takeScreenshot
}
from
'../../src/external-deps/sigmajs-screenshot.js'
;
import
CircleNodeProgram
from
'sigma/rendering/webgl/programs/node.fast'
;
import
ContourCircleNodeProgram
from
'../../src/external-deps/sigmajs-circle-with-contour.js'
;
let
sigma
=
Sigma
.
Sigma
;
let
sigma
=
Sigma
.
Sigma
;
console
.
log
(
'imported sigma'
,
Sigma
);
console
.
log
(
'imported sigma'
,
Sigma
);
...
@@ -164,7 +166,14 @@ let sigmaMouseSelector = function(sigma, options) {
...
@@ -164,7 +166,14 @@ let sigmaMouseSelector = function(sigma, options) {
function
_sigma
(
left
,
right
,
el
,
opts
)
{
function
_sigma
(
left
,
right
,
el
,
opts
)
{
try
{
try
{
let
graph
=
new
Graph
();
let
graph
=
new
Graph
();
let
s
=
new
sigma
(
graph
,
el
,
opts
.
settigns
);
const
settings
=
{
nodeProgramClasses
:
{
circle
:
CircleNodeProgram
.
default
,
// TODO why default? It seems that import should be fixed
ccircle
:
ContourCircleNodeProgram
},
...
opts
.
settings
};
let
s
=
new
sigma
(
graph
,
el
,
settings
);
console
.
log
(
'[_sigma] initializing sigma with el'
,
el
,
'opts'
,
opts
.
settings
,
'sigma'
,
s
);
console
.
log
(
'[_sigma] initializing sigma with el'
,
el
,
'opts'
,
opts
.
settings
,
'sigma'
,
s
);
console
.
log
(
'[_sigma] labelRenderedSizeThreshold'
,
opts
.
settings
.
labelRenderedSizeThreshold
);
console
.
log
(
'[_sigma] labelRenderedSizeThreshold'
,
opts
.
settings
.
labelRenderedSizeThreshold
);
sigmaMouseSelector
(
s
);
sigmaMouseSelector
(
s
);
...
...
src/Gargantext/Hooks/Sigmax/Types.purs
View file @
565d20c5
...
@@ -9,6 +9,7 @@ import Data.Map as Map
...
@@ -9,6 +9,7 @@ import Data.Map as Map
import Data.Maybe (Maybe(..), fromJust)
import Data.Maybe (Maybe(..), fromJust)
import Data.Sequence as Seq
import Data.Sequence as Seq
import Data.Set as Set
import Data.Set as Set
import Data.Traversable (class Traversable)
import Data.Tuple (Tuple(..))
import Data.Tuple (Tuple(..))
import Partial.Unsafe (unsafePartial)
import Partial.Unsafe (unsafePartial)
import Prelude (class Eq, class Show, map, ($), (&&), (==), (||), (<$>), (<), mod, not)
import Prelude (class Eq, class Show, map, ($), (&&), (==), (||), (<$>), (<), mod, not)
...
@@ -107,19 +108,20 @@ graphEdges (Graph {edges}) = edges
...
@@ -107,19 +108,20 @@ graphEdges (Graph {edges}) = edges
graphNodes :: SGraph -> Seq.Seq (Record Node)
graphNodes :: SGraph -> Seq.Seq (Record Node)
graphNodes (Graph {nodes}) = nodes
graphNodes (Graph {nodes}) = nodes
idMap :: forall r t. Traversable t => t { id :: String | r } -> Map.Map String { id :: String | r }
idMap xs = Map.fromFoldable $ (\x@{ id } -> Tuple id x) <$> xs
edgesGraphMap :: SGraph -> EdgesMap
edgesGraphMap :: SGraph -> EdgesMap
edgesGraphMap graph =
edgesGraphMap graph = idMap $ graphEdges graph
Map.fromFoldable $ map (\e -> Tuple e.id e) $ graphEdges graph
edgesFilter :: (Record Edge -> Boolean) -> SGraph -> SGraph
edgesFilter :: (Record Edge -> Boolean) -> SGraph -> SGraph
edgesFilter f (Graph {edges, nodes}) = Graph { edges: Seq.filter f edges, nodes }
edgesFilter f (Graph {edges, nodes}) = Graph { edges: Seq.filter f edges, nodes }
nodesMap :: Seq.Seq (Record Node) -> NodesMap
nodesMap :: Seq.Seq (Record Node) -> NodesMap
nodesMap
nodes = Map.fromFoldable $ map (\n -> Tuple n.id n) nodes
nodesMap
= idMap
nodesGraphMap :: SGraph -> NodesMap
nodesGraphMap :: SGraph -> NodesMap
nodesGraphMap graph =
nodesGraphMap graph = idMap $ graphNodes graph
nodesMap $ graphNodes graph
nodesFilter :: (Record Node -> Boolean) -> SGraph -> SGraph
nodesFilter :: (Record Node -> Boolean) -> SGraph -> SGraph
nodesFilter f (Graph {edges, nodes}) = Graph { edges, nodes: Seq.filter f nodes }
nodesFilter f (Graph {edges, nodes}) = Graph { edges, nodes: Seq.filter f nodes }
...
...
src/external-deps/sigmajs-circle-with-contour.js
0 → 100644
View file @
565d20c5
// Based on sigma.js/src/rendering/webgl/programs/node.fast.ts
import
{
NodeDisplayData
}
from
"sigma/types"
;
import
{
floatColor
}
from
"sigma/utils"
;
import
vertexShaderSource
from
"sigma/rendering/webgl/shaders/node.fast.vert.glsl"
;
import
fragmentShaderSource
from
"sigma/rendering/webgl/shaders/node.fast.frag.glsl"
;
import
{
AbstractNodeProgram
}
from
"sigma/rendering/webgl/programs/common/node"
;
import
{
RenderParams
}
from
"sigma/rendering/webgl/programs/common/program"
;
import
CircleNodeProgram
from
'sigma/rendering/webgl/programs/node.fast'
;
const
POINTS
=
2
;
const
ATTRIBUTES
=
4
;
/*
export default class NodeContourFastProgram extends AbstractNodeProgram {
//constructor(gl : WebGLRenderingContext) {
constructor(gl) {
super(gl, vertexShaderSource, fragmentShaderSource, POINTS, ATTRIBUTES);
this.bind();
}
*/
export
default
class
NodeContourFastProgram
extends
CircleNodeProgram
{
//process(data: NodeDisplayData, hidden: boolean, offset: number): void {
process
(
data
,
hidden
,
offset
)
{
const
array
=
this
.
array
;
let
i
=
offset
*
POINTS
*
ATTRIBUTES
;
if
(
hidden
)
{
// contour
array
[
i
++
]
=
0
;
array
[
i
++
]
=
0
;
array
[
i
++
]
=
0
;
array
[
i
++
]
=
0
;
// circle
array
[
i
++
]
=
0
;
array
[
i
++
]
=
0
;
array
[
i
++
]
=
0
;
array
[
i
++
]
=
0
;
return
;
}
const
color
=
floatColor
(
data
.
color
);
const
black
=
floatColor
(
'black'
);
// contour
array
[
i
++
]
=
data
.
x
;
array
[
i
++
]
=
data
.
y
;
array
[
i
++
]
=
data
.
size
+
1
;
array
[
i
++
]
=
black
;
// circle
array
[
i
++
]
=
data
.
x
;
array
[
i
++
]
=
data
.
y
;
array
[
i
++
]
=
data
.
size
;
array
[
i
]
=
color
;
}
//render(params: RenderParams): void {
render
(
params
)
{
if
(
this
.
hasNothingToRender
())
return
;
const
gl
=
this
.
gl
;
const
program
=
this
.
program
;
gl
.
useProgram
(
program
);
gl
.
uniform1f
(
this
.
ratioLocation
,
1
/
Math
.
sqrt
(
params
.
ratio
));
gl
.
uniform1f
(
this
.
scaleLocation
,
params
.
scalingRatio
);
gl
.
uniformMatrix3fv
(
this
.
matrixLocation
,
false
,
params
.
matrix
);
gl
.
drawArrays
(
gl
.
POINTS
,
0
,
this
.
array
.
length
/
ATTRIBUTES
);
}
}
src/sass/_legacy/_graph.sass
View file @
565d20c5
...
@@ -216,6 +216,9 @@
...
@@ -216,6 +216,9 @@
&
__item
&
__item
display
:
inline-block
padding
:
2px
&
:not
(
:last-child
)
&
:not
(
:last-child
)
margin-bottom
:
space-x
(
0
.5
)
margin-bottom
:
space-x
(
0
.5
)
...
...
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