(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.createGraph = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i= 0) { fromNode.links.splice(idx, 1); } } if (toNode) { idx = indexOfElementInArray(link, toNode.links); if (idx >= 0) { toNode.links.splice(idx, 1); } } recordLinkChange(link, 'remove'); exitModification(); return true; } function getLink(fromNodeId, toNodeId) { // TODO: Use sorted links to speed this up var node = getNode(fromNodeId), i; if (!node || !node.links) { return null; } for (i = 0; i < node.links.length; ++i) { var link = node.links[i]; if (link.fromId === fromNodeId && link.toId === toNodeId) { return link; } } return null; // no link. } function clear() { enterModification(); forEachNode(function(node) { removeNode(node.id); }); exitModification(); } function forEachLink(callback) { var i, length; if (typeof callback === 'function') { for (i = 0, length = links.length; i < length; ++i) { callback(links[i]); } } } function forEachLinkedNode(nodeId, callback, oriented) { var node = getNode(nodeId); if (node && node.links && typeof callback === 'function') { if (oriented) { return forEachOrientedLink(node.links, nodeId, callback); } else { return forEachNonOrientedLink(node.links, nodeId, callback); } } } function forEachNonOrientedLink(links, nodeId, callback) { var quitFast; for (var i = 0; i < links.length; ++i) { var link = links[i]; var linkedNodeId = link.fromId === nodeId ? link.toId : link.fromId; quitFast = callback(nodes.get(linkedNodeId), link); if (quitFast) { return true; // Client does not need more iterations. Break now. } } } function forEachOrientedLink(links, nodeId, callback) { var quitFast; for (var i = 0; i < links.length; ++i) { var link = links[i]; if (link.fromId === nodeId) { quitFast = callback(nodes.get(link.toId), link) if (quitFast) { return true; // Client does not need more iterations. Break now. } } } } // we will not fire anything until users of this library explicitly call `on()` // method. function noop() {} // Enter, Exit modification allows bulk graph updates without firing events. function enterModificationReal() { suspendEvents += 1; } function exitModificationReal() { suspendEvents -= 1; if (suspendEvents === 0 && changes.length > 0) { graphPart.fire('changed', changes); changes.length = 0; } } function forEachNode(callback) { if (typeof callback !== 'function') { throw new Error('Function is expected to iterate over graph nodes. You passed ' + callback); } var valuesIterator = nodes.values(); var nextValue = valuesIterator.next(); while (!nextValue.done) { if (callback(nextValue.value)) { return true; // client doesn't want to proceed. Return. } nextValue = valuesIterator.next(); } } } // need this for old browsers. Should this be a separate module? function indexOfElementInArray(element, array) { if (!array) return -1; if (array.indexOf) { return array.indexOf(element); } var len = array.length, i; for (i = 0; i < len; i += 1) { if (array[i] === element) { return i; } } return -1; } /** * Internal structure to represent node; */ function Node(id, data) { this.id = id; this.links = null; this.data = data; } function addLinkToNode(node, link) { if (node.links) { node.links.push(link); } else { node.links = [link]; } } /** * Internal structure to represent links; */ function Link(fromId, toId, data, id) { this.fromId = fromId; this.toId = toId; this.data = data; this.id = id; } function makeLinkId(fromId, toId) { return fromId.toString() + '👉 ' + toId.toString(); } },{"ngraph.events":2}],2:[function(require,module,exports){ module.exports = function eventify(subject) { validateSubject(subject); var eventsStorage = createEventsStorage(subject); subject.on = eventsStorage.on; subject.off = eventsStorage.off; subject.fire = eventsStorage.fire; return subject; }; function createEventsStorage(subject) { // Store all event listeners to this hash. Key is event name, value is array // of callback records. // // A callback record consists of callback function and its optional context: // { 'eventName' => [{callback: function, ctx: object}] } var registeredEvents = Object.create(null); return { on: function (eventName, callback, ctx) { if (typeof callback !== 'function') { throw new Error('callback is expected to be a function'); } var handlers = registeredEvents[eventName]; if (!handlers) { handlers = registeredEvents[eventName] = []; } handlers.push({callback: callback, ctx: ctx}); return subject; }, off: function (eventName, callback) { var wantToRemoveAll = (typeof eventName === 'undefined'); if (wantToRemoveAll) { // Killing old events storage should be enough in this case: registeredEvents = Object.create(null); return subject; } if (registeredEvents[eventName]) { var deleteAllCallbacksForEvent = (typeof callback !== 'function'); if (deleteAllCallbacksForEvent) { delete registeredEvents[eventName]; } else { var callbacks = registeredEvents[eventName]; for (var i = 0; i < callbacks.length; ++i) { if (callbacks[i].callback === callback) { callbacks.splice(i, 1); } } } } return subject; }, fire: function (eventName) { var callbacks = registeredEvents[eventName]; if (!callbacks) { return subject; } var fireArguments; if (arguments.length > 1) { fireArguments = Array.prototype.splice.call(arguments, 1); } for(var i = 0; i < callbacks.length; ++i) { var callbackInfo = callbacks[i]; callbackInfo.callback.apply(callbackInfo.ctx, fireArguments); } return subject; } }; } function validateSubject(subject) { if (!subject) { throw new Error('Eventify cannot use falsy object as events subject'); } var reservedWords = ['on', 'fire', 'off']; for (var i = 0; i < reservedWords.length; ++i) { if (subject.hasOwnProperty(reservedWords[i])) { throw new Error("Subject cannot be eventified, since it already has property '" + reservedWords[i] + "'"); } } } },{}]},{},[1])(1) });