From 81c7e46ee3187cd0a9858fd8f6417f47412fe04b Mon Sep 17 00:00:00 2001 From: Brendon Page Date: Thu, 23 Jul 2015 10:10:39 +0200 Subject: [PATCH 1/4] Fixed issue where broken images wouldn't always be rendered. --- .../network/nodeStyles/circularImages.html | 6 +- lib/network/Images.js | 90 +++++++++---------- 2 files changed, 47 insertions(+), 49 deletions(-) diff --git a/examples/network/nodeStyles/circularImages.html b/examples/network/nodeStyles/circularImages.html index 95fcbe3b..6e2ce27e 100644 --- a/examples/network/nodeStyles/circularImages.html +++ b/examples/network/nodeStyles/circularImages.html @@ -45,7 +45,8 @@ {id: 12, shape: 'circularImage', image: DIR + '12.png'}, {id: 13, shape: 'circularImage', image: DIR + '13.png'}, {id: 14, shape: 'circularImage', image: DIR + '14.png'}, - {id: 15, shape: 'circularImage', image: DIR + 'missing.png', brokenImage: DIR + 'missingBrokenImage.png', label:"when images\nfail\nto load"} + {id: 15, shape: 'circularImage', image: DIR + 'missing.png', brokenImage: DIR + 'missingBrokenImage.png', label:"when images\nfail\nto load"}, + {id: 16, shape: 'circularImage', image: DIR + 'anotherMissing.png', brokenImage: DIR + '9.png', label:"fallback image in action"} ]; // create connections between people @@ -64,7 +65,8 @@ {from: 10, to: 11}, {from: 11, to: 12}, {from: 12, to: 13}, - {from: 13, to: 14} + {from: 13, to: 14}, + {from: 9, to: 16} ]; // create a network diff --git a/lib/network/Images.js b/lib/network/Images.js index a7354fae..25e5536d 100644 --- a/lib/network/Images.js +++ b/lib/network/Images.js @@ -15,58 +15,54 @@ function Images(callback) { * @param {string} url Url of an image to use if the url image is not found * @return {Image} img The image object */ -Images.prototype.load = function(url, brokenUrl, id) { - var img = this.images[url]; // make a pointer - if (img === undefined) { - // create the image +Images.prototype.load = function (url, brokenUrl, id) { var me = this; - img = new Image(); - img.onload = function () { - // IE11 fix -- thanks dponch! - if (this.width === 0) { - document.body.appendChild(this); - this.width = this.offsetWidth; - this.height = this.offsetHeight; - document.body.removeChild(this); - } - - if (me.callback) { - me.images[url] = img; - me.callback(this); - } - }; - - img.onerror = function () { - if (brokenUrl === undefined) { - console.error("Could not load image:", url); - delete this.src; - if (me.callback) { - me.callback(this); + + function addImageToCache(imageToCache) { + // IE11 fix -- thanks dponch! + if (imageToCache.width === 0) { + document.body.appendChild(imageToCache); + imageToCache.width = imageToCache.offsetWidth; + imageToCache.height = imageToCache.offsetHeight; + document.body.removeChild(imageToCache); } - } - else { - if (me.imageBroken[id] && me.imageBroken[id][url] === true) { - console.error("Could not load brokenImage:", brokenUrl); - delete this.src; - if (me.callback) { - me.callback(this); - } - } - else { - console.error("Could not load image:", url); - this.src = brokenUrl; - if (me.imageBroken[id] === undefined) { - me.imageBroken[id] = {}; - } - me.imageBroken[id][url] = true; + + me.images[url] = imageToCache; + } + + function redrawWithImage(imageToRedrawWith) { + if (me.callback) { + me.callback(imageToRedrawWith); } - } + } + + function tryloadBrokenUrl(imageToLoadBrokenUrlOn) { + if (brokenUrl === undefined) return; + + imageToLoadBrokenUrlOn.onerror = function() { + console.error("Could not load brokenImage:", brokenUrl); + addImageToCache(new Image()); + }; + imageToLoadBrokenUrlOn.src = brokenUrl; + } + + var cachedImage = this.images[url]; + if (cachedImage) return cachedImage; + + var img = new Image(); + img.onload = function() { + addImageToCache(img); + redrawWithImage(img); }; - + + img.onerror = function () { + console.error("Could not load image:", url); + tryloadBrokenUrl(img); + } + img.src = url; - } - - return img; + + return img; }; module.exports = Images; From 05da3df6b82217c767ed05c28a251a369534a498 Mon Sep 17 00:00:00 2001 From: Brendon Page Date: Thu, 23 Jul 2015 10:16:49 +0200 Subject: [PATCH 2/4] Fixed indenting issue in cirular images example --- examples/network/nodeStyles/circularImages.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/network/nodeStyles/circularImages.html b/examples/network/nodeStyles/circularImages.html index 6e2ce27e..46cf898e 100644 --- a/examples/network/nodeStyles/circularImages.html +++ b/examples/network/nodeStyles/circularImages.html @@ -66,7 +66,7 @@ {from: 11, to: 12}, {from: 12, to: 13}, {from: 13, to: 14}, - {from: 9, to: 16} + {from: 9, to: 16} ]; // create a network From e015f7fca29367785dc453238555bb819a5e9986 Mon Sep 17 00:00:00 2001 From: Brendon Page Date: Thu, 23 Jul 2015 14:45:59 +0200 Subject: [PATCH 3/4] Moved internal functions in Images.load onto the prototype Added comments to Images.js --- lib/network/Images.js | 95 ++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 33 deletions(-) diff --git a/lib/network/Images.js b/lib/network/Images.js index 25e5536d..bd5f0caa 100644 --- a/lib/network/Images.js +++ b/lib/network/Images.js @@ -10,58 +10,87 @@ function Images(callback) { } /** - * - * @param {string} url Url of the image - * @param {string} url Url of an image to use if the url image is not found - * @return {Image} img The image object + * @param {string} url The Url to cache the image as + * @return {Image} imageToLoadBrokenUrlOn The image object */ -Images.prototype.load = function (url, brokenUrl, id) { - var me = this; - - function addImageToCache(imageToCache) { - // IE11 fix -- thanks dponch! - if (imageToCache.width === 0) { - document.body.appendChild(imageToCache); - imageToCache.width = imageToCache.offsetWidth; - imageToCache.height = imageToCache.offsetHeight; - document.body.removeChild(imageToCache); - } - - me.images[url] = imageToCache; - } - - function redrawWithImage(imageToRedrawWith) { - if (me.callback) { - me.callback(imageToRedrawWith); - } +Images.prototype._addImageToCache = function (url, imageToCache) { + // IE11 fix -- thanks dponch! + if (imageToCache.width === 0) { + document.body.appendChild(imageToCache); + imageToCache.width = imageToCache.offsetWidth; + imageToCache.height = imageToCache.offsetHeight; + document.body.removeChild(imageToCache); } + + this.images[url] = imageToCache; +} + +/** + * @param {string} url The original Url that failed to load, if the broken image is successfully loaded it will be added to the cache using this Url as the key so that subsequent requests for this Url will return the broken image + * @param {string} brokenUrl Url the broken image to try and load + * @return {Image} imageToLoadBrokenUrlOn The image object + */ +Images.prototype._tryloadBrokenUrl = function (url, brokenUrl, imageToLoadBrokenUrlOn) { + //Store the instance of the Images object so that we can reference it in events + var self = this; - function tryloadBrokenUrl(imageToLoadBrokenUrlOn) { - if (brokenUrl === undefined) return; + //If any of the parameters aren't specified then exit the function because nothing constructive can be done + if (url === undefined || brokenUrl === undefined || imageToLoadBrokenUrlOn === undefined) return; + + //Clear the old subscription to the error event and put a new in place that only handle errors in loading the brokenImageUrl + imageToLoadBrokenUrlOn.onerror = function() { + console.error("Could not load brokenImage:", brokenUrl); + //Add an empty image to the cache so that when subsequent load calls are made for the url we don't try load the image and broken image again + self._addImageToCache(url, new Image()); + }; - imageToLoadBrokenUrlOn.onerror = function() { - console.error("Could not load brokenImage:", brokenUrl); - addImageToCache(new Image()); - }; - imageToLoadBrokenUrlOn.src = brokenUrl; + //Set the source of the image to the brokenUrl, this is actually what kicks off the loading of the broken image + imageToLoadBrokenUrlOn.src = brokenUrl; +} + +/** + * @return {Image} imageToRedrawWith The images that will be passed to the callback when it is invoked + */ +Images.prototype._redrawWithImage = function (imageToRedrawWith) { + if (this.callback) { + this.callback(imageToRedrawWith); } +} + +/** + * @param {string} url Url of the image + * @param {string} brokenUrl Url of an image to use if the url image is not found + * @return {Image} img The image object + */ +Images.prototype.load = function (url, brokenUrl, id) { + //Store the instance of the Images object so that we can reference it in events + var self = this; + //Try and get the image from the cache, if successful then return the cached image var cachedImage = this.images[url]; if (cachedImage) return cachedImage; + //Create a new image var img = new Image(); + + //Subscribe to the event that is raised if the image loads successfully img.onload = function() { - addImageToCache(img); - redrawWithImage(img); + //Add the image to the cache and then request a redraw + self._addImageToCache(url, img); + self._redrawWithImage(img); }; + //Subscribe to the event that is raised if the image fails to load img.onerror = function () { console.error("Could not load image:", url); - tryloadBrokenUrl(img); + //Try and load the image specified by the brokenUrl using + self._tryloadBrokenUrl(url, brokenUrl, img); } + //Set the source of the image to the url, this is actuall what kicks off the loading of the image img.src = url; + //Return the new image return img; }; From 1cb3221df7986dda1e2574dd7f48020aba706a3a Mon Sep 17 00:00:00 2001 From: Brendon Page Date: Thu, 23 Jul 2015 15:39:53 +0200 Subject: [PATCH 4/4] Rewrote the Images.js for the network in ECMA script 6 syntax. --- lib/network/Images.js | 163 ++++++++++++++++++++---------------------- 1 file changed, 79 insertions(+), 84 deletions(-) diff --git a/lib/network/Images.js b/lib/network/Images.js index bd5f0caa..464e4585 100644 --- a/lib/network/Images.js +++ b/lib/network/Images.js @@ -2,96 +2,91 @@ * @class Images * This class loads images and keeps them stored. */ -function Images(callback) { - this.images = {}; - this.imageBroken = {}; - this.callback = callback; - -} - -/** - * @param {string} url The Url to cache the image as - * @return {Image} imageToLoadBrokenUrlOn The image object - */ -Images.prototype._addImageToCache = function (url, imageToCache) { - // IE11 fix -- thanks dponch! - if (imageToCache.width === 0) { - document.body.appendChild(imageToCache); - imageToCache.width = imageToCache.offsetWidth; - imageToCache.height = imageToCache.offsetHeight; - document.body.removeChild(imageToCache); - } - - this.images[url] = imageToCache; -} - -/** - * @param {string} url The original Url that failed to load, if the broken image is successfully loaded it will be added to the cache using this Url as the key so that subsequent requests for this Url will return the broken image - * @param {string} brokenUrl Url the broken image to try and load - * @return {Image} imageToLoadBrokenUrlOn The image object - */ -Images.prototype._tryloadBrokenUrl = function (url, brokenUrl, imageToLoadBrokenUrlOn) { - //Store the instance of the Images object so that we can reference it in events - var self = this; - - //If any of the parameters aren't specified then exit the function because nothing constructive can be done - if (url === undefined || brokenUrl === undefined || imageToLoadBrokenUrlOn === undefined) return; - - //Clear the old subscription to the error event and put a new in place that only handle errors in loading the brokenImageUrl - imageToLoadBrokenUrlOn.onerror = function() { - console.error("Could not load brokenImage:", brokenUrl); - //Add an empty image to the cache so that when subsequent load calls are made for the url we don't try load the image and broken image again - self._addImageToCache(url, new Image()); - }; - - //Set the source of the image to the brokenUrl, this is actually what kicks off the loading of the broken image - imageToLoadBrokenUrlOn.src = brokenUrl; -} - -/** - * @return {Image} imageToRedrawWith The images that will be passed to the callback when it is invoked - */ -Images.prototype._redrawWithImage = function (imageToRedrawWith) { - if (this.callback) { - this.callback(imageToRedrawWith); +class Images{ + constructor(callback){ + this.images = {}; + this.imageBroken = {}; + this.callback = callback; } -} - -/** - * @param {string} url Url of the image - * @param {string} brokenUrl Url of an image to use if the url image is not found - * @return {Image} img The image object - */ -Images.prototype.load = function (url, brokenUrl, id) { - //Store the instance of the Images object so that we can reference it in events - var self = this; - //Try and get the image from the cache, if successful then return the cached image - var cachedImage = this.images[url]; - if (cachedImage) return cachedImage; + /** + * @param {string} url The Url to cache the image as + * @return {Image} imageToLoadBrokenUrlOn The image object + */ + _addImageToCache (url, imageToCache) { + // IE11 fix -- thanks dponch! + if (imageToCache.width === 0) { + document.body.appendChild(imageToCache); + imageToCache.width = imageToCache.offsetWidth; + imageToCache.height = imageToCache.offsetHeight; + document.body.removeChild(imageToCache); + } - //Create a new image - var img = new Image(); + this.images[url] = imageToCache; + } - //Subscribe to the event that is raised if the image loads successfully - img.onload = function() { - //Add the image to the cache and then request a redraw - self._addImageToCache(url, img); - self._redrawWithImage(img); - }; + /** + * @param {string} url The original Url that failed to load, if the broken image is successfully loaded it will be added to the cache using this Url as the key so that subsequent requests for this Url will return the broken image + * @param {string} brokenUrl Url the broken image to try and load + * @return {Image} imageToLoadBrokenUrlOn The image object + */ + _tryloadBrokenUrl (url, brokenUrl, imageToLoadBrokenUrlOn) { + //If any of the parameters aren't specified then exit the function because nothing constructive can be done + if (url === undefined || brokenUrl === undefined || imageToLoadBrokenUrlOn === undefined) return; - //Subscribe to the event that is raised if the image fails to load - img.onerror = function () { - console.error("Could not load image:", url); - //Try and load the image specified by the brokenUrl using - self._tryloadBrokenUrl(url, brokenUrl, img); + //Clear the old subscription to the error event and put a new in place that only handle errors in loading the brokenImageUrl + imageToLoadBrokenUrlOn.onerror = () => { + console.error("Could not load brokenImage:", brokenUrl); + //Add an empty image to the cache so that when subsequent load calls are made for the url we don't try load the image and broken image again + this._addImageToCache(url, new Image()); + }; + + //Set the source of the image to the brokenUrl, this is actually what kicks off the loading of the broken image + imageToLoadBrokenUrlOn.src = brokenUrl; } - //Set the source of the image to the url, this is actuall what kicks off the loading of the image - img.src = url; + /** + * @return {Image} imageToRedrawWith The images that will be passed to the callback when it is invoked + */ + _redrawWithImage (imageToRedrawWith) { + if (this.callback) { + this.callback(imageToRedrawWith); + } + } - //Return the new image - return img; -}; + /** + * @param {string} url Url of the image + * @param {string} brokenUrl Url of an image to use if the url image is not found + * @return {Image} img The image object + */ + load (url, brokenUrl, id) { + //Try and get the image from the cache, if successful then return the cached image + var cachedImage = this.images[url]; + if (cachedImage) return cachedImage; + + //Create a new image + var img = new Image(); + + //Subscribe to the event that is raised if the image loads successfully + img.onload = () => { + //Add the image to the cache and then request a redraw + this._addImageToCache(url, img); + this._redrawWithImage(img); + }; + + //Subscribe to the event that is raised if the image fails to load + img.onerror = () => { + console.error("Could not load image:", url); + //Try and load the image specified by the brokenUrl using + this._tryloadBrokenUrl(url, brokenUrl, img); + } + + //Set the source of the image to the url, this is actuall what kicks off the loading of the image + img.src = url; + + //Return the new image + return img; + } +} -module.exports = Images; +export default Images; \ No newline at end of file