Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
clinicaltrials
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
david Chavalarias
clinicaltrials
Commits
7af0b354
Commit
7af0b354
authored
Apr 04, 2017
by
Romain Loth
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP: area select
parent
9e6a6545
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
224 additions
and
159 deletions
+224
-159
extras_explorerjs.js
extras_explorerjs.js
+127
-49
grid.css
libs/css2/grid.css
+2
-6
Tinaweb.js
tinawebJS/Tinaweb.js
+86
-98
enviroment.js
tinawebJS/enviroment.js
+2
-2
main.js
tinawebJS/main.js
+4
-1
methods.js
tinawebJS/methods.js
+3
-3
No files found.
extras_explorerjs.js
View file @
7af0b354
...
@@ -414,7 +414,7 @@ function draw1Circle(ctx , x , y , color) {
...
@@ -414,7 +414,7 @@ function draw1Circle(ctx , x , y , color) {
// --------------------
// --------------------
// new sigma.js: could be replaced by default _moveHandler with bindings ?
// new sigma.js: could be replaced by default _moveHandler with bindings ?
// => atm rewrote entire function with new values
// => atm rewrote entire function with new values
function
t
rackMouse
(
e
)
{
function
circleT
rackMouse
(
e
)
{
if
(
!
shift_key
)
{
if
(
!
shift_key
)
{
// $.doTimeout(300,function (){
// $.doTimeout(300,function (){
// new sigma.js 2D mouse context
// new sigma.js 2D mouse context
...
@@ -426,17 +426,9 @@ function trackMouse(e) {
...
@@ -426,17 +426,9 @@ function trackMouse(e) {
TW
.
partialGraph
.
renderers
[
0
].
container
.
offsetWidth
,
TW
.
partialGraph
.
renderers
[
0
].
container
.
offsetWidth
,
TW
.
partialGraph
.
renderers
[
0
].
container
.
offsetHeight
);
TW
.
partialGraph
.
renderers
[
0
].
container
.
offsetHeight
);
// testing with overNodes event
// classic mousemove event or other similar non-sigma events
// cf. https://github.com/jacomyal/sigma.js/wiki/Events-API
x
=
sigma
.
utils
.
getX
(
e
);
if
(
e
.
type
==
"overNodes"
)
{
y
=
sigma
.
utils
.
getY
(
e
);
x
=
e
.
data
.
captor
.
clientX
y
=
e
.
data
.
captor
.
clientY
}
// classic mousemove event or other similar events
else
{
x
=
sigma
.
utils
.
getX
(
e
);
y
=
sigma
.
utils
.
getY
(
e
);
}
// console.log("trackMouse mod: x", x, "y", y)
// console.log("trackMouse mod: x", x, "y", y)
...
@@ -446,46 +438,33 @@ function trackMouse(e) {
...
@@ -446,46 +438,33 @@ function trackMouse(e) {
ctx
.
globalAlpha
=
0.5
;
ctx
.
globalAlpha
=
0.5
;
ctx
.
beginPath
();
ctx
.
beginPath
();
//
labels appear
//
convert (TODO CHECK IN THIS CONTEXT)
// var nds = TW.partialGraph.graph.nodes(
)
var
camCoords
=
TW
.
cam
.
cameraPosition
(
x
,
y
)
// TODO replace by a hover binding (and POSS use quadtree zone)
var
exactNodeset
=
circleGetAreaNodes
(
camCoords
.
x
,
camCoords
.
y
)
// TODO REFA UNCOMMENT pseudo hover
// labels appear
//
//
// if(TW.partialGraph.camera.ratio>showLabelsIfZoom){
// if(TW.partialGraph.camera.ratio > showLabelsIfZoom){
// for(var i in nds){
// for n of exactNodeset
// n=nds[i];
// n.forceLabel=true;
// if(n.hidden==false){
// distance = Math.sqrt(
// Math.pow((x-parseInt(n.displayX)),2) +
// Math.pow((y-parseInt(n.displayY)),2)
// );
// if(parseInt(distance)<=cursor_size) {
// n.forceLabel=true;
// } else {
// if(typeof(n.neighbour)!=="undefined") {
// if(!n.neighbour) n.forceLabel=false;
// } else n.forceLabel=false;
// }
// }
// }
// if(TW.partialGraph.forceatlas2 && TW.partialGraph.forceatlas2.count<=1) {
// TW.partialGraph.refresh({skipIndexation:true})
// }
// } else {
// for(var i in nds){
// n=nds[i];
// if(!n.hidden){
// n.forceLabel=false;
// if(typeof(n.neighbour)!=="undefined") {
// if(!n.neighbour) n.forceLabel=false;
// else n.forceLabel=true;
// } else n.forceLabel=false;
// }
// }
// if(TW.partialGraph.forceatlas2 && TW.partialGraph.forceatlas2.count<=1) {
// TW.partialGraph.refresh({skipIndexation:true})
// }
// }
// }
// else {
// for(var i in exactNodeset){
// n.forceLabel=false;
// if(typeof(n.neighbour)!=="undefined") {
// if(!n.neighbour) n.forceLabel=false;
// else n.forceLabel=true;
// } else n.forceLabel=false;
// }
// if(TW.partialGraph.forceatlas2 && TW.partialGraph.forceatlas2.count<=1) {
// TW.partialGraph.refresh({skipIndexation:true})
// }
// }
ctx
.
arc
(
x
,
y
,
cursor_size
,
0
,
Math
.
PI
*
2
,
true
);
ctx
.
arc
(
x
,
y
,
cursor_size
,
0
,
Math
.
PI
*
2
,
true
);
//ctx.arc(TW.partialGraph._core.width/2, TW.partialGraph._core.height/2, 4, 0, 2 * Math.PI, true);/*todel*/
//ctx.arc(TW.partialGraph._core.width/2, TW.partialGraph._core.height/2, 4, 0, 2 * Math.PI, true);/*todel*/
ctx
.
closePath
();
ctx
.
closePath
();
...
@@ -495,6 +474,105 @@ function trackMouse(e) {
...
@@ -495,6 +474,105 @@ function trackMouse(e) {
}
}
}
}
// exact subset of nodes under circle
function
circleGetAreaNodes
(
camX0
,
camY0
)
{
// leverage quadtree to get a neighborhood
var
slightlyLargerNodeset
=
circleLocalSubset
(
camX0
,
camY0
,
cursor_size
*
TW
.
cam
.
ratio
// cursor_size to cam units
)
var
exactNodeset
=
[]
for
(
var
i
in
slightlyLargerNodeset
){
n
=
slightlyLargerNodeset
[
i
];
if
(
n
.
hidden
==
false
){
distance
=
Math
.
sqrt
(
Math
.
pow
((
x
-
parseInt
(
n
.
displayX
)),
2
)
+
Math
.
pow
((
y
-
parseInt
(
n
.
displayY
)),
2
)
);
if
(
parseInt
(
distance
)
<=
cursor_size
)
{
exactNodeset
.
push
.
}
else
{
if
(
typeof
(
n
.
neighbour
)
!==
"undefined"
)
{
if
(
!
n
.
neighbour
)
n
.
forceLabel
=
false
;
}
else
n
.
forceLabel
=
false
;
}
}
}
if
(
TW
.
partialGraph
.
forceatlas2
&&
TW
.
partialGraph
.
forceatlas2
.
count
<=
1
)
{
TW
.
partialGraph
.
refresh
({
skipIndexation
:
true
})
}
return
exactNodeset
}
// returns set of nodes in the quad subzones around a square
// that is containing the circle centered on x0, y0
// (use case: reduce number of nodes before exact check)
function
circleLocalSubset
(
camX0
,
camY0
,
camRay
)
{
y
var
P0
=
{
x
:
camX0
,
y
:
camY0
}
// to use quadtree.area, we consider the square
// in which our circle is inscribed
// y-
//
// P1 x----------x P2
// | |
// <= x- | P0 | 2r x+ =>
// | |
// x----------x
//
// y+
var
P1
=
{
x
:
P0
.
x
-
camRay
,
y
:
P0
.
y
-
camRay
}
// top left
var
P2
=
{
x
:
P0
.
x
+
camRay
,
y
:
P0
.
y
-
camRay
}
// top right
var
areaNodes
=
TW
.
cam
.
quadtree
.
area
({
height
:
2
*
camRay
,
x1
:
P1
.
x
,
y1
:
P1
.
y
,
x2
:
P2
.
x
,
y2
:
P2
.
y
})
// neighborhood guaranteed a bit larger than the square
// console.log('got ',areaNodes.length, 'nodes:', areaNodes)
return
areaNodes
}
// not used but useful to quickly make visible any nodes[]
function
flashNodesArray
(
nodesArray
)
{
// for diagnostic
var
minX
=
1000000
var
minY
=
1000000
var
maxX
=
0
var
maxY
=
0
for
(
var
j
in
nodesArray
)
{
var
n
=
nodesArray
[
j
]
if
(
minX
>
n
.
x
)
minX
=
n
.
x
if
(
minY
>
n
.
y
)
minY
=
n
.
y
if
(
maxX
<
n
.
x
)
maxX
=
n
.
x
if
(
maxY
<
n
.
y
)
maxY
=
n
.
y
n
.
size
=
300
n
.
label
=
"> "
+
n
.
label
+
"< "
n
.
color
=
"yellow"
}
console
.
log
(
"nodesArray encompassed by:"
,
minX
,
minY
,
';'
,
maxX
,
maxY
)
TW
.
partialGraph
.
refresh
()
}
// BASIC MODULARITY
// BASIC MODULARITY
// =================
// =================
// ProcessDivsFlags is for adding/removing features from TinawebJS
// ProcessDivsFlags is for adding/removing features from TinawebJS
...
...
libs/css2/grid.css
View file @
7af0b354
...
@@ -14,15 +14,11 @@
...
@@ -14,15 +14,11 @@
display
:
none
;
display
:
none
;
}
}
#graph-div
{
#sigma-contnr
{
background-color
:
#22e
;
}
#graph-zone
{
background-color
:
#44b
;
background-color
:
#44b
;
}
}
#
right-
sidebar
{
#sidebar
{
background-color
:
#2e2
;
background-color
:
#2e2
;
}
}
...
...
tinawebJS/Tinaweb.js
View file @
7af0b354
...
@@ -682,110 +682,85 @@ TinaWebJS = function ( sigmacanvas ) {
...
@@ -682,110 +682,85 @@ TinaWebJS = function ( sigmacanvas ) {
});
});
// new sigma.js: attempt to use sigma events bindings
// new sigma.js: attempt to use sigma events bindings
// cf. https://github.com/jacomyal/sigma.js/wiki/Events-API
// cases:
// cases:
// [DONE] - simple click, one node
// 'click' - simple click, early event
// [TODO] - simple click, area
// used for area (with global: cursor_size)
// 'clickNode'- simple click, second event if one node
// one node:
// POSS easy in new sigma.js:
// add doubleClick to select node + neighboors
// when circle area select
// ========================
// 1st event, even before we know if there are nodes
TW
.
partialGraph
.
bind
(
'click'
,
function
(
e
)
{
// console.log("sigma click event e", e)
// case with a selector circle cursor handled here
if
(
cursor_size
>
0
)
{
// actual click position, but in graph coords
var
x
=
e
.
data
.
x
var
y
=
e
.
data
.
y
// convert
var
camCoords
=
TW
.
cam
.
cameraPosition
(
x
,
y
)
// retrieve area nodes, using indexed quadtree and global cursor_size
var
circleNodes
=
circleGetAreaNodes
(
camCoords
.
x
,
camCoords
.
y
)
// TODO 1) use SelectorEngine prevsels iff 'Add'
// circleNodes += prevsels
// 2) show selection + do all related effects
SelInst
.
MultipleSelection2
({
nodes
:
circleNodes
})
}
})
// when one node and normal click
// ===============================
TW
.
partialGraph
.
bind
(
'clickNode'
,
function
(
e
)
{
TW
.
partialGraph
.
bind
(
'clickNode'
,
function
(
e
)
{
console
.
log
(
"clickNode event node"
,
e
.
data
.
node
)
// console.log("clickNode event e", e.data.node)
// new sigma.js gives easy access to clicked node!
// new sigma.js gives easy access to clicked node!
theNodeId
=
e
.
data
.
node
.
id
theNodeId
=
e
.
data
.
node
.
id
cancelSelection
(
false
);
cancelSelection
(
false
);
if
(
cursor_size
==
0
)
{
if
(
cursor_size
==
0
)
{
// sigma already provided us the target
SelInst
.
MultipleSelection2
({
nodes
:[
theNodeId
]})
SelInst
.
MultipleSelection2
({
nodes
:[
theNodeId
]})
}
}
// case with a selector circle cursor
// case with a selector circle cursor handled
else
{
// just before, at click event
// cf TODO mousedown
}
})
})
// TODO re-connect area click
// -------------------------------------------fragment from v1.customized
// TW.partialGraph.bind('click', function(e) {
// FOLLOW UP in v1 customized
// console.log("===click===");
// =========
// console.log("e", e);
// (last non-reimplemented bit that was using SelectorEngine)
// })
//
// var targeted = SelInst.SelectorEngine( {
// TW.partialGraph.bind('downgraph upgraph', function(e) {
// cursorsize:cursor_size,
// console.log("===downgraph upgraph===");
// area:area,
// console.log("e", e);
// addvalue:checkBox,
// })
// clicktype:"simple",
// prevsels:selections
// } )
// --------------------------------------------fragment from v1.customized
// if(targeted.length>0) {
// TW.partialGraph.bind('mousedown mouseup', function(e) {
// cancelSelection(false);
//
// SelInst.MultipleSelection2( {nodes:targeted} )
// console.log("---------- event", e)
// }
// var targeted = self.graph.nodes.filter(function(n) {
// partialGraph.refresh({skipIndexation:true});
// return !!n['hover'];
// trackMouse(e);
// }).map(function(n) {
// return n.id;
// -------------------------------------------/fragment from v1.customized
// });
// console.log("---------- targeted by hover check loop", targeted)
// })
// for all goTo (move/zoom) events
//
// self.dispatch(
// e['type'] == 'mousedown' ?
// 'downgraph' :
// 'upgraph'
// );
//
// if (targeted.length) {
// self.dispatch(
// e['type'] == 'mousedown' ?
// 'downnodes' :
// 'upnodes',
// targeted
// );
// }
// }
//
// FOLLOW UP in v1 customized:
// ===========================
// .mousedown(function(e) { // using SelectionEngine
// //left click!<- normal click
// if(e.which==1){
// console.warn('new sigma.js FIX event bindings for downgraph, upgraph')
// partialGraph.dispatchEvent(
// e['type'] == 'mousedown' ?
// 'downgraph' :
// 'upgraph'
// );
// var area = {}
//
//
// // new sigma.js: (x,y) from event -- TODO check if convert coords
// area.x1 = sigma.utils.getX(e);
// area.y1 = sigma.utils.getY(e);
//
// // old version
// // area.x1 = partialGraph._core.mousecaptor.mouseX;
// // area.y1 = partialGraph._core.mousecaptor.mouseY;
//
// var targeted = SelInst.SelectorEngine( {
// cursorsize:cursor_size,
// area:area,
// addvalue:checkBox,
// clicktype:"simple",
// prevsels:selections
// } )
// if(targeted.length>0) {
// cancelSelection(false);
// SelInst.MultipleSelection2( {nodes:targeted} )
// }
// partialGraph.refresh({skipIndexation:true});
// trackMouse(e);
// }
// });
// -------------------------------------------/fragment from v1.customized
// goTo (move/zoom) events
var
zoomTimeoutId
=
null
var
zoomTimeoutId
=
null
TW
.
cam
.
bind
(
'coordinatesUpdated'
,
function
(
e
)
{
TW
.
cam
.
bind
(
'coordinatesUpdated'
,
function
(
e
)
{
// debounce
// debounce
...
@@ -796,12 +771,12 @@ TinaWebJS = function ( sigmacanvas ) {
...
@@ -796,12 +771,12 @@ TinaWebJS = function ( sigmacanvas ) {
}
}
// schedule next
// schedule next
zoomTimeoutId
=
window
.
setTimeout
(
zoomTimeoutId
=
window
.
setTimeout
(
// make zoom slider cursor follow scroll
function
(){
function
(){
// make zoom slider cursor follow scroll
$
(
"#zoomSlider"
).
slider
(
"value"
,
1
/
TW
.
cam
.
ratio
)
$
(
"#zoomSlider"
).
slider
(
"value"
,
1
/
TW
.
cam
.
ratio
)
// console.log('auto cursor on val', 1/TW.cam.ratio , "( ratio:", TW.cam.ratio,")" )
// console.log('auto cursor on val', 1/TW.cam.ratio , "( ratio:", TW.cam.ratio,")" )
},
},
25
0
50
0
)
)
})
})
...
@@ -810,14 +785,13 @@ TinaWebJS = function ( sigmacanvas ) {
...
@@ -810,14 +785,13 @@ TinaWebJS = function ( sigmacanvas ) {
// ==========
// ==========
$
(
"#sigma-contnr"
)
$
(
"#sigma-contnr"
)
.
mousemove
(
function
(
e
vent
){
.
mousemove
(
function
(
e
){
if
(
!
isUndef
(
partialGraph
))
{
if
(
!
isUndef
(
partialGraph
))
{
//
when
selector circle cursor
//
show/move
selector circle cursor
if
(
cursor_size
>
0
)
trackMouse
(
event
);
if
(
cursor_size
>
0
)
circleTrackMouse
(
e
);
}
}
})
})
// POSSible for the future: add tools to contextmenu
// POSSible for the future: add tools to contextmenu
// .contextmenu(function(){
// .contextmenu(function(){
// return false;
// return false;
...
@@ -941,6 +915,8 @@ TinaWebJS = function ( sigmacanvas ) {
...
@@ -941,6 +915,8 @@ TinaWebJS = function ( sigmacanvas ) {
});
});
//Cursor Size slider
//Cursor Size slider
// + reindexation when size is settled (=> updates the quadtree)
var
reindexTimeout
=
null
$
(
"#unranged-value"
).
freshslider
({
$
(
"#unranged-value"
).
freshslider
({
step
:
1
,
step
:
1
,
min
:
cursor_size_min
,
min
:
cursor_size_min
,
...
@@ -950,9 +926,21 @@ TinaWebJS = function ( sigmacanvas ) {
...
@@ -950,9 +926,21 @@ TinaWebJS = function ( sigmacanvas ) {
// console.log("en cursorsize: "+value);
// console.log("en cursorsize: "+value);
cursor_size
=
value
;
cursor_size
=
value
;
if
(
cursor_size
==
0
)
partialGraph
.
refresh
({
skipIndexation
:
true
});
if
(
cursor_size
==
0
)
partialGraph
.
refresh
({
skipIndexation
:
true
});
// have reindex ready to go for when user stops moving slider
if
(
reindexTimeout
)
{
// (debounced)
clearTimeout
(
reindexTimeout
)
reindexTimeout
=
null
}
reindexTimeout
=
setTimeout
(
function
()
{
TW
.
partialGraph
.
refresh
({
skipIndexation
:
false
})
// =====
console
.
log
(
"graph quadtree reindexed for cursor"
)
},
500
)
}
}
});
});
}
}
// finish initListeners
};
};
tinawebJS/enviroment.js
View file @
7af0b354
...
@@ -66,7 +66,7 @@ function changeType() {
...
@@ -66,7 +66,7 @@ function changeType() {
}
}
}
}
TW
.
partialGraph
.
emptyGraph
();
TW
.
partialGraph
.
graph
.
clear
();
var
nodes_2_colour
=
{}
var
nodes_2_colour
=
{}
var
edges_2_colour
=
{}
var
edges_2_colour
=
{}
...
@@ -296,7 +296,7 @@ function changeLevel() {
...
@@ -296,7 +296,7 @@ function changeLevel() {
}
}
var
str_nextState
=
nextState
.
map
(
Number
).
join
(
"|"
)
var
str_nextState
=
nextState
.
map
(
Number
).
join
(
"|"
)
TW
.
partialGraph
.
emptyGraph
();
TW
.
partialGraph
.
graph
.
clear
();
var
voisinage
=
{}
var
voisinage
=
{}
// Dictionaries of: selection+neighbors
// Dictionaries of: selection+neighbors
...
...
tinawebJS/main.js
View file @
7af0b354
...
@@ -258,8 +258,11 @@ if(RES["OK"]) {
...
@@ -258,8 +258,11 @@ if(RES["OK"]) {
});
});
// shortcuts to the renderer and camera
// shortcuts to the renderer and camera
TW
.
rend
=
TW
.
partialGraph
.
renderers
[
0
]
TW
.
cam
=
TW
.
partialGraph
.
camera
TW
.
cam
=
TW
.
partialGraph
.
camera
TW
.
rend
=
TW
.
partialGraph
.
renderers
[
0
]
// NB : camera positions are fix if the node is fixed => they only depend on layout
// renderer position depend on viewpoint/zoom (like ~ html absolute positions of the node in the div)
// useful
// useful
TW
.
partialGraph
.
nNodes
=
TW
.
partialGraph
.
graph
.
nodes
().
length
TW
.
partialGraph
.
nNodes
=
TW
.
partialGraph
.
graph
.
nodes
().
length
...
...
tinawebJS/methods.js
View file @
7af0b354
...
@@ -399,7 +399,7 @@ function LevelButtonDisable( TF ){
...
@@ -399,7 +399,7 @@ function LevelButtonDisable( TF ){
function
graphTagCloudElem
(
nodes
)
{
function
graphTagCloudElem
(
nodes
)
{
console
.
log
(
"in graphTagCloudElem, nodae_id: "
+
nodes
);
console
.
log
(
"in graphTagCloudElem, nodae_id: "
+
nodes
);
cancelSelection
();
cancelSelection
();
TW
.
partialGraph
.
emptyGraph
();
TW
.
partialGraph
.
graph
.
clear
();
var
ndsids
=
[]
var
ndsids
=
[]
...
@@ -603,7 +603,7 @@ function add1Elem(id) {
...
@@ -603,7 +603,7 @@ function add1Elem(id) {
updateSearchLabels
(
id
,
TW
.
Nodes
[
id
].
label
,
TW
.
Nodes
[
id
].
type
);
updateSearchLabels
(
id
,
TW
.
Nodes
[
id
].
label
,
TW
.
Nodes
[
id
].
type
);
nodeslength
++
;
nodeslength
++
;
}
}
TW
.
partialGraph
.
addNode
(
id
,
anode
);
TW
.
partialGraph
.
graph
.
addNode
(
anode
);
return
;
return
;
}
}
}
else
{
// It's an edge!
}
else
{
// It's an edge!
...
@@ -621,7 +621,7 @@ function add1Elem(id) {
...
@@ -621,7 +621,7 @@ function add1Elem(id) {
weight
:
TW
.
Edges
[
id
].
weight
weight
:
TW
.
Edges
[
id
].
weight
};
};
TW
.
partialGraph
.
addEdge
(
id
,
anedge
.
sourceID
,
anedge
.
targetID
,
anedge
);
TW
.
partialGraph
.
graph
.
addEdge
(
anedge
);
return
;
return
;
}
}
}
}
...
...
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