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
6db0c594
Commit
6db0c594
authored
Dec 19, 2019
by
Przemyslaw Kaminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Graph] work on sigmajs selector
parent
9e296c86
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
142 additions
and
15 deletions
+142
-15
Graph.purs
src/Gargantext/Components/Graph.purs
+6
-3
GraphExplorer.purs
src/Gargantext/Components/GraphExplorer.purs
+1
-1
Controls.purs
src/Gargantext/Components/GraphExplorer/Controls.purs
+5
-1
RangeControl.purs
src/Gargantext/Components/GraphExplorer/RangeControl.purs
+0
-2
SlideButton.purs
src/Gargantext/Components/GraphExplorer/SlideButton.purs
+23
-4
ToggleButton.purs
src/Gargantext/Components/GraphExplorer/ToggleButton.purs
+0
-1
Sigmax.purs
src/Gargantext/Hooks/Sigmax.purs
+1
-1
Sigma.js
src/Gargantext/Hooks/Sigmax/Sigma.js
+96
-2
Sigma.purs
src/Gargantext/Hooks/Sigmax/Sigma.purs
+10
-0
No files found.
src/Gargantext/Components/Graph.purs
View file @
6db0c594
...
@@ -4,13 +4,11 @@ module Gargantext.Components.Graph
...
@@ -4,13 +4,11 @@ module Gargantext.Components.Graph
-- , forceAtlas2Settings, ForceAtlas2Settings, ForceAtlas2OptionalSettings
-- , forceAtlas2Settings, ForceAtlas2Settings, ForceAtlas2OptionalSettings
-- )
-- )
where
where
import Prelude (bind, const, discard,
pure, ($), unit, map, not, show
)
import Prelude (bind, const, discard,
not, pure, unit, ($)
)
import Data.Array as A
import Data.Either (Either(..))
import Data.Either (Either(..))
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
import Data.Nullable (Nullable)
import Data.Nullable (Nullable)
import Data.Tuple (fst)
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import DOM.Simple.Console (log, log2)
import DOM.Simple.Console (log, log2)
import DOM.Simple.Types (Element)
import DOM.Simple.Types (Element)
...
@@ -72,6 +70,7 @@ graphCpt = R.hooksComponent "Graph" cpt
...
@@ -72,6 +70,7 @@ graphCpt = R.hooksComponent "Graph" cpt
_ <- Sigma.addRenderer sig {
_ <- Sigma.addRenderer sig {
"type": "canvas"
"type": "canvas"
, container: c
, container: c
, additionalContexts: ["mouseSelector"]
}
}
pure unit
pure unit
...
@@ -80,6 +79,8 @@ graphCpt = R.hooksComponent "Graph" cpt
...
@@ -80,6 +79,8 @@ graphCpt = R.hooksComponent "Graph" cpt
Sigmax.dependOnSigma (R.readRef sigmaRef) "[graphCpt (Ready)] no sigma" $ \sigma -> do
Sigmax.dependOnSigma (R.readRef sigmaRef) "[graphCpt (Ready)] no sigma" $ \sigma -> do
-- bind the click event only initially, when ref was empty
-- bind the click event only initially, when ref was empty
Sigmax.bindSelectedNodesClick sigma selectedNodeIds multiSelectEnabledRef
Sigmax.bindSelectedNodesClick sigma selectedNodeIds multiSelectEnabledRef
_ <- Sigma.bindMouseSelectorPlugin sigma
pure unit
Sigmax.setEdges sig false
Sigmax.setEdges sig false
Sigma.startForceAtlas2 sig props.forceAtlas2Settings
Sigma.startForceAtlas2 sig props.forceAtlas2Settings
...
@@ -172,6 +173,7 @@ type SigmaSettings =
...
@@ -172,6 +173,7 @@ type SigmaSettings =
, mouseEnabled :: Boolean
, mouseEnabled :: Boolean
-- , mouseInertiaDuration :: Number
-- , mouseInertiaDuration :: Number
-- , mouseInertiaRatio :: Number
-- , mouseInertiaRatio :: Number
, mouseSelectorSize :: Number
-- , mouseWheelEnabled :: Boolean
-- , mouseWheelEnabled :: Boolean
, mouseZoomDuration :: Number
, mouseZoomDuration :: Number
, nodeBorderColor :: String
, nodeBorderColor :: String
...
@@ -239,6 +241,7 @@ sigmaSettings =
...
@@ -239,6 +241,7 @@ sigmaSettings =
, minEdgeSize: 0.5 -- in fact used in tina as edge size
, minEdgeSize: 0.5 -- in fact used in tina as edge size
, minNodeSize: 1.0
, minNodeSize: 1.0
, mouseEnabled: true
, mouseEnabled: true
, mouseSelectorSize: 10.0
, mouseZoomDuration: 150.0
, mouseZoomDuration: 150.0
, nodeBorderColor: "default" -- choices: "default" color vs. "node" color
, nodeBorderColor: "default" -- choices: "default" color vs. "node" color
--, nodesPowRatio : 10.8
--, nodesPowRatio : 10.8
...
...
src/Gargantext/Components/GraphExplorer.purs
View file @
6db0c594
...
@@ -414,6 +414,6 @@ transformGraph controls graph = SigmaxTypes.Graph {nodes: newNodes, edges: newEd
...
@@ -414,6 +414,6 @@ transformGraph controls graph = SigmaxTypes.Graph {nodes: newNodes, edges: newEd
_ -> edge
_ -> edge
nodeMarked node@{ id } =
nodeMarked node@{ id } =
if Set.member id (fst controls.selectedNodeIds) then
if Set.member id (fst controls.selectedNodeIds) then
node { borderColor = "#000", type = "
hover
ed" }
node { borderColor = "#000", type = "
select
ed" }
else
else
node
node
src/Gargantext/Components/GraphExplorer/Controls.purs
View file @
6db0c594
...
@@ -25,7 +25,7 @@ import Gargantext.Components.Graph as Graph
...
@@ -25,7 +25,7 @@ import Gargantext.Components.Graph as Graph
import Gargantext.Components.GraphExplorer.Button (centerButton)
import Gargantext.Components.GraphExplorer.Button (centerButton)
import Gargantext.Components.GraphExplorer.RangeControl (edgeConfluenceControl, edgeWeightControl, nodeSizeControl)
import Gargantext.Components.GraphExplorer.RangeControl (edgeConfluenceControl, edgeWeightControl, nodeSizeControl)
import Gargantext.Components.GraphExplorer.Search (nodeSearchControl)
import Gargantext.Components.GraphExplorer.Search (nodeSearchControl)
import Gargantext.Components.GraphExplorer.SlideButton (cursorSizeButton, labelSizeButton)
import Gargantext.Components.GraphExplorer.SlideButton (cursorSizeButton, labelSizeButton
, mouseSelectorSizeButton
)
import Gargantext.Components.GraphExplorer.ToggleButton (multiSelectEnabledButton, edgesToggleButton, pauseForceAtlasButton)
import Gargantext.Components.GraphExplorer.ToggleButton (multiSelectEnabledButton, edgesToggleButton, pauseForceAtlasButton)
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax as Sigmax
...
@@ -56,14 +56,17 @@ controlsToSigmaSettings { cursorSize: (cursorSize /\ _)} = Graph.sigmaSettings
...
@@ -56,14 +56,17 @@ controlsToSigmaSettings { cursorSize: (cursorSize /\ _)} = Graph.sigmaSettings
type LocalControls =
type LocalControls =
( labelSize :: R.State Number
( labelSize :: R.State Number
, mouseSelectorSize :: R.State Number
)
)
initialLocalControls :: R.Hooks (Record LocalControls)
initialLocalControls :: R.Hooks (Record LocalControls)
initialLocalControls = do
initialLocalControls = do
labelSize <- R.useState' 14.0
labelSize <- R.useState' 14.0
mouseSelectorSize <- R.useState' 10.0
pure $ {
pure $ {
labelSize
labelSize
, mouseSelectorSize
}
}
controls :: Record Controls -> R.Element
controls :: Record Controls -> R.Element
...
@@ -153,6 +156,7 @@ controlsCpt = R.hooksComponent "GraphControls" cpt
...
@@ -153,6 +156,7 @@ controlsCpt = R.hooksComponent "GraphControls" cpt
-- save button
-- save button
, RH.li {} [ nodeSearchControl { graph: props.graph
, RH.li {} [ nodeSearchControl { graph: props.graph
, selectedNodeIds: props.selectedNodeIds } ]
, selectedNodeIds: props.selectedNodeIds } ]
, RH.li {} [ mouseSelectorSizeButton props.sigmaRef localControls.mouseSelectorSize ]
]
]
]
]
]
]
...
...
src/Gargantext/Components/GraphExplorer/RangeControl.purs
View file @
6db0c594
...
@@ -12,8 +12,6 @@ import Reactix as R
...
@@ -12,8 +12,6 @@ import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
import Gargantext.Components.RangeSlider as RS
import Gargantext.Components.RangeSlider as RS
import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Utils.Range as Range
import Gargantext.Utils.Range as Range
type Props = (
type Props = (
...
...
src/Gargantext/Components/GraphExplorer/SlideButton.purs
View file @
6db0c594
...
@@ -3,6 +3,7 @@ module Gargantext.Components.GraphExplorer.SlideButton
...
@@ -3,6 +3,7 @@ module Gargantext.Components.GraphExplorer.SlideButton
, sizeButton
, sizeButton
, cursorSizeButton
, cursorSizeButton
, labelSizeButton
, labelSizeButton
, mouseSelectorSizeButton
) where
) where
import Global (readFloat)
import Global (readFloat)
...
@@ -48,27 +49,45 @@ sizeButtonCpt = R.hooksComponent "SizeButton" cpt
...
@@ -48,27 +49,45 @@ sizeButtonCpt = R.hooksComponent "SizeButton" cpt
cursorSizeButton :: R.State Number -> R.Element
cursorSizeButton :: R.State Number -> R.Element
cursorSizeButton state =
cursorSizeButton state =
sizeButton {
sizeButton {
state
: state
state
, caption: "Cursor Size"
, caption: "Cursor Size"
, min: 1.0
, min: 1.0
, max: 4.0
, max: 4.0
, onChange:
\e -> snd state $ const $ readFloat $ R2.unsafeEventValue
e
, onChange:
snd state <<< const <<< readFloat <<< R2.unsafeEventValu
e
}
}
labelSizeButton :: R.Ref Sigmax.Sigma -> R.State Number -> R.Element
labelSizeButton :: R.Ref Sigmax.Sigma -> R.State Number -> R.Element
labelSizeButton sigmaRef state =
labelSizeButton sigmaRef state =
sizeButton {
sizeButton {
state
: state
state
, caption: "Label Size"
, caption: "Label Size"
, min: 5.0
, min: 5.0
, max: 30.0
, max: 30.0
, onChange: \e -> do
, onChange: \e -> do
let sigma = R.readRef sigmaRef
let sigma = R.readRef sigmaRef
let newValue = readFloat $ R2.unsafeEventValue e
let newValue = readFloat $ R2.unsafeEventValue e
let (
value
/\ setValue) = state
let (
_
/\ setValue) = state
Sigmax.dependOnSigma sigma "[labelSizeButton] sigma: Nothing" $ \s -> do
Sigmax.dependOnSigma sigma "[labelSizeButton] sigma: Nothing" $ \s -> do
Sigma.setSettings s {
Sigma.setSettings s {
defaultLabelSize: newValue
defaultLabelSize: newValue
}
}
setValue $ const newValue
setValue $ const newValue
}
}
mouseSelectorSizeButton :: R.Ref Sigmax.Sigma -> R.State Number -> R.Element
mouseSelectorSizeButton sigmaRef state =
sizeButton {
state
, caption: "Selector Size"
, min: 1.0
, max: 50.0
, onChange: \e -> do
let sigma = R.readRef sigmaRef
let (_ /\ setValue) = state
let newValue = readFloat $ R2.unsafeEventValue e
Sigmax.dependOnSigma sigma "[mouseSelectorSizeButton] sigma: Nothing" $ \s -> do
Sigma.setSettings s {
mouseSelectorSize: newValue
}
setValue $ const newValue
}
src/Gargantext/Components/GraphExplorer/ToggleButton.purs
View file @
6db0c594
...
@@ -19,7 +19,6 @@ import Reactix as R
...
@@ -19,7 +19,6 @@ import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax.Types as SigmaxTypes
import Gargantext.Hooks.Sigmax.Types as SigmaxTypes
type Props = (
type Props = (
...
...
src/Gargantext/Hooks/Sigmax.purs
View file @
6db0c594
module Gargantext.Hooks.Sigmax
module Gargantext.Hooks.Sigmax
where
where
import Prelude (Unit, bind, discard, flip, pure, unit, ($), (*>), (<<<), (<>), (>>=),
(||),
not, const, map)
import Prelude (Unit, bind, discard, flip, pure, unit, ($), (*>), (<<<), (<>), (>>=), not, const, map)
import Data.Array as A
import Data.Array as A
import Data.Either (either)
import Data.Either (either)
...
...
src/Gargantext/Hooks/Sigmax/Sigma.js
View file @
6db0c594
...
@@ -9,7 +9,7 @@ if (typeof window !== 'undefined') {
...
@@ -9,7 +9,7 @@ if (typeof window !== 'undefined') {
const
CustomShapes
=
require
(
'sigma/plugins/garg.js'
).
init
(
sigma
,
window
).
customShapes
;
const
CustomShapes
=
require
(
'sigma/plugins/garg.js'
).
init
(
sigma
,
window
).
customShapes
;
require
(
'sigma/src/utils/sigma.utils.js'
).
init
(
sigma
);
require
(
'sigma/src/utils/sigma.utils.js'
).
init
(
sigma
);
sigma
.
canvas
.
nodes
.
hover
ed
=
(
node
,
context
,
settings
)
=>
{
sigma
.
canvas
.
nodes
.
select
ed
=
(
node
,
context
,
settings
)
=>
{
// hack
// hack
// We need to temporarily set node.type to 'def'. This is for 2 reasons
// We need to temporarily set node.type to 'def'. This is for 2 reasons
// 1. Make it render as a normal node
// 1. Make it render as a normal node
...
@@ -17,11 +17,96 @@ sigma.canvas.nodes.hovered = (node, context, settings) => {
...
@@ -17,11 +17,96 @@ sigma.canvas.nodes.hovered = (node, context, settings) => {
// again with node.type = 'hovered')
// again with node.type = 'hovered')
node
.
type
=
'def'
;
node
.
type
=
'def'
;
sigma
.
canvas
.
hovers
.
def
(
node
,
context
,
settings
);
sigma
.
canvas
.
hovers
.
def
(
node
,
context
,
settings
);
node
.
type
=
'
hover
ed'
;
node
.
type
=
'
select
ed'
;
};
};
CustomShapes
.
init
();
CustomShapes
.
init
();
let
sigmaMouseSelector
=
(
sigma
,
options
)
=>
{
sigma
.
plugins
=
sigma
.
plugins
||
{};
sigma
.
plugins
.
mouseSelector
=
(
s
,
renderer
)
=>
{
var
_self
=
this
;
var
_offset
=
null
;
const
_s
=
s
;
const
_renderer
=
renderer
;
const
_container
=
_renderer
.
container
;
//renderer.initDOM('canvas', 'mouseSelector');
// A hack to force resize to be called (there is a width/height equality
// check which can't be escaped in any other way).
//renderer.resize(renderer.width - 1, renderer.height - 1);
//renderer.resize(renderer.width + 1, renderer.height + 1);
const
_context
=
_renderer
.
contexts
.
mouseSelector
;
_container
.
onmousemove
=
function
(
e
)
{
return
mouseMove
(
e
);
};
_context
.
canvas
.
onclick
=
function
(
e
)
{
return
onClick
(
e
);
};
s
.
bind
(
'click'
,
function
(
e
)
{
return
onClick
(
e
);
})
// The mouseSelector canvas will pass its events down to the "mouse" canvas.
_context
.
canvas
.
style
.
pointerEvents
=
'none'
;
s
.
bind
(
'kill'
,
()
=>
_self
.
unbindAll
());
this
.
unbindAll
=
()
=>
{
console
.
log
(
'[sigmaMouseSelector] unbinding'
);
_container
.
onclick
=
null
;
_container
.
onmousemove
=
null
;
}
const
mouseMove
=
(
e
)
=>
{
const
size
=
_s
.
settings
(
'mouseSelectorSize'
)
||
3
;
const
x
=
e
.
clientX
-
_offset
.
left
-
size
/
2
;
const
y
=
e
.
clientY
-
_offset
.
top
-
size
/
2
;
_context
.
clearRect
(
0
,
0
,
_context
.
canvas
.
width
,
_context
.
canvas
.
height
);
_context
.
fillStyle
=
'rgba(91, 192, 222, 0.7)'
;
_context
.
beginPath
();
_context
.
arc
(
x
,
y
,
size
,
0
,
Math
.
PI
*
2
,
true
);
_context
.
closePath
();
_context
.
fill
();
}
const
onClick
=
(
e
)
=>
{
const
size
=
_s
.
settings
(
'mouseSelectorSize'
)
||
3
;
const
x
=
e
.
data
.
clientX
-
_offset
.
left
-
size
/
2
;
const
y
=
e
.
data
.
clientY
-
_offset
.
top
-
size
/
2
;
const
prefix
=
_renderer
.
options
.
prefix
;
console
.
log
(
'[sigmaMouseSelector] clicked'
,
e
,
x
,
y
,
size
);
let
nodes
=
[];
_s
.
graph
.
nodes
().
forEach
((
node
)
=>
{
const
nodeX
=
node
[
prefix
+
'x'
];
const
nodeY
=
node
[
prefix
+
'y'
];
if
(
sigma
.
utils
.
getDistance
(
x
,
y
,
nodeX
,
nodeY
)
<=
size
)
{
nodes
.
push
(
node
);
}
});
console
.
log
(
'[sigmaMouseSelector] nodes'
,
nodes
);
}
const
calculateOffset
=
(
element
)
=>
{
var
style
=
window
.
getComputedStyle
(
element
);
var
getCssProperty
=
function
(
prop
)
{
return
parseInt
(
style
.
getPropertyValue
(
prop
).
replace
(
'px'
,
''
))
||
0
;
};
return
{
left
:
element
.
getBoundingClientRect
().
left
+
getCssProperty
(
'padding-left'
),
top
:
element
.
getBoundingClientRect
().
top
+
getCssProperty
(
'padding-top'
)
};
};
_offset
=
calculateOffset
(
renderer
.
container
);
}
}
sigmaMouseSelector
(
sigma
);
function
_sigma
(
left
,
right
,
opts
)
{
function
_sigma
(
left
,
right
,
opts
)
{
try
{
try
{
return
right
(
new
sigma
(
opts
));
return
right
(
new
sigma
(
opts
));
...
@@ -45,6 +130,14 @@ function addRenderer(left, right, sigma, renderer) {
...
@@ -45,6 +130,14 @@ function addRenderer(left, right, sigma, renderer) {
return
left
(
e
);
return
left
(
e
);
}
}
}
}
function
bindMouseSelectorPlugin
(
left
,
right
,
sig
)
{
try
{
return
right
(
sigma
.
plugins
.
mouseSelector
(
sig
,
sig
.
renderers
[
0
]));
}
catch
(
e
)
{
console
.
log
(
'[bindMouseSelectorPlugin] error'
,
e
);
return
left
(
e
);
}
}
function
killRenderer
(
left
,
right
,
sigma
,
renderer
)
{
function
killRenderer
(
left
,
right
,
sigma
,
renderer
)
{
try
{
try
{
sigma
.
killRenderer
(
renderer
);
sigma
.
killRenderer
(
renderer
);
...
@@ -91,6 +184,7 @@ exports._sigma = _sigma;
...
@@ -91,6 +184,7 @@ exports._sigma = _sigma;
exports
.
_graphRead
=
graphRead
;
exports
.
_graphRead
=
graphRead
;
exports
.
_refresh
=
refresh
;
exports
.
_refresh
=
refresh
;
exports
.
_addRenderer
=
addRenderer
;
exports
.
_addRenderer
=
addRenderer
;
exports
.
_bindMouseSelectorPlugin
=
bindMouseSelectorPlugin
;
exports
.
_killRenderer
=
killRenderer
;
exports
.
_killRenderer
=
killRenderer
;
exports
.
_getRendererContainer
=
getRendererContainer
;
exports
.
_getRendererContainer
=
getRendererContainer
;
exports
.
_setRendererContainer
=
setRendererContainer
;
exports
.
_setRendererContainer
=
setRendererContainer
;
...
...
src/Gargantext/Hooks/Sigmax/Sigma.purs
View file @
6db0c594
...
@@ -70,6 +70,16 @@ foreign import _addRenderer
...
@@ -70,6 +70,16 @@ foreign import _addRenderer
r
r
(Either err Unit)
(Either err Unit)
bindMouseSelectorPlugin :: forall err. Sigma -> Effect (Either err Unit)
bindMouseSelectorPlugin = runEffectFn3 _bindMouseSelectorPlugin Left Right
foreign import _bindMouseSelectorPlugin
:: forall a b err.
EffectFn3 (a -> Either a b)
(b -> Either a b)
Sigma
(Either err Unit)
killRenderer :: forall r err. Sigma -> r -> Effect (Either err Unit)
killRenderer :: forall r err. Sigma -> r -> Effect (Either err Unit)
killRenderer = runEffectFn4 _killRenderer Left Right
killRenderer = runEffectFn4 _killRenderer Left Right
...
...
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