Commit 0e9a5727a56fefe33c5f591f659353f9dec1125a

Authored by Luigi Serra
1 parent 1aced18e

graph updatesù

datalets/graph-datalet/demo/demo-clustering.html
... ... @@ -3,7 +3,7 @@
3 3 <head>
4 4 <meta charset="UTF-8">
5 5 <title>Demo Graph with node clustering</title>
6   - <link rel="import" href="../graph-with-clustering-datalet.html">
  6 + <link rel="import" href="../graph-with-clustering-extend-datalet.html">
7 7 <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.js"></script>
8 8 </head>
9 9 <script>
... ... @@ -11,8 +11,8 @@
11 11 var xhttp = new XMLHttpRequest();
12 12 xhttp.onreadystatechange = function() {
13 13 if (xhttp.readyState == 4 && xhttp.status == 200) {
14   - document.getElementById("graph-placeholder").innerHTML = '<graph-with-clustering-datalet width="1000" height="700" graph=\'' + JSON.parse(xhttp.responseText).graph +
15   - '\'></graph-with-clustering-datalet>';
  14 + document.getElementById("graph-placeholder").innerHTML = '<graph-with-clustering-extend-datalet width="1000" height="700" graph=\'' + JSON.parse(xhttp.responseText).graph +
  15 + '\'></graph-with-clustering-extend-datalet>';
16 16 }
17 17 };
18 18 xhttp.open("GET", "http://192.168.164.128/public_room/ajax/get-graph?id=1&type=comments", true);
... ...
datalets/graph-datalet/graph-datalet.html
... ... @@ -328,7 +328,9 @@ Example:
328 328 },
329 329  
330 330 active : function (t) {
331   - _this.fire('graph-datalet_node-clicked', {node : t});
  331 + if(t.image) return;
  332 +
  333 + _this.fire('graph-datalet_node-clicked', {node : t});
332 334  
333 335 if(prev_selected_node != null){
334 336 prev_selected_node.style.fill = prev_selected_node.style.stroke;
... ...
datalets/graph-datalet/graph-with-clustering-datalet_.html renamed to datalets/graph-datalet/graph-with-clustering-extend-datalet.html
... ... @@ -49,7 +49,7 @@ Example:
49 49 @group datalets
50 50 -->
51 51  
52   -<dom-module id="graph-with-clustering-datalet">
  52 +<dom-module id="graph-with-clustering-extend-datalet">
53 53 <template>
54 54  
55 55 <link rel="stylesheet" href="static/css/graphStyle.css">
... ... @@ -95,7 +95,7 @@ Example:
95 95 _this = null;
96 96  
97 97 Polymer({
98   - is : 'graph-with-clustering-datalet',
  98 + is : 'graph-with-clustering-extend-datalet',
99 99  
100 100 properties: {
101 101 /**
... ... @@ -111,8 +111,8 @@ Example:
111 111 },
112 112  
113 113 svgNodes : {
114   - type : Array,
115   - value : []
  114 + type : Array,
  115 + value : []
116 116 },
117 117  
118 118 svgLinks : {
... ... @@ -158,186 +158,251 @@ Example:
158 158 value: []
159 159 },
160 160  
161   - hulls : {
162   - type: Array,
163   - value: []
164   - },
165 161 hull : {
166 162 type : Array,
167 163 value : []
  164 + },
  165 + /*test*/
  166 + hullg : {
  167 + type : Array,
  168 + value : []
  169 + },
168 170  
  171 + offset :{
  172 + type : Number,
  173 + value : 15
169 174 }
170   - },
171 175  
172   - groupPath : function(d) {
173   - return "M" +
174   - d3.geom.hull(d.values.map(function(i) { return [i.x, i.y];}))
175   - .join("L")
176   - + "Z";
  176 + /*end test*/
177 177 },
178 178  
179   - groupFill : function(d, i) {
180   - var fill = d3.scale.category10();
181   - return fill(i & 3);
182   - },
  179 + convexHulls : function() {
  180 + var hullset = [];
  181 + /*for(var i in _this.groups){
  182 + for(var j=0; j < _this.groups[i].length && _this.groups[i].extend;j++){
  183 + var vertices = [];
  184 + for(var v=0;v < _this.groups[i][j].values.length; v++){
  185 + vertices.push([_this.groups[i][j].values[v].x - _this.offset, _this.groups[i][j].values[v].y - _this.offset]);
  186 + vertices.push([_this.groups[i][j].values[v].x - _this.offset, _this.groups[i][j].values[v].y + _this.offset]);
  187 + vertices.push([_this.groups[i][j].values[v].x + _this.offset, _this.groups[i][j].values[v].y - _this.offset]);
  188 + vertices.push([_this.groups[i][j].values[v].x + _this.offset, _this.groups[i][j].values[v].y + _this.offset]);
  189 + }
183 190  
184   - createHulls : function(nodes){
185   - this.svg.selectAll("path")
186   - .data(nodes)
187   - .attr("d", this.groupPath)
188   - .enter().insert("path", "g")
189   - //.style("fill", _this.groupFill)
190   - .style("fill", "#60df20")
191   - //.style("stroke", _this.groupFill)
192   - .style("stroke", "#60df20")
193   - .style("stroke-width", 30)
194   - .style("stroke-linejoin", "round")
195   - .style("opacity", .2)
196   - .attr("d", this.groupPath);
  191 + hullset.push({id : parseInt(i) + 3, sentiment: j , path: d3.geom.hull(vertices), extend : _this.groups[i][j].extend});
  192 + }
  193 + }*/
  194 + for(var n in _this.hulls){
  195 + var vertices = [];
  196 + for(var v in _this.hulls[n]){
  197 + vertices.push([_this.hulls[n][v].x - _this.offset, _this.hulls[n][v].y - _this.offset]);
  198 + vertices.push([_this.hulls[n][v].x - _this.offset, _this.hulls[n][v].y + _this.offset]);
  199 + vertices.push([_this.hulls[n][v].x + _this.offset, _this.hulls[n][v].y - _this.offset]);
  200 + vertices.push([_this.hulls[n][v].x + _this.offset, _this.hulls[n][v].y + _this.offset]);
  201 + }
  202 + hullset.push({/*id : parseInt(i) + 3,*/ sentiment: _this.hulls[n][v].sentiment , path: d3.geom.hull(vertices), extend : true});
  203 + }
  204 + return hullset;
197 205 },
198 206  
199   - getNetwork : function(){
200   -
201   - var nodes = [], links = [], prevLevel = 1, prevGroupIndex = 1;
  207 + fill : function(d){
  208 + switch(((d - 1) % 3)){
  209 + case 0 :
  210 + return "#1F77B4";
  211 + case 1 :
  212 + return "#2CA02C";
  213 + case 2:
  214 + return "#FF1E1E";
  215 + }
  216 + },
202 217  
203   - //for(var i=0; i < 27; i++) groups.push({key : "" + i , values : []});
  218 + drawCluster : function(d) {
  219 + var curve = d3.svg.line()
  220 + .interpolate("cardinal-closed")
  221 + .tension(.85);
204 222  
205   - //nodes.push(this.graph.nodes[0])
  223 + return curve(d.path); // 0.8
  224 + },
206 225  
  226 + getGroups : function(){
207 227 for(var i= 0,j=0; i < this.graph.nodes.length;i++,j+=3){
208   - var node = this.graph.nodes[i];
209   - var l = node.level;
210   - var sentiment = node.sentiment;
211   - var id = node.id;
212   - var father = node.father;
213   -
214   - this.groups.push([{key : "" + j, values : []}, {key : "" + (j + 1), values : []}, {key : "" + (j + 2), values : []}]);
215   - if(this.graph.nodes[i].father != null){
216   - switch (parseInt(this.graph.nodes[i].sentiment)){
217   - case 1:
218   - this.groups[this.graph.nodes[i].father.id][0].values.push(this.graph.nodes[i]);
219   - break;
220   - case 2:
221   - this.groups[this.graph.nodes[i].father.id][1].values.push(this.graph.nodes[i]);
222   - break;
223   - case 3:
224   - this.groups[this.graph.nodes[i].father.id][2].values.push(this.graph.nodes[i]);
225   - break;
226   - }
227   - }
228 228  
229   - /*var node = this.graph.nodes[i];
230   - var l = node.level;
231   - var sentiment = node.sentiment;
232   - var id = node.id;
  229 + var f = this.graph.nodes[i].father;
  230 + if(f != null) {
  231 + while (f.sentiment == this.graph.nodes[i].sentiment) f = f.father;
  232 + }
233 233  
234   - var gi = (((this.graph.nodes[i].level - 1) * 3) + parseInt(this.graph.nodes[i].sentiment));
235   - groups[gi].values.push(node);*/
  234 + if(f != null){
  235 + if(this.groups[f.id] == undefined){
  236 + this.groups[f.id] = ([
  237 + {key: "" + j, values: [], extend: false},
  238 + {key: "" + (j + 1), values: [],extend: false},
  239 + {key: "" + (j + 2), values: [], extend: false}
  240 + ]);
  241 + }
  242 + this.graph.nodes[i].group = f.id;
  243 + this.groups[f.id][parseInt(this.graph.nodes[i].sentiment) - 1].values.push(this.graph.nodes[i]);
236 244  
  245 + }else{
  246 + this.graph.nodes[i].group = -1;
  247 + }
237 248 }
  249 + },
  250 +
  251 + getNetwork : function(){
  252 + var nodes = [], links = [];
  253 + var nodesMap = [];
  254 +
  255 + //Associate the root to first node
  256 + var root = ({
  257 + id: 0,
  258 + group: -1,
  259 + r: 30,
  260 + });
  261 + nodes.push(root);
  262 + nodesMap[-1] = root;
  263 + nodesMap[0] = root;
238 264  
239 265 this.hulls = [];
240   - var index = 0;
241   - for(var i=0; i < _this.groups.length; i++){
242   - for(var j=0; j < _this.groups[i].length;j++){
243   - if(_this.groups[i][j].values.length != 0) {
244   - if(_this.groups[i][j].values.length > 0){
245   - _this.groups[i][j].key = "" + index;
246   - index++;
247   - this.hulls.push(_this.groups[i][j]);
  266 + for(var g in this.groups){
  267 + for(var s in this.groups[g]) {
  268 + if(this.groups[g][s].values.length > 0) {
  269 + if(this.groups[g][s].extend){
  270 + this.hulls[g + "-" + s] = [];
  271 + for(var n=0; n < this.groups[g][s].values.length;n++) {
  272 + var node = ({
  273 + id: g + "-" + s + "-" + n,
  274 + group: g + "-" + s,
  275 + sentiment: parseInt(s) + 1,
  276 + r: 3,
  277 + });
  278 + nodes.push(node);
  279 + nodesMap[this.groups[g][s].values[n].id] = node;
  280 + this.hulls[g + "-" + s].push(node);
  281 + }
  282 + }else{
  283 + var node = ({
  284 + id : g + "-"+ s,
  285 + group: g,
  286 + sentiment: parseInt(s) + 1,
  287 + nodes: this.groups[g][s].values,
  288 + r: this.groups[g][s].values.length * 3,
  289 + extend: false
  290 + });
  291 +
  292 + nodes.push(node);
  293 +
  294 + for(var n=0; n < this.groups[g][s].values.length;n++)
  295 + nodesMap[this.groups[g][s].values[n].id] = node;
248 296 }
  297 +
  298 + //root.r +=(this.groups[g][s].values.length * 3);
249 299 }
250 300 }
251 301 }
252   - },
253 302  
254   - /*TEST*/
255   - convexHulls : function(nodes, index, offset) {
256   - var hulls = {};
257   -
258   - // create point sets
259   - for (var k=0; k<nodes.length; ++k) {
260   - var n = nodes[k];
261   - if (n.size) continue;
262   - var i = index(n),
263   - l = hulls[i] || (hulls[i] = []);
264   - l.push([n.x-offset, n.y-offset]);
265   - l.push([n.x-offset, n.y+offset]);
266   - l.push([n.x+offset, n.y-offset]);
267   - l.push([n.x+offset, n.y+offset]);
  303 + for(var e = 0; e < this.graph.links.length; e++){
  304 + if(this.graph.nodes[this.graph.links[e].source.id].group != this.graph.nodes[this.graph.links[e].target.id].group) {
  305 + var id = nodesMap[this.graph.links[e].source.id].id + "-" + nodesMap[this.graph.links[e].target.id].id;
  306 + var link = this.findLink(links, id);
  307 + if(link != null)
  308 + link.size += 3;
  309 + else
  310 + links.push({
  311 + id: id,
  312 + source: nodesMap[this.graph.links[e].source.id],
  313 + target: nodesMap[this.graph.links[e].target.id],
  314 + value: 120,
  315 + size : 1
  316 + });
  317 + }else{
  318 + links.push({
  319 + id: id,
  320 + source: nodesMap[this.graph.links[e].source.father.id],
  321 + target: nodesMap[this.graph.links[e].target.id],
  322 + value: 120,
  323 + size : 1
  324 + });
  325 + }
268 326 }
269 327  
270   - // create convex hulls
271   - var hullset = [];
272   - for (i in hulls) {
273   - hullset.push({group: i, path: d3.geom.hull(hulls[i])});
274   - }
275   - return hullset;
276   - },
  328 + return {nodes : nodes, links : links};
  329 + //return {nodes : this.graph.nodes, links : this.graph.links};
277 330  
278   - drawCluster : function(d) {
279   - return this.curve(d.path); // 0.8
280 331 },
281 332  
282   - curve : function(d){
283   - var curve = d3.svg.line()
284   - .interpolate("cardinal-closed")
285   - .tension(.85);
286   - return curve(d);
  333 + findLink : function(links, id){
  334 + for(var i=0; i<links.length;i++){
  335 + if(links[i].id == id) return links[i];
  336 + }
  337 + return null;
  338 +
  339 +
287 340 },
288   - /*END TEST*/
289 341  
290 342 init : function(){
291 343  
292   - this.getNetwork();
  344 + var net = this.getNetwork();
293 345  
294 346 if(this.force != null) this.force.stop();
295 347 force = d3.layout.force()
296   - .nodes(this.graph.nodes)
297   - .links(this.graph.links)
298   - .size([this.width, this.height])
299   - .charge(-1e3)
300   - .friction(.7)
301   - .linkDistance(function (t){ return t.value ? t.value : 80})
302   - .on("tick", this.tick).start();
303   -
304   - _this.svg.selectAll("path").remove();
305   - _this.hull = _this.svg.append("path")
306   - .style("fill", "#60df20")
307   - .style("stroke", "#60df20")
308   - .style("stroke-width", 30)
  348 + .nodes(net.nodes)
  349 + .links(net.links)
  350 + .size([this.width, this.height])
  351 + .charge(-1e3)
  352 + .friction(.7)
  353 + .linkDistance(function (t){ return t.value ? t.value : 80})
  354 + .on("tick", this.tick).start();
  355 +
  356 + this.hullg.selectAll("path.hull").remove();
  357 + this.hull = this.hullg.selectAll("path.hull")
  358 + .data(this.convexHulls)
  359 + .enter().append("path")
309 360 .attr("class", "hull")
310   - .style("stroke-linejoin", "round")
311   - .style("opacity", .2);
312   -
  361 + .attr("d", this.drawCluster)
  362 + .style("fill", "#60df20")
  363 + .style("opacity", .2)
  364 + .on("click", function(d) {
  365 + alert(d.id);
  366 + });
313 367  
314   - this.svg.selectAll(".link").data(this.graph.links).remove();
315   - this.svgLinks = this.svg.selectAll(".link").data(this.graph.links).enter()
  368 +
  369 + this.svg.selectAll(".link").data(net.links).remove();
  370 + this.svgLinks = this.svg.selectAll(".link").data(net.links).enter()
316 371 .append("line")
317 372 .attr("class", "link")
318   - /* .attr("x1", function(d) { return d.source.x; })
319   - .attr("y1", function(d) { return d.source.y; })
320   - .attr("x2", function(d) { return d.target.x; })
321   - .attr("y2", function(d) { return d.target.y; })*/
322   - .attr("style", function(t){ return "stroke:" + t.color })
323   - .style("stroke-width", function(d) { return d.size || 1; });
324   -
325   - this.svg.selectAll(".node").data(this.graph.nodes).remove();
326   - this.svgNodes = this.svg.selectAll(".node").data(this.graph.nodes).enter()
  373 + .attr("style", function(t){ return "stroke:#333"; /*+ t.color*/ })
  374 + .style("stroke-width", function(d) { return d.size || 0.3; });
  375 +
  376 + this.svg.selectAll(".node").data(net.nodes).remove();
  377 + this.svgNodes = this.svg.selectAll(".node").data(net.nodes).enter()
327 378 .append("g")
328 379 .on("mouseover", this.mouseover)
329 380 .on("mouseout", this.mouseout)
330 381 .attr("class", function (t) { return t.fixed ? "node fixed" : "node"})
331 382 .attr("name", function (t) { return t.name ? t.name.split(" ").join("_").toLowerCase() : ""})
332 383 .append("circle")
333   - .on("click", this.active)
334   - .attr("id", function(t){ return t.id })
335   - .attr("class", function (t) { return t.fixed ? "" : "drag"})
336   - .attr("r", function (t){ return t.r ? t.r : 15 })
337   - .attr("style", function (t) { return t.color ? "fill:" + t.color : !1 + "; stroke:white"})
338   - .attr("filter", function(t){return t.image ? 'url(#filter1)' : ""});
339   -
340   - //d3.selectAll(".drag").call(force.drag), this.svg.selectAll("g.node").call(this.text);
  384 + .on("click", this.active)
  385 + .attr("id", function(t){ return t.id })
  386 + .attr("class", function (t) { return t.fixed ? "" : "drag"})
  387 + .attr("r", function (t){ return t.r ? t.r : 15 })
  388 + .attr("style", function (t) {
  389 + switch(parseInt(t.sentiment)){
  390 + case 1 :
  391 + t.color = "#1F77B4";
  392 + break;
  393 + case 2 :
  394 + t.color = "#2CA02C";
  395 + break;
  396 + case 3:
  397 + t.color = "#D62728";
  398 + break;
  399 + default:
  400 + t.color = "#333";
  401 + }
  402 + //return t.color ? "fill:" + t.color : !1 + "; stroke:white"
  403 + return "fill:" + t.color + "; stroke:white"
  404 + })
  405 + .attr("filter", function(t){return t.image ? 'url(#filter1)' : ""});
341 406  
342 407 this.svg.style("opacity", 1e-6)
343 408 .transition()
... ... @@ -355,7 +420,6 @@ Example:
355 420  
356 421 //set initial zoom
357 422 scale = (1.0);
358   - //translate = [(width-scale*width)/2, ((height-scale*height)/4)];
359 423 translate = [0, 0];
360 424 this.svg.transition()
361 425 .duration(750)
... ... @@ -382,6 +446,15 @@ Example:
382 446 .append("feImage")
383 447 .attr("xlink:href","http://icons.iconarchive.com/icons/hopstarter/soft-scraps/256/User-Executive-Green-icon.png");
384 448  
  449 + for (var i = 0; i < this.graph.links.length; ++i) {
  450 + o = this.graph.links[i];
  451 + o.source = this.graph.nodes[o.source];
  452 + o.target = this.graph.nodes[o.target];
  453 + }
  454 +
  455 + this.hullg = this.svg.append("g");
  456 +
  457 + this.getGroups();
385 458 this.init();
386 459 },
387 460  
... ... @@ -400,57 +473,55 @@ Example:
400 473 },
401 474  
402 475 tick : function () {
403   - // d3.select("svg").attr("style", "transform:translate(8%)");
404   - d3.selectAll("g foreignObject").attr("x", function (t) {
405   - return t.x + (t.r ? 0.8 * t.r : 15)
406   - }).attr("y", function (t) {
407   - return t.y - 20
408   - });
409   -
410   - d3.selectAll("#logo text").attr("x", function (t) {
411   - return t.x + .7 * (t.r ? t.r : 15)
412   - }).attr("y", function (t) {
413   - return t.y
414   - });
415   -
416   - _this.svgNodes.attr("cx", function (t) {
417   - return t.x = Math.max(25, Math.min(_this.width - 50, t.x))
418   - }).attr("cy", function (t) {
419   - return t.y = Math.max(8, Math.min(600, t.y))
420   - });
421   -
422   - _this.svgLinks.attr("x1", function (t) {
423   - return t.source.x
424   - }).attr("y1", function (t) {
425   - return t.source.y
426   - }).attr("x2", function (t) {
427   - return t.target.x
428   - }).attr("y2", function (t) {
429   - return t.target.y
430   - });
431   -
432   - //create hulls
433   - //var n = [{key : "0", values : [ _this.graph.nodes[14], _this.graph.nodes[15], _this.graph.nodes[16],_this.graph.nodes[17], _this.graph.nodes[18]]}];
  476 + if(_this.hull != undefined) {
  477 + if (!_this.hull.empty()) {
  478 + _this.hull.data(_this.convexHulls)
  479 + .style("fill", function (d) {
  480 + return _this.fill(d.sentiment);
  481 + })
  482 + .attr("d", _this.drawCluster);
  483 + }
434 484  
435   - //_this.createHulls([_this.hulls[2]]);
436   - //_this.createHulls(_this.hulls);
437 485  
438   - var vertices = [];
439   - for(var i=0; i < _this.groups[0][0].values.length;i++){
440   - vertices.push([_this.groups[0][0].values[i].x, _this.groups[0][0].values[i].y]);
  486 + d3.selectAll("g foreignObject").attr("x", function (t) {
  487 + return t.x + (t.r ? 0.8 * t.r : 15)
  488 + }).attr("y", function (t) {
  489 + return t.y - 20
  490 + });
  491 +
  492 + d3.selectAll("#logo text").attr("x", function (t) {
  493 + return t.x + .7 * (t.r ? t.r : 15)
  494 + }).attr("y", function (t) {
  495 + return t.y
  496 + });
  497 +
  498 + _this.svgNodes.attr("cx", function (t) {
  499 + return t.x = Math.max(25, Math.min(_this.width - 50, t.x))
  500 + }).attr("cy", function (t) {
  501 + return t.y = Math.max(8, Math.min(600, t.y))
  502 + });
  503 +
  504 + _this.svgLinks.attr("x1", function (t) {
  505 + return t.source.x
  506 + }).attr("y1", function (t) {
  507 + return t.source.y
  508 + }).attr("x2", function (t) {
  509 + return t.target.x
  510 + }).attr("y2", function (t) {
  511 + return t.target.y
  512 + });
441 513 }
442   - _this.hull.datum(d3.geom.hull(vertices)).attr("d", function(d) { return "M" + d.join("L") + "Z"; });
  514 +
443 515 },
444 516  
445 517 mouseover : function (t) {
446 518 d3.select(this).selectAll("circle").transition().duration(600).ease("elastic").attr("r", function (t) {
447   - //return 1 == t.fixed ? 1.4 * t.r : 15
448 519 return 1 == t.fixed ? 1.4 * t.r : t.r + 10;
449 520 });
450 521  
451 522 _this.$.dialog.close();
452 523 _this.$.dialog_title.innerHTML = t.name;
453   - _this.$.dialog_content.innerHTML = t.content;
  524 + _this.$.dialog_content.innerHTML = t.nodes ? t.nodes.length : 1;
454 525  
455 526 _this.$.dialog.open();
456 527 },
... ... @@ -464,23 +535,24 @@ Example:
464 535  
465 536 active : function (t) {
466 537  
467   - _this.init();
468   - _this.fire('graph-datalet_node-clicked', {node : t});
  538 + if(t.extend == undefined)
  539 + {
  540 + _this.init();
  541 + _this.fire('graph-datalet_node-clicked', {node : t});
469 542  
470   - if(_this.prev_selected_node != null){
471   - _this.prev_selected_node.style.fill = _this.prev_selected_node.style.stroke;
472   - _this.prev_selected_node.style.stroke = "#FFFFFF";
473   - }
474   -
475   - _this.prev_selected_node = document.getElementById("" + t.id);
476   - _this.prev_selected_node.style.fill = "#FFFFFF"
477   - _this.prev_selected_node.style.stroke = t.color;
478   -
479   - /* _this.$.dialog.close();
480   - _this.$.dialog_title.innerHTML = t.name;
481   - _this.$.dialog_content.innerHTML = t.content;
  543 + if(_this.prev_selected_node != null){
  544 + _this.prev_selected_node.style.fill = _this.prev_selected_node.style.stroke;
  545 + _this.prev_selected_node.style.stroke = "#FFFFFF";
  546 + }
482 547  
483   - _this.$.dialog.open();*/
  548 + _this.prev_selected_node = document.getElementById("" + t.id);
  549 + _this.prev_selected_node.style.fill = "#FFFFFF"
  550 + _this.prev_selected_node.style.stroke = t.color;
  551 + }else{
  552 + var gids = t.id.split("-");
  553 + _this.groups[gids[0]][gids[1]].extend = true;
  554 + _this.init();
  555 + }
484 556 },
485 557  
486 558 _onCloseClick : function(){
... ... @@ -505,9 +577,9 @@ Example:
505 577 width: "100%",
506 578 height: "100%"
507 579 }).attr("viewBox", "0 0 " + this.width + " " + this.height)
508   - .attr("pointer-events", "all")
  580 + .attr("pointer-events", "all")
509 581 .attr("style", "transform:translate(0px)")
510   - .style("position", "absolute");
  582 + .style("position", "absolute");
511 583  
512 584 this.buildGraph();
513 585 }
... ...