mgraph.fromjson
Version:
Library to load graph from simple json format
2 lines (1 loc) • 4.33 kB
JavaScript
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(n="undefined"!=typeof globalThis?globalThis:n||self).mgraphFromJSON=t()}(this,(function(){"use strict";function n(n={}){if("uniqueLinkId"in n&&(console.warn("mgraph.graph: `uniqueLinkId` is deprecated. Use `multigraph` instead."),n.multigraph=n.uniqueLinkId),void 0===n.multigraph&&(n.multigraph=!1),"function"!=typeof Map)throw new Error("mgraph.graph requires Map to be defined. Please polyfill it.");const r=new Map,f=new Map,d={};let s=0;const u=[];let a=j,c=j,l=j,h=j;const p=n.multigraph?function(n,t,e){let r=i(n,t);const f=Object.prototype.hasOwnProperty.call(d,r);if(f||L(n,t)){f||(d[r]=0);const e="@"+ ++d[r];r=i(n+e,t+e)}return new o(n,t,e,r)}:function(n,t,e){const r=i(n,t),d=f.get(r);if(d)return d.data=e,d;return new o(n,t,e,r)},g={version:1,addNode:m,addLink:function(n,t,o){l();const i=y(n)||m(n),r=y(t)||m(t),d=p(n,t,o),s=f.has(d.id);f.set(d.id,d),e(i,d),n!==t&&e(r,d);return a(d,s?"update":"add"),h(),d},removeLink:function(n,t){void 0!==t&&(n=L(n,t));return E(n)},removeNode:v,getNode:y,hasNode:y,getLink:L,hasLink:L,getNodeCount:I,getNodesCount:I,getLinkCount:b,getLinksCount:b,getLinks:function(n){const t=y(n);return t?t.links:null},forEachNode:function(n){for(const t of r.values())if(n(t))return!0},forEachLink:function(n){for(const t of f.values())if(n(t))return!0},forEachLinkedNode:function(n,t,e){const o=y(n);if(o&&o.links&&"function"==typeof t)return e?function(n,t,e){for(const o of n.values())if(o.fromId===t&&e(r.get(o.toId),o))return!0}(o.links,n,t):function(n,t,e){for(const o of n.values()){const n=o.fromId===t?o.toId:o.fromId;if(e(r.get(n),o))return!0}}(o.links,n,t)},beginUpdate:N,endUpdate:O,clear:function(){l(),r.forEach((n=>v(n.id))),h()}};return function(n){if(!n)throw new Error("Eventify cannot use a falsy object as events subject");for(const t of["on","off","fire"])if(Object.prototype.hasOwnProperty.call(n,t))throw new Error(`Subject already has property '${t}'`);const t=new Map;n.on=function(e,o,i){if("function"!=typeof o)throw new Error("Callback is expected to be a function");return t.has(e)||t.set(e,[]),t.get(e).push({callback:o,ctx:i}),n},n.off=function(e,o){if(void 0===e)return t.clear(),n;if(t.has(e))if("function"!=typeof o)t.delete(e);else{const n=t.get(e).filter((n=>n.callback!==o));n.length?t.set(e,n):t.delete(e)}return n},n.fire=function(e,...o){const i=t.get(e);if(i)for(const{callback:n,ctx:t}of i)n.apply(t,o);return n}}(g),function(){const n=g.on;g.on=function(...t){return g.beginUpdate=l=N,g.endUpdate=h=O,a=k,c=w,g.on=n,n.apply(g,t)}}(),g;function k(n,t){u.push({link:n,changeType:t})}function w(n,t){u.push({node:n,changeType:t})}function m(n,e){if(void 0===n)throw new Error("Invalid node identifier");l();let o=y(n);return o?(o.data=e,c(o,"update")):(o=new t(n,e),c(o,"add")),r.set(n,o),h(),o}function y(n){return r.get(n)}function v(n){const t=y(n);return!!t&&(l(),t.links&&(t.links.forEach(E),t.links=null),r.delete(n),c(t,"remove"),h(),!0)}function I(){return r.size}function b(){return f.size}function E(n){if(!n||!f.get(n.id))return!1;l(),f.delete(n.id);const t=y(n.fromId),e=y(n.toId);return t&&t.links&&t.links.delete(n),e&&e.links&&e.links.delete(n),a(n,"remove"),h(),!0}function L(n,t){if(void 0!==n&&void 0!==t)return f.get(i(n,t))}function N(){s++}function O(){s--,0===s&&u.length>0&&(g.fire("changed",u),u.length=0)}function j(){}}function t(n,t){this.id=n,this.links=null,this.data=t}function e(n,t){n.links?n.links.add(t):n.links=new Set([t])}function o(n,t,e,o){this.fromId=n,this.toId=t,this.data=e,this.id=o}function i(n,t){return n.toString()+"👉"+t.toString()}function r(n){return n}return function(t,e,o){let i;e=e||r,o=o||r,i="string"==typeof t?JSON.parse(t):t;const f=n();if(void 0===i.links||void 0===i.nodes)throw new Error("Cannot load graph without links and nodes");for(let n=0;n<i.nodes.length;++n){const t=e(i.nodes[n]);if(!t.hasOwnProperty("id"))throw new Error("Graph node format is invalid: Node id is missing");f.addNode(t.id,t.data)}for(let n=0;n<i.links.length;++n){const t=o(i.links[n]);if(!t.hasOwnProperty("fromId")||!t.hasOwnProperty("toId"))throw new Error("Graph link format is invalid. Both fromId and toId are required");f.addLink(t.fromId,t.toId,t.data)}return f}}));