From f0b7d3d32bc9794868d0d6dc568c4eba380fd172 Mon Sep 17 00:00:00 2001 From: Raibaz Date: Fri, 18 May 2012 15:46:10 +0200 Subject: [PATCH 1/4] Added a new node property, 'shape', that allows to draw square nodes by setting it to 'square' Added triangle and star shapes. Added missing semicolons, and filtered for in loops. --- src/core/graph.js | 195 +++++++++++++++++++++------------------- src/core/monitor.js | 8 +- src/core/plotter.js | 142 ++++++++++++++++++++++++----- src/core/sigma.js | 6 +- src/core/sigmapublic.js | 2 +- src/intro.js | 2 +- src/public/chronos.js | 14 +-- src/public/debug.js | 10 ++- 8 files changed, 251 insertions(+), 128 deletions(-) diff --git a/src/core/graph.js b/src/core/graph.js index c0d575571..bc7c24d84 100644 --- a/src/core/graph.js +++ b/src/core/graph.js @@ -68,6 +68,7 @@ function Graph() { 'hidden': false, 'forceLabel': false, // Strings : + 'shape': 'circle', 'label': id.toString(), 'id': id.toString(), // Custom attributes : @@ -75,26 +76,29 @@ function Graph() { }; for (var k in params) { - switch (k) { - case 'id': - break; - case 'x': - case 'y': - case 'size': - n[k] = +params[k]; - break; - case 'fixed': - case 'active': - case 'hidden': - case 'forceLabel': - n[k] = !!params[k]; - break; - case 'color': - case 'label': - n[k] = params[k]; - break; - default: - n['attr'][k] = params[k]; + if (params.hasOwnProperty(k)) { + switch (k) { + case 'id': + break; + case 'x': + case 'y': + case 'size': + n[k] = +params[k]; + break; + case 'fixed': + case 'active': + case 'hidden': + case 'forceLabel': + n[k] = !!params[k]; + break; + case 'color': + case 'label': + case 'shape': + n[k] = params[k]; + break; + default: + n['attr'][k] = params[k]; + } } } @@ -143,33 +147,36 @@ function Graph() { */ function checkNode(node, copy) { for (var k in copy) { - switch (k) { - case 'id': - case 'attr': - case 'degree': - case 'inDegree': - case 'outDegree': - case 'displayX': - case 'displayY': - case 'displaySize': - break; - case 'x': - case 'y': - case 'size': - node[k] = +copy[k]; - break; - case 'fixed': - case 'active': - case 'hidden': - case 'forceLabel': - node[k] = !!copy[k]; - break; - case 'color': - case 'label': - node[k] = (copy[k] || '').toString(); - break; - default: - node['attr'][k] = copy[k]; + if (copy.hasOwnProperty(k)) { + switch (k) { + case 'id': + case 'attr': + case 'degree': + case 'inDegree': + case 'outDegree': + case 'displayX': + case 'displayY': + case 'displaySize': + break; + case 'x': + case 'y': + case 'size': + node[k] = +copy[k]; + break; + case 'fixed': + case 'active': + case 'hidden': + case 'forceLabel': + node[k] = !!copy[k]; + break; + case 'color': + case 'label': + case 'shape': + node[k] = (copy[k] || '').toString(); + break; + default: + node['attr'][k] = copy[k]; + } } } @@ -272,29 +279,31 @@ function Graph() { e['target']['inDegree']++; for (var k in params) { - switch (k) { - case 'id': - case 'source': - case 'target': - break; - case 'hidden': - e[k] = !!params[k]; - break; - case 'size': - case 'weight': - e[k] = +params[k]; - break; - case 'color': - e[k] = params[k].toString(); - break; - case 'type': - e[k] = params[k].toString(); - break; - case 'label': - e[k] = params[k]; - break; - default: - e['attr'][k] = params[k]; + if (params.hasOwnProperty(k)) { + switch (k) { + case 'id': + case 'source': + case 'target': + break; + case 'hidden': + e[k] = !!params[k]; + break; + case 'size': + case 'weight': + e[k] = +params[k]; + break; + case 'color': + e[k] = params[k].toString(); + break; + case 'type': + e[k] = params[k].toString(); + break; + case 'label': + e[k] = params[k]; + break; + default: + e['attr'][k] = params[k]; + } } } @@ -337,28 +346,30 @@ function Graph() { */ function checkEdge(edge, copy) { for (var k in copy) { - switch (k) { - case 'id': - case 'displaySize': - break; - case 'weight': - case 'size': - edge[k] = +copy[k]; - break; - case 'source': - case 'target': - edge[k] = self.nodesIndex[k] || edge[k]; - break; - case 'hidden': - edge[k] = !!copy[k]; - break; - case 'color': - case 'label': - case 'type': - edge[k] = (copy[k] || '').toString(); - break; - default: - edge['attr'][k] = copy[k]; + if (copy.hasOwnProperty(k)) { + switch (k) { + case 'id': + case 'displaySize': + break; + case 'weight': + case 'size': + edge[k] = +copy[k]; + break; + case 'source': + case 'target': + edge[k] = self.nodesIndex[k] || edge[k]; + break; + case 'hidden': + edge[k] = !!copy[k]; + break; + case 'color': + case 'label': + case 'type': + edge[k] = (copy[k] || '').toString(); + break; + default: + edge['attr'][k] = copy[k]; + } } } diff --git a/src/core/monitor.js b/src/core/monitor.js index 134506de4..0fa946cc8 100644 --- a/src/core/monitor.js +++ b/src/core/monitor.js @@ -92,12 +92,16 @@ function Monitor(instance, dom) { s += '

GLOBAL :

'; for (var k in self.p.globalProbes) { - s += '

' + k + ' : ' + self.p.globalProbes[k]() + '

'; + if (self.p.globalProbes.hasOwnProperty(k)) { + s += '

' + k + ' : ' + self.p.globalProbes[k]() + '

'; + } } s += '

LOCAL :

'; for (var k in self.p.localProbes) { - s += '

' + k + ' : ' + self.p.localProbes[k]() + '

'; + if (self.p.localProbes.hasOwnproperty(k)) { + s += '

' + k + ' : ' + self.p.localProbes[k]() + '

'; + } } self.p.dom.innerHTML = s; diff --git a/src/core/plotter.js b/src/core/plotter.js index c86c94218..f6b358a7e 100644 --- a/src/core/plotter.js +++ b/src/core/plotter.js @@ -104,6 +104,7 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { // NODES: // ------ defaultNodeColor: '#aaa', + defaultNodeShape: 'circle', // HOVER: // Node hover color: // - 'node' @@ -278,16 +279,48 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { */ function drawNode(node) { var size = Math.round(node['displaySize'] * 10) / 10; + var shape = node['shape']; var ctx = nodesCtx; ctx.fillStyle = node['color']; ctx.beginPath(); - ctx.arc(node['displayX'], - node['displayY'], - size, - 0, - Math.PI * 2, - true); + switch(shape) { + case 'square': + var radius = Math.sqrt(Math.PI) * size / 2; + ctx.fillRect(node['displayX'] - radius, + node['displayY'] - radius, + radius, + radius); + break; + case 'triangle': + var radius = Math.sqrt(2 * Math.PI) * size / 2; + ctx.moveTo(node['displayX'] - radius, node['displayY'] - radius); + ctx.lineTo(node['displayX'] + radius, node['displayY'] - radius); + ctx.lineTo(node['displayX'], node['displayY'] + radius); + ctx.lineTo(node['displayX'] - radius, node['displayY'] - radius); + break; + case 'star': + var numPoints = 5; + var outerRadius = Math.sqrt(Math.PI) * size; + var innerRadius = outerRadius / 2; + ctx.moveTo(node['displayX'], node['displayY'] - outerRadius); + for (var i = 1; i < numPoints * 2; i++) { + var r = innerRadius; + if (i % 2 === 1) { + r = outerRadius; + } + var dx = r * Math.sin(i * Math.PI / numPoints); + var dy = - r * Math.cos(i * Math.PI / numPoints); + ctx.lineTo(node['displayX'] + dx, node['displayY'] + dy); + } + break; + default: + ctx.arc(node['displayX'], + node['displayY'], + size, + 0, + Math.PI * 2, + true); ctx.closePath(); ctx.fill(); @@ -389,6 +422,9 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { function drawHoverNode(node) { var ctx = hoverCtx; + var shape = node['shape']; + var size = node['size']; + var fontSize = self.p.labelSize == 'fixed' ? self.p.defaultLabelSize : self.p.labelSizeRatio * node['displaySize']; @@ -434,12 +470,44 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { ctx.fillStyle = self.p.nodeBorderColor == 'node' ? (node['color'] || self.p.defaultNodeColor) : self.p.defaultNodeBorderColor; - ctx.arc(Math.round(node['displayX']), - Math.round(node['displayY']), - node['displaySize'] + self.p.borderSize, - 0, - Math.PI * 2, - true); + switch(shape) { + case 'square': + var radius = Math.sqrt(Math.PI) * size / 2 + self.p.borderSize; + ctx.strokeRect(node['displayX'] - radius, + node['displayY'] - radius, + radius, + radius); + break; + case 'triangle': + var radius = Math.sqrt(2 * Math.PI) * size / 2 + self.p.borderSize; + ctx.moveTo(node['displayX'] - radius, node['displayY'] - radius); + ctx.lineTo(node['displayX'] + radius, node['displayY'] - radius); + ctx.lineTo(node['displayX'], node['displayY'] + radius); + ctx.lineTo(node['displayX'] - radius, node['displayY'] - radius); + break; + case 'star': + var numPoints = 5; + var outerRadius = Math.sqrt(Math.PI) * size; + var innerRadius = outerRadius / 2; + ctx.moveTo(node['displayX'], node['displayY'] - outerRadius - self.p.borderSize); + for (var i = 1; i < numPoints * 2; i++) { + var r = innerRadius + self.p.borderSize; + if (i % 2 === 1) { + r = outerRadius + self.p.borderSize; + } + var dx = r * Math.sin(i * Math.PI / numPoints); + var dy = - r * Math.cos(i * Math.PI / numPoints); + ctx.lineTo(node['displayX'] + dx, node['displayY'] + dy); + } + break; + default: + ctx.arc(node['displayX'], + node['displayY'], + size + self.p.borderSize, + 0, + Math.PI * 2, + true); + } ctx.closePath(); ctx.fill(); @@ -448,12 +516,44 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { ctx.fillStyle = self.p.nodeHoverColor == 'node' ? (node['color'] || self.p.defaultNodeColor) : self.p.defaultNodeHoverColor; - ctx.arc(Math.round(node['displayX']), - Math.round(node['displayY']), - node['displaySize'], - 0, - Math.PI * 2, - true); + switch(shape) { + case 'square': + var radius = Math.sqrt(Math.PI) * size / 2; + ctx.fillRect(node['displayX'] - radius, + node['displayY'] - radius, + radius, + radius); + break; + case 'triangle': + var radius = Math.sqrt(2 * Math.PI) * size / 2; + ctx.moveTo(node['displayX'] - radius, node['displayY'] - radius); + ctx.lineTo(node['displayX'] + radius, node['displayY'] - radius); + ctx.lineTo(node['displayX'], node['displayY'] + radius); + ctx.lineTo(node['displayX'] - radius, node['displayY'] - radius); + break; + case 'star': + var numPoints = 5; + var outerRadius = Math.sqrt(Math.PI) * size; + var innerRadius = outerRadius / 2; + ctx.moveTo(node['displayX'], node['displayY'] - outerRadius); + for (var i = 1; i < numPoints * 2; i++) { + var r = innerRadius; + if (i % 2 === 1) { + r = outerRadius; + } + var dx = r * Math.sin(i * Math.PI / numPoints); + var dy = - r * Math.cos(i * Math.PI / numPoints); + ctx.lineTo(node['displayX'] + dx, node['displayY'] + dy); + } + break; + default: + ctx.arc(node['displayX'], + node['displayY'], + size, + 0, + Math.PI * 2, + true); + } ctx.closePath(); ctx.fill(); @@ -463,9 +563,9 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { (node['color'] || self.p.defaultNodeColor) : self.p.defaultLabelHoverColor; ctx.fillText( - node['label'], - Math.round(node['displayX'] + node['displaySize'] * 1.5), - Math.round(node['displayY'] + fontSize / 2 - 3) + node['label'], + Math.round(node['displayX'] + size * 1.5), + Math.round(node['displayY'] + fontSize / 2 - 3) ); return self; diff --git a/src/core/sigma.js b/src/core/sigma.js index 93f81a335..bf5b30352 100644 --- a/src/core/sigma.js +++ b/src/core/sigma.js @@ -200,8 +200,10 @@ function Sigma(root, id) { if (oldW != self.width || oldH != self.height) { for (var k in self.domElements) { - self.domElements[k].setAttribute('width', self.width + 'px'); - self.domElements[k].setAttribute('height', self.height + 'px'); + if (self.domElements.hasOwnProperty(k)) { + self.domElements[k].setAttribute('width', self.width + 'px'); + self.domElements[k].setAttribute('height', self.height + 'px'); + } } self.plotter.resize(self.width, self.height); diff --git a/src/core/sigmapublic.js b/src/core/sigmapublic.js index ab525c023..c5f43184a 100644 --- a/src/core/sigmapublic.js +++ b/src/core/sigmapublic.js @@ -127,7 +127,7 @@ function SigmaPublic(sigmaInstance) { this.addEdge = function(id, source, target, params) { s.graph.addEdge(id, source, target, params); return self; - } + }; this.dropNode = function(v) { s.graph.dropNode(v); diff --git a/src/intro.js b/src/intro.js index 5a45b1072..97f4da877 100644 --- a/src/intro.js +++ b/src/intro.js @@ -118,7 +118,7 @@ sigma.instances = {}; } } return result; - } + }; })(); } })(); diff --git a/src/public/chronos.js b/src/public/chronos.js index 67e6983e3..71c5e3bcd 100644 --- a/src/public/chronos.js +++ b/src/public/chronos.js @@ -398,12 +398,14 @@ sigma.chronos = new (function() { self.unbind('killed', onTaskEnded); insertFrame(function() { for (var k in generators) { - generators[k].on = true; - addTask( - generators[k].task, - k, - false - ); + if (generators.hasOwnProperty(k)) { + generators[k].on = true; + addTask( + generators[k].task, + k, + false + ); + } } }); diff --git a/src/public/debug.js b/src/public/debug.js index 920f1fd58..bdc5371ef 100644 --- a/src/public/debug.js +++ b/src/public/debug.js @@ -3,11 +3,15 @@ sigma.debugMode = 0; sigma.log = function() { if (sigma.debugMode == 1) { for (var k in arguments) { - console.log(arguments[k]); + if (arguments.hasOwnProperty(k)) { + console.log(arguments[k]); + } } - }else if (sigma.debugMode > 1) { + } else if (sigma.debugMode > 1) { for (var k in arguments) { - throw new Error(arguments[k]); + if (arguments.hasOwnProperty(k)) { + throw new Error(arguments[k]); + } } } From 4ca587e9394d9dc003653b06e119e12618329fb9 Mon Sep 17 00:00:00 2001 From: Timothy Crain Date: Tue, 5 Mar 2013 09:28:08 -0800 Subject: [PATCH 2/4] Fixed size of square nodes on hover over. --- src/core/plotter.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/plotter.js b/src/core/plotter.js index f6b358a7e..84005bf1c 100644 --- a/src/core/plotter.js +++ b/src/core/plotter.js @@ -475,8 +475,8 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { var radius = Math.sqrt(Math.PI) * size / 2 + self.p.borderSize; ctx.strokeRect(node['displayX'] - radius, node['displayY'] - radius, - radius, - radius); + 2 * radius, + 2 * radius); break; case 'triangle': var radius = Math.sqrt(2 * Math.PI) * size / 2 + self.p.borderSize; @@ -521,8 +521,8 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { var radius = Math.sqrt(Math.PI) * size / 2; ctx.fillRect(node['displayX'] - radius, node['displayY'] - radius, - radius, - radius); + 2 * radius, + 2 * radius); break; case 'triangle': var radius = Math.sqrt(2 * Math.PI) * size / 2; From 142f0f572b8e338af98ee380f632acc482bec458 Mon Sep 17 00:00:00 2001 From: Timothy Crain Date: Mon, 25 Mar 2013 13:19:31 -0700 Subject: [PATCH 3/4] Added missing semi-colon. --- src/core/plotter.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/plotter.js b/src/core/plotter.js index 84005bf1c..42a343f4b 100644 --- a/src/core/plotter.js +++ b/src/core/plotter.js @@ -321,6 +321,7 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { 0, Math.PI * 2, true); + } ctx.closePath(); ctx.fill(); From 67efd8cb79b76dbb2d6decbfd75a7df74a21f8b7 Mon Sep 17 00:00:00 2001 From: Timothy Crain Date: Thu, 28 Mar 2013 14:10:54 -0700 Subject: [PATCH 4/4] Fixed star shape and added diamond shape. --- src/core/plotter.js | 82 +++++++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 29 deletions(-) diff --git a/src/core/plotter.js b/src/core/plotter.js index 42a343f4b..951efe68c 100644 --- a/src/core/plotter.js +++ b/src/core/plotter.js @@ -289,8 +289,8 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { var radius = Math.sqrt(Math.PI) * size / 2; ctx.fillRect(node['displayX'] - radius, node['displayY'] - radius, - radius, - radius); + radius * 2, + radius * 2); break; case 'triangle': var radius = Math.sqrt(2 * Math.PI) * size / 2; @@ -299,18 +299,26 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { ctx.lineTo(node['displayX'], node['displayY'] + radius); ctx.lineTo(node['displayX'] - radius, node['displayY'] - radius); break; + case 'diamond': + var radius = Math.sqrt(2 * Math.PI) * size / 2; + ctx.moveTo(node['displayX'] - radius, node['displayY']); + ctx.lineTo(node['displayX'], node['displayY'] - radius); + ctx.lineTo(node['displayX'] + radius, node['displayY']); + ctx.lineTo(node['displayX'], node['displayY'] + radius); + ctx.lineTo(node['displayX'] - radius, node['displayY']); + break; case 'star': var numPoints = 5; var outerRadius = Math.sqrt(Math.PI) * size; var innerRadius = outerRadius / 2; - ctx.moveTo(node['displayX'], node['displayY'] - outerRadius); + ctx.moveTo(node['displayX'], node['displayY'] + innerRadius); for (var i = 1; i < numPoints * 2; i++) { var r = innerRadius; if (i % 2 === 1) { r = outerRadius; } var dx = r * Math.sin(i * Math.PI / numPoints); - var dy = - r * Math.cos(i * Math.PI / numPoints); + var dy = r * Math.cos(i * Math.PI / numPoints); ctx.lineTo(node['displayX'] + dx, node['displayY'] + dy); } break; @@ -471,14 +479,14 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { ctx.fillStyle = self.p.nodeBorderColor == 'node' ? (node['color'] || self.p.defaultNodeColor) : self.p.defaultNodeBorderColor; - switch(shape) { + switch (shape) { case 'square': - var radius = Math.sqrt(Math.PI) * size / 2 + self.p.borderSize; - ctx.strokeRect(node['displayX'] - radius, - node['displayY'] - radius, - 2 * radius, - 2 * radius); - break; + var radius = Math.sqrt(Math.PI) * size / 2 + self.p.borderSize; + ctx.strokeRect(node['displayX'] - radius, + node['displayY'] - radius, + 2 * radius, + 2 * radius); + break; case 'triangle': var radius = Math.sqrt(2 * Math.PI) * size / 2 + self.p.borderSize; ctx.moveTo(node['displayX'] - radius, node['displayY'] - radius); @@ -486,24 +494,32 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { ctx.lineTo(node['displayX'], node['displayY'] + radius); ctx.lineTo(node['displayX'] - radius, node['displayY'] - radius); break; + case 'diamond': + var radius = Math.sqrt(2 * Math.PI) * size / 2 + self.p.borderSize; + ctx.moveTo(node['displayX'] - radius, node['displayY']); + ctx.lineTo(node['displayX'], node['displayY'] - radius); + ctx.lineTo(node['displayX'] + radius, node['displayY']); + ctx.lineTo(node['displayX'], node['displayY'] + radius); + ctx.lineTo(node['displayX'] - radius, node['displayY']); + break; case 'star': var numPoints = 5; var outerRadius = Math.sqrt(Math.PI) * size; var innerRadius = outerRadius / 2; - ctx.moveTo(node['displayX'], node['displayY'] - outerRadius - self.p.borderSize); + ctx.moveTo(node['displayX'], node['displayY'] + innerRadius + self.p.borderSize); for (var i = 1; i < numPoints * 2; i++) { var r = innerRadius + self.p.borderSize; if (i % 2 === 1) { r = outerRadius + self.p.borderSize; } var dx = r * Math.sin(i * Math.PI / numPoints); - var dy = - r * Math.cos(i * Math.PI / numPoints); + var dy = r * Math.cos(i * Math.PI / numPoints); ctx.lineTo(node['displayX'] + dx, node['displayY'] + dy); } break; default: ctx.arc(node['displayX'], - node['displayY'], + node['displayY'], size + self.p.borderSize, 0, Math.PI * 2, @@ -517,7 +533,7 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { ctx.fillStyle = self.p.nodeHoverColor == 'node' ? (node['color'] || self.p.defaultNodeColor) : self.p.defaultNodeHoverColor; - switch(shape) { + switch (shape) { case 'square': var radius = Math.sqrt(Math.PI) * size / 2; ctx.fillRect(node['displayX'] - radius, @@ -532,28 +548,36 @@ function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { ctx.lineTo(node['displayX'], node['displayY'] + radius); ctx.lineTo(node['displayX'] - radius, node['displayY'] - radius); break; + case 'diamond': + var radius = Math.sqrt(2 * Math.PI) * size / 2; + ctx.moveTo(node['displayX'] - radius, node['displayY']); + ctx.lineTo(node['displayX'], node['displayY'] - radius); + ctx.lineTo(node['displayX'] + radius, node['displayY']); + ctx.lineTo(node['displayX'], node['displayY'] + radius); + ctx.lineTo(node['displayX'] - radius, node['displayY']); + break; case 'star': var numPoints = 5; var outerRadius = Math.sqrt(Math.PI) * size; var innerRadius = outerRadius / 2; - ctx.moveTo(node['displayX'], node['displayY'] - outerRadius); + ctx.moveTo(node['displayX'], node['displayY'] + innerRadius); for (var i = 1; i < numPoints * 2; i++) { - var r = innerRadius; - if (i % 2 === 1) { - r = outerRadius; - } - var dx = r * Math.sin(i * Math.PI / numPoints); - var dy = - r * Math.cos(i * Math.PI / numPoints); - ctx.lineTo(node['displayX'] + dx, node['displayY'] + dy); + var r = innerRadius; + if (i % 2 === 1) { + r = outerRadius; + } + var dx = r * Math.sin(i * Math.PI / numPoints); + var dy = r * Math.cos(i * Math.PI / numPoints); + ctx.lineTo(node['displayX'] + dx, node['displayY'] + dy); } break; - default: + default: ctx.arc(node['displayX'], - node['displayY'], - size, - 0, - Math.PI * 2, - true); + node['displayY'], + size, + 0, + Math.PI * 2, + true); } ctx.closePath();