forked from cytoscape/cytoscape.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjquery.cytoscapeweb.layout.grid.js
135 lines (104 loc) · 3.3 KB
/
jquery.cytoscapeweb.layout.grid.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
$(function(){
var defaults = {
};
function GridLayout(options){
$.cytoscapeweb("debug", "Creating grid layout with options (%o)", options);
this.options = $.extend({}, defaults, options);
}
GridLayout.prototype.run = function(params){
var nodes = params.nodes;
var edges = params.edges;
var renderer = params.renderer;
var options = this.options;
var container = $(options.selector);
$.cytoscapeweb("debug", "Running grid layout with options (%o)", params);
var width = container.width();
var height = container.height();
$.cytoscapeweb("debug", "Running grid layout on container of size (w, h) = (%i, %i) with %i nodes", width, height, nodes.size());
if( height == 0 || width == 0){
$.cytoscapeweb("warn", "Running grid layout on container of size 0");
nodes.positions(function(){
return { x: 0, y: 0 };
});
return;
}
// width/height * splits^2 = cells where splits is number of times to split width
var cells = nodes.size();
var splits = Math.sqrt( cells * height/width );
var rows = Math.round( splits );
var cols = Math.round( width/height * splits );
$.cytoscapeweb("debug", "Grid layout decided on initial (cols, rows) = (%i, %i)", cols, rows);
function small(val){
if( val == undefined ){
return Math.min(rows, cols);
} else {
var min = Math.min(rows, cols);
if( min == rows ){
rows = val;
$.cytoscapeweb("debug", "Grid layout set small number of rows to %i", rows);
} else {
cols = val;
$.cytoscapeweb("debug", "Grid layout set small number of columns to %i", cols);
}
}
}
function large(val){
if( val == undefined ){
return Math.max(rows, cols);
} else {
var max = Math.max(rows, cols);
if( max == rows ){
rows = val;
$.cytoscapeweb("debug", "Grid layout set large number of rows to %i", rows);
} else {
cols = val;
$.cytoscapeweb("debug", "Grid layout set large number of columns to %i", cols);
}
}
}
// if rounding was up, see if we can reduce rows or columns
if( cols * rows > cells ){
var sm = small();
var lg = large();
$.cytoscapeweb("debug", "Grid layout is looking to make a reduction");
// reducing the small side takes away the most cells, so try it first
if( (sm - 1) * lg >= cells ){
small(sm - 1);
} else if( (lg - 1) * sm >= cells ){
large(lg - 1);
}
} else {
$.cytoscapeweb("debug", "Grid layout is looking to make an increase");
// if rounding was too low, add rows or columns
while( cols * rows < cells ){
var sm = small();
var lg = large();
// try to add to larger side first (adds less in multiplication)
if( (lg + 1) * sm >= cells ){
large(lg + 1);
} else {
small(sm + 1);
}
}
}
$.cytoscapeweb("debug", "Grid layout split area into cells (cols, rows) = (%i, %i)", cols, rows);
var cellWidth = width / cols;
var cellHeight = height / rows;
var row = 0;
var col = 0;
nodes.positions(function(i, element){
if( element.locked() ){
return false;
}
var x = col * cellWidth + cellWidth/2;
var y = row * cellHeight + cellHeight/2;
col++;
if( col >= cols ){
col = 0;
row++;
}
return { x: x, y: y };
});
};
$.cytoscapeweb("layout", "grid", GridLayout);
});