From 00649c2e32c69afc96392d2d6b5fa97fc5661783 Mon Sep 17 00:00:00 2001 From: Brendon Page Date: Fri, 9 Jan 2015 10:30:06 +0200 Subject: [PATCH 1/4] Added CircularImage shape --- lib/network/Node.js | 85 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 16 deletions(-) diff --git a/lib/network/Node.js b/lib/network/Node.js index 13524f41..8649b119 100644 --- a/lib/network/Node.js +++ b/lib/network/Node.js @@ -206,7 +206,7 @@ Node.prototype.setProperties = function(properties, constants) { this.radiusFixed = this.radiusFixed || (properties.radius !== undefined); - if (this.options.shape == 'image') { + if (this.options.shape === 'image' || this.options.shape === 'circularImage') { this.options.radiusMin = constants.nodes.widthMin; this.options.radiusMax = constants.nodes.widthMax; } @@ -219,6 +219,7 @@ Node.prototype.setProperties = function(properties, constants) { case 'ellipse': this.draw = this._drawEllipse; this.resize = this._resizeEllipse; break; // TODO: add diamond shape case 'image': this.draw = this._drawImage; this.resize = this._resizeImage; break; + case 'circularImage': this.draw = this._drawCircularImage; this.resize = this._resizeCircularImage; break; case 'text': this.draw = this._drawText; this.resize = this._resizeText; break; case 'dot': this.draw = this._drawDot; this.resize = this._resizeShape; break; case 'square': this.draw = this._drawSquare; this.resize = this._resizeShape; break; @@ -535,12 +536,7 @@ Node.prototype._resizeImage = function (ctx) { }; -Node.prototype._drawImage = function (ctx) { - this._resizeImage(ctx); - this.left = this.x - this.width / 2; - this.top = this.y - this.height / 2; - - var yLabel; +Node.prototype._drawImageAtPosition = function (ctx) { if (this.imageObj.width != 0 ) { // draw the shade if (this.clusterSize > 1) { @@ -555,6 +551,13 @@ Node.prototype._drawImage = function (ctx) { // draw the image ctx.globalAlpha = 1.0; ctx.drawImage(this.imageObj, this.left, this.top, this.width, this.height); + } +}; + +Node.prototype._drawImageLabel = function (ctx) { + var yLabel; + if (this.imageObj.width != 0 ) { + yLabel = this.y + this.height / 2; } else { @@ -562,18 +565,64 @@ Node.prototype._drawImage = function (ctx) { yLabel = this.y; } + this._label(ctx, this.label, this.x, yLabel, undefined, "top"); +}; + +Node.prototype._drawImage = function (ctx) { + this._resizeImage(ctx); + this.left = this.x - this.width / 2; + this.top = this.y - this.height / 2; + + this._drawImageAtPosition(ctx); this.boundingBox.top = this.top; this.boundingBox.left = this.left; this.boundingBox.right = this.left + this.width; this.boundingBox.bottom = this.top + this.height; - this._label(ctx, this.label, this.x, yLabel, undefined, "top"); + this._drawImageLabel(ctx); this.boundingBox.left = Math.min(this.boundingBox.left, this.labelDimensions.left); this.boundingBox.right = Math.max(this.boundingBox.right, this.labelDimensions.left + this.labelDimensions.width); this.boundingBox.bottom = Math.max(this.boundingBox.bottom, this.boundingBox.bottom + this.labelDimensions.height); }; +Node.prototype._resizeCircularImage = function (ctx) { + this._resizeImage(ctx); +}; + +Node.prototype._drawCircularImage = function (ctx) { + this._resizeCircularImage(ctx); + + this.left = this.x - this.width / 2; + this.top = this.y - this.height / 2; + + var centerX = this.left + (this.width / 2); + var centerY = this.top + (this.height / 2); + var radius = Math.abs(this.height / 2); + + this._drawRawCircle(ctx, centerX, centerY, radius); + + ctx.save(); + ctx.beginPath(); + ctx.arc(centerX, centerY, radius, 0, Math.PI * 2, true); + ctx.closePath(); + ctx.clip(); + + this._drawImageAtPosition(ctx); + + ctx.restore(); + + this.boundingBox.top = this.y - this.options.radius; + this.boundingBox.left = this.x - this.options.radius; + this.boundingBox.right = this.x + this.options.radius; + this.boundingBox.bottom = this.y + this.options.radius; + + this._drawImageLabel(ctx); + + this.boundingBox.left = Math.min(this.boundingBox.left, this.labelDimensions.left); + this.boundingBox.right = Math.max(this.boundingBox.right, this.labelDimensions.left + this.labelDimensions.width); + this.boundingBox.bottom = Math.max(this.boundingBox.bottom, this.boundingBox.bottom + this.labelDimensions.height); +}; Node.prototype._resizeBox = function (ctx) { if (!this.width) { @@ -702,15 +751,11 @@ Node.prototype._resizeCircle = function (ctx) { } }; -Node.prototype._drawCircle = function (ctx) { - this._resizeCircle(ctx); - this.left = this.x - this.width / 2; - this.top = this.y - this.height / 2; - +Node.prototype._drawRawCircle = function (ctx, x, y, radius) { var clusterLineWidth = 2.5; var borderWidth = this.options.borderWidth; var selectionLineWidth = this.options.borderWidthSelected || 2 * this.options.borderWidth; - + ctx.strokeStyle = this.selected ? this.options.color.highlight.border : this.hover ? this.options.color.hover.border : this.options.color.border; // draw the outer border @@ -719,7 +764,7 @@ Node.prototype._drawCircle = function (ctx) { ctx.lineWidth *= this.networkScaleInv; ctx.lineWidth = Math.min(this.width,ctx.lineWidth); - ctx.circle(this.x, this.y, this.options.radius+2*ctx.lineWidth); + ctx.circle(x, y, radius+2*ctx.lineWidth); ctx.stroke(); } ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); @@ -727,9 +772,17 @@ Node.prototype._drawCircle = function (ctx) { ctx.lineWidth = Math.min(this.width,ctx.lineWidth); ctx.fillStyle = this.selected ? this.options.color.highlight.background : this.hover ? this.options.color.hover.background : this.options.color.background; - ctx.circle(this.x, this.y, this.options.radius); + ctx.circle(this.x, this.y, radius); ctx.fill(); ctx.stroke(); +}; + +Node.prototype._drawCircle = function (ctx) { + this._resizeCircle(ctx); + this.left = this.x - this.width / 2; + this.top = this.y - this.height / 2; + + this._drawRawCircle(ctx, this.x, this.y, this.options.radius); this.boundingBox.top = this.y - this.options.radius; this.boundingBox.left = this.x - this.options.radius; From 7f6068159663df326796c9952eeef18f33ce0f4a Mon Sep 17 00:00:00 2001 From: Brendon Page Date: Fri, 9 Jan 2015 10:53:59 +0200 Subject: [PATCH 2/4] Fixed issue in network/images.js where load() would return undefined if image was already loaded --- lib/network/Images.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/network/Images.js b/lib/network/Images.js index 0097fb16..9e6962d5 100644 --- a/lib/network/Images.js +++ b/lib/network/Images.js @@ -23,10 +23,11 @@ Images.prototype.setOnloadCallback = function(callback) { * @return {Image} img The image object */ Images.prototype.load = function(url, brokenUrl) { - if (this.images[url] == undefined) { + var img = this.images[url]; + if (img === undefined) { // create the image var me = this; - var img = new Image(); + img = new Image(); img.onload = function () { // IE11 fix -- thanks dponch! From 2ebb1a00c3beab1004a07d34120d14d0643aa3ca Mon Sep 17 00:00:00 2001 From: Brendon Page Date: Fri, 9 Jan 2015 11:14:54 +0200 Subject: [PATCH 3/4] Updated network documentation to include circularImage shape. --- docs/network.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/network.html b/docs/network.html index 4d729591..7054abe4 100644 --- a/docs/network.html +++ b/docs/network.html @@ -940,11 +940,11 @@ All options defined per-node override these global settings. Define the shape for the node. Choose from ellipse (default), circle, box, - database, image, label, dot, + database, image, circularImage, label, dot, star, triangle, triangleDown, and square.

- In case of image, a property with name image must + In case of image and circularImage, a property with name image must be provided, containing image urls.

From 510077602b635008861e2969146f6b93aa169bf2 Mon Sep 17 00:00:00 2001 From: Brendon Page Date: Fri, 9 Jan 2015 11:50:05 +0200 Subject: [PATCH 4/4] Added an example for circular images. --- examples/network/34_circular_images.html | 87 ++++++++++++++++++++++++ examples/network/index.html | 1 + 2 files changed, 88 insertions(+) create mode 100644 examples/network/34_circular_images.html diff --git a/examples/network/34_circular_images.html b/examples/network/34_circular_images.html new file mode 100644 index 00000000..9e323d21 --- /dev/null +++ b/examples/network/34_circular_images.html @@ -0,0 +1,87 @@ + + + + Network | Scalable images + + + + + + + + + + +
+ +
+ + diff --git a/examples/network/index.html b/examples/network/index.html index d3d4d6ad..ac8c7bdd 100644 --- a/examples/network/index.html +++ b/examples/network/index.html @@ -45,6 +45,7 @@

31_localization.html

32_hierarchicaLayoutMethods.html

33_animation.html

+

34_circular_images.html

graphviz_gallery.html