@logixode/force-graph-lib 0.1.9 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/force-graph-lib.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import f from "force-graph";
|
|
2
2
|
import * as c from "d3";
|
|
3
|
-
class
|
|
3
|
+
class b {
|
|
4
4
|
container;
|
|
5
5
|
graph;
|
|
6
6
|
data = { nodes: [], links: [] };
|
|
@@ -9,6 +9,7 @@ class C {
|
|
|
9
9
|
options;
|
|
10
10
|
worker = null;
|
|
11
11
|
groupBounds = /* @__PURE__ */ new Map();
|
|
12
|
+
isFirstRender = !0;
|
|
12
13
|
constructor(t, i = { nodes: [], links: [] }, o = {}) {
|
|
13
14
|
this.container = t, this.data = i, this.graph = new f(this.container), i.nodes.forEach((r) => {
|
|
14
15
|
this.nodesMap.set(r.id.toString(), r);
|
|
@@ -34,7 +35,9 @@ class C {
|
|
|
34
35
|
}, this.initGraph();
|
|
35
36
|
}
|
|
36
37
|
initGraph() {
|
|
37
|
-
this.applyOptions(), this.render(), this.graphData(this.data), this.graph.onEngineStop(() =>
|
|
38
|
+
this.applyOptions(), this.render(), this.graphData(this.data), this.graph.onEngineStop(() => {
|
|
39
|
+
this.data.nodes.length && (this.isFirstRender ? (this.options.onRenderComplete ? this.options.onRenderComplete() : this.graph.zoomToFit(400), this.isFirstRender = !1) : this.options.onGraphUpdated && this.options.onGraphUpdated());
|
|
40
|
+
});
|
|
38
41
|
}
|
|
39
42
|
renderer() {
|
|
40
43
|
return this.graph;
|
|
@@ -49,7 +52,7 @@ class C {
|
|
|
49
52
|
}
|
|
50
53
|
}
|
|
51
54
|
render() {
|
|
52
|
-
this.graph.width(this.options.width ?? 800).height(this.options.height ?? 400).cooldownTime(this.getCooldownTime()).d3Force("charge", c.forceManyBody().strength(this.options.nodeGap ?? -50)), typeof this.options.nodeClickHandler == "function" && this.graph.onNodeClick((t) => {
|
|
55
|
+
this.graph.width(this.options.width ?? 800).height(this.options.height ?? 400).cooldownTime(this.getCooldownTime()).d3Force("charge", c.forceManyBody().strength(this.options.nodeGap ?? -50)), this.options.cooldownTicks !== void 0 && this.graph.cooldownTicks(this.options.cooldownTicks), typeof this.options.nodeClickHandler == "function" && this.graph.onNodeClick((t) => {
|
|
53
56
|
this.options.nodeClickHandler(t);
|
|
54
57
|
});
|
|
55
58
|
}
|
|
@@ -215,6 +218,8 @@ class C {
|
|
|
215
218
|
* Normal: node.length * 125%
|
|
216
219
|
*/
|
|
217
220
|
getCooldownTime() {
|
|
221
|
+
if (this.options.cooldownTime !== void 0)
|
|
222
|
+
return this.options.cooldownTime;
|
|
218
223
|
const i = this.data.nodes.length * (125 / 100);
|
|
219
224
|
return Math.max(4e3, i);
|
|
220
225
|
}
|
|
@@ -362,5 +367,5 @@ class C {
|
|
|
362
367
|
}
|
|
363
368
|
}
|
|
364
369
|
export {
|
|
365
|
-
|
|
370
|
+
b as ForceGraph
|
|
366
371
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(a,l){typeof exports=="object"&&typeof module<"u"?l(exports,require("force-graph"),require("d3")):typeof define=="function"&&define.amd?define(["exports","force-graph","d3"],l):(a=typeof globalThis<"u"?globalThis:a||self,l(a.ForceGraphLib={},a.ForceGraph,a.d3))})(this,(function(a,l,b){"use strict";function k(d){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(d){for(const i in d)if(i!=="default"){const o=Object.getOwnPropertyDescriptor(d,i);Object.defineProperty(t,i,o.get?o:{enumerable:!0,get:()=>d[i]})}}return t.default=d,Object.freeze(t)}const m=k(b);class C{container;graph;data={nodes:[],links:[]};nodesMap=new Map;linkMap=new Map;options;worker=null;groupBounds=new Map;constructor(t,i={nodes:[],links:[]},o={}){this.container=t,this.data=i,this.graph=new l(this.container),i.nodes.forEach(r=>{this.nodesMap.set(r.id.toString(),r)});const e={labelThreshold:1.5,showGroups:!1,...o},s=e.showGroups?{groupBy:"topic",groupBorderColor:"#666",groupBorderWidth:2,groupBorderOpacity:.3,groupLabelColor:"#333",groupLabelSize:16,groupLabelThreshold:.8,groupPadding:20}:{};this.options={...e,...s},this.initGraph()}initGraph(){this.applyOptions(),this.render(),this.graphData(this.data),this.graph.onEngineStop(()=>this.graph.zoomToFit(400))}renderer(){return this.graph}focusPosition(t={}){if(Object.values(t).length){if(t.id){const{x:i,y:o}=this.nodesMap.get(t.id)??{x:0,y:0};i&&o&&(t={x:i,y:o})}t&&(this.graph.centerAt(t.x,t.y,1e3),this.graph.zoom(8,2e3))}}render(){this.graph.width(this.options.width??800).height(this.options.height??400).cooldownTime(this.getCooldownTime()).d3Force("charge",m.forceManyBody().strength(this.options.nodeGap??-50)),typeof this.options.nodeClickHandler=="function"&&this.graph.onNodeClick(t=>{this.options.nodeClickHandler(t)})}force(t,i){return this.graph.d3Force(t,i)}applyOptions(){this.options.keepDragPosition&&this.graph.onNodeDragEnd(t=>{t.fx=t.x,t.fy=t.y}),this.options.pointerInteraction||this.graph.enablePointerInteraction(!1),this.graph.nodeCanvasObject((t,i,o)=>{t===this.data.nodes[0]&&this.renderGroups(i,o);const e=this.getNodeSize(t)*2,s=typeof this.options.nodeBorderWidth=="function"?this.options.nodeBorderWidth(t):this.options.nodeBorderWidth;i.beginPath(),i.arc(t.x||0,t.y||0,e,0,2*Math.PI),i.fillStyle=this.getNodeColor(t),i.fill(),s&&s>0&&(i.beginPath(),i.arc(t.x||0,t.y||0,e,0,2*Math.PI),i.strokeStyle=this.getNodeBorderColor(t),i.lineWidth=s,i.stroke());const r=this.getNodeLabel(t);if(r&&this.shouldShowLabel(t,o)){const p=typeof this.options.nodeLabelColor=="function"?this.options.nodeLabelColor(t):this.options.nodeLabelColor??"#555",n=(this.options.labelFontSize||14)/o;i.font=`${n}px Arial`,i.fillStyle=p,i.textAlign="center",i.textBaseline="middle",i.fillText(r,t.x||0,(t.y||0)+e+n/2+2)}}),this.applyLinkOptions()}getNodeSize(t){return typeof this.options.nodeSize=="function"?this.options.nodeSize(t)||t?.marker?.radius:this.options.nodeSize||t?.marker?.radius||1}getNodeLabel(t){return typeof this.options.nodeLabel=="function"?this.options.nodeLabel(t):t?.label||t.id}shouldShowLabel(t,i){const o=this.getNodeSize(t)*2,s=(this.options.labelFontSize||14)/i,r=this.options.labelThreshold||1.5;return s<=o*r}updateData(t){const i=new Set(this.data.nodes.map(r=>r.id.toString())),o=t.nodes.filter(r=>!i.has(r.id.toString()));o.forEach(r=>{this.nodesMap.set(r.id.toString(),r)});const e=new Set(this.data.links.map(r=>this.createLinkKey(r.source,r.target))),s=t.links.filter(r=>!e.has(this.createLinkKey(r.source,r.target)));this.data={nodes:[...this.data.nodes,...o],links:[...this.data.links,...s]},this.refreshGraph()}getNodeColor(t){if(typeof this.options.nodeColor=="function"){const i=this.options.nodeColor(t);if(i)return i}return t?.color??""}getNodeBorderColor(t){return typeof this.options.nodeBorderColor=="function"?this.options.nodeBorderColor(t):this.options.nodeBorderColor||"#333"}applyLinkOptions(){this.options.linkWidth!==void 0&&this.graph.linkWidth(t=>this.getLinkProperty(this.options.linkWidth,t)??1),this.options.linkCurvature!==void 0&&this.graph.linkCurvature(this.getLinkCurvature.bind(this)),this.options.linkDirectionalParticles&&this.graph.linkDirectionalParticles(t=>this.getLinkProperty(this.options.linkDirectionalParticles,t)??0),this.options.linkDirectionalParticleSpeed!==void 0&&this.graph.linkDirectionalParticleSpeed(t=>this.getLinkProperty(this.options.linkDirectionalParticleSpeed,t)??0),this.options.linkDirectionalParticleWidth!==void 0&&this.graph.linkDirectionalParticleWidth(t=>this.getLinkProperty(this.options.linkDirectionalParticleWidth,t)??0),this.options.linkDirectionalParticleColor!==void 0&&this.graph.linkDirectionalParticleColor(t=>this.getLinkProperty(this.options.linkDirectionalParticleColor,t)??"#aaa")}getLinkCurvature(t){return typeof this.options.linkCurvature=="function"?this.options.linkCurvature(t):typeof this.options.linkCurvature=="string"?t[this.options.linkCurvature]||0:typeof this.options.linkCurvature=="number"?this.options.linkCurvature:t.curvature||0}getLinkProperty(t,i){return typeof t=="function"?t(i):t}calculateGroupBounds(){if(!this.options.showGroups)return;this.groupBounds.clear();const t=this.options.groupPadding||20,i=new Map;this.data.nodes.forEach(o=>{const e=this.getNodeGroupId(o);e&&(i.has(e)||i.set(e,[]),i.get(e).push(o))}),i.forEach((o,e)=>{if(o.length===0)return;let s=1/0,r=1/0,p=-1/0,u=-1/0;o.forEach(n=>{if(n.x!==void 0&&n.y!==void 0){const h=this.getNodeSize(n);s=Math.min(s,n.x-h),r=Math.min(r,n.y-h),p=Math.max(p,n.x+h),u=Math.max(u,n.y+h)}}),s!==1/0&&this.groupBounds.set(e,{minX:s-t,minY:r-t,maxX:p+t,maxY:u+t,nodes:o})})}getNodeGroupId(t){if(this.options.groupBy){if(typeof this.options.groupBy=="function")return this.options.groupBy(t);if(typeof this.options.groupBy=="string")return t[this.options.groupBy]}}renderGroups(t,i){this.options.showGroups&&(this.calculateGroupBounds(),this.groupBounds.forEach((o,e)=>{const s=this.getGroupBorderColor(e),r=this.options.groupBorderWidth||2,p=this.options.groupBorderOpacity||.3;t.save(),t.globalAlpha=p,t.strokeStyle=s,t.lineWidth=r/i,t.setLineDash([10/i,5/i]),t.strokeRect(o.minX,o.minY,o.maxX-o.minX,o.maxY-o.minY),t.restore();const u=this.options.groupLabelThreshold||.8;if(i<=u){const n=this.getGroupLabelColor(e),h=(this.options.groupLabelSize||16)/i;t.save(),t.font=`bold ${h}px Arial`,t.fillStyle=n,t.textAlign="center",t.textBaseline="middle";const g=(o.minX+o.maxX)/2,f=o.minY-h/2,c=t.measureText(e).width,y=h;t.globalAlpha=.8,t.fillStyle="rgba(255, 255, 255, 0.9)",t.fillRect(g-c/2-4,f-y/2-2,c+8,y+4),t.globalAlpha=1,t.fillStyle=n,t.fillText(e,g,f),t.restore()}}))}getGroupBorderColor(t){return typeof this.options.groupBorderColor=="function"?this.options.groupBorderColor(t):this.options.groupBorderColor||"#666"}getGroupLabelColor(t){return typeof this.options.groupLabelColor=="function"?this.options.groupLabelColor(t):this.options.groupLabelColor||"#333"}getNodeById(t){return this.nodesMap.get(t.toString())}hasNode(t){return this.nodesMap.has(t.toString())}getCooldownTime(){const i=this.data.nodes.length*(125/100);return Math.max(4e3,i)}getDataSize(){const{nodes:t,links:i}=this.graph.graphData();return{nodes:t.length,links:i.length}}getAllNodeIds(){return Array.from(this.nodesMap.keys())}updateNode(t,i){const o=this.nodesMap.get(t.toString());if(o){Object.assign(o,i);const e=this.data.nodes.findIndex(s=>s.id.toString()===t.toString());return e!==-1&&(this.data.nodes[e]=o),this.refreshGraph(),!0}return!1}removeNode(t){const i=t.toString();return this.nodesMap.has(i)?(this.nodesMap.delete(i),this.data.nodes=this.data.nodes.filter(o=>o.id.toString()!==i),this.data.links=this.data.links.filter(o=>{const e=typeof o.source=="object"?o.source.id:o.source,s=typeof o.target=="object"?o.target.id:o.target;return e?.toString()!==i&&s?.toString()!==i}),this.graph.cooldownTime(this.getCooldownTime()),this.refreshGraph(),!0):!1}async addData(t){t.nodes.forEach(i=>{this.nodesMap.has(i.id.toString())||this.nodesMap.set(i.id.toString(),i)}),t.links.forEach(i=>{const o=this.createLinkKey(i.source,i.target);this.linkMap.has(o)?console.log("link already exists",i):this.linkMap.set(o,i)}),this.data={nodes:Array.from(this.nodesMap.values()),links:Array.from(this.linkMap.values())},this.graph.cooldownTime(this.getCooldownTime()),this.graph.graphData(this.data)}setLabelThreshold(t){this.options.labelThreshold=t,this.render()}setOptions(t){this.options={...this.options,...t},this.applyOptions()}refreshGraph(){this.graphData(this.data)}reinitialize(){this.initGraph()}reset(){this.graph.pauseAnimation();const t=this.graph.d3Force("simulation");t&&t.stop(),this.data={nodes:[],links:[]},this.nodesMap.clear(),this.graph=new l(this.container),this.initGraph()}getData(){return this.data}getNodesData(){return this.data.nodes}getLinksData(){return this.data.links}createLinkKey(t,i){const o=t===void 0?"undefined":typeof t=="object"?t.id:t,e=i===void 0?"undefined":typeof i=="object"?i.id:i;return`${o}-${e}`}graphData(t){return this.nodesMap.clear(),this.linkMap.clear(),t.nodes.forEach(i=>{this.nodesMap.has(i.id.toString())||this.nodesMap.set(i.id.toString(),i)}),t.links.forEach(i=>{const o=this.createLinkKey(i.source,i.target);this.linkMap.has(o)||this.linkMap.set(o,i)}),this.data={nodes:Array.from(this.nodesMap.values()),links:Array.from(this.linkMap.values())},this.graph.cooldownTime(this.getCooldownTime()),this.graph.graphData(this.data),this}showGroups(t){return this.options.showGroups=t,t&&Object.entries({groupBy:"topic",groupBorderColor:"#666",groupBorderWidth:2,groupBorderOpacity:.3,groupLabelColor:"#333",groupLabelSize:16,groupLabelThreshold:.8,groupPadding:20}).forEach(([o,e])=>{this.options[o]===void 0&&(this.options[o]=e)}),this.applyOptions(),this.refreshGraph(),this}setGroupBy(t){return this.options.groupBy=t,this.applyOptions(),this.refreshGraph(),this}setGroupOptions(t){return t.borderColor!==void 0&&(this.options.groupBorderColor=t.borderColor),t.borderWidth!==void 0&&(this.options.groupBorderWidth=t.borderWidth),t.borderOpacity!==void 0&&(this.options.groupBorderOpacity=t.borderOpacity),t.labelColor!==void 0&&(this.options.groupLabelColor=t.labelColor),t.labelSize!==void 0&&(this.options.groupLabelSize=t.labelSize),t.labelThreshold!==void 0&&(this.options.groupLabelThreshold=t.labelThreshold),t.padding!==void 0&&(this.options.groupPadding=t.padding),this.applyOptions(),this.refreshGraph(),this}getGroups(){const t=new Set;return this.data.nodes.forEach(i=>{const o=this.getNodeGroupId(i);o&&t.add(o)}),Array.from(t)}getNodesInGroup(t){return this.data.nodes.filter(i=>this.getNodeGroupId(i)===t)}getOptions(){return{...this.options}}destroy(){this.worker&&(this.worker.terminate(),this.worker=null),this.graph._destructor()}}a.ForceGraph=C,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})}));
|
|
1
|
+
(function(h,l){typeof exports=="object"&&typeof module<"u"?l(exports,require("force-graph"),require("d3")):typeof define=="function"&&define.amd?define(["exports","force-graph","d3"],l):(h=typeof globalThis<"u"?globalThis:h||self,l(h.ForceGraphLib={},h.ForceGraph,h.d3))})(this,(function(h,l,k){"use strict";function b(d){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(d){for(const i in d)if(i!=="default"){const o=Object.getOwnPropertyDescriptor(d,i);Object.defineProperty(t,i,o.get?o:{enumerable:!0,get:()=>d[i]})}}return t.default=d,Object.freeze(t)}const m=b(k);class C{container;graph;data={nodes:[],links:[]};nodesMap=new Map;linkMap=new Map;options;worker=null;groupBounds=new Map;isFirstRender=!0;constructor(t,i={nodes:[],links:[]},o={}){this.container=t,this.data=i,this.graph=new l(this.container),i.nodes.forEach(r=>{this.nodesMap.set(r.id.toString(),r)});const e={labelThreshold:1.5,showGroups:!1,...o},s=e.showGroups?{groupBy:"topic",groupBorderColor:"#666",groupBorderWidth:2,groupBorderOpacity:.3,groupLabelColor:"#333",groupLabelSize:16,groupLabelThreshold:.8,groupPadding:20}:{};this.options={...e,...s},this.initGraph()}initGraph(){this.applyOptions(),this.render(),this.graphData(this.data),this.graph.onEngineStop(()=>{this.data.nodes.length&&(this.isFirstRender?(this.options.onRenderComplete?this.options.onRenderComplete():this.graph.zoomToFit(400),this.isFirstRender=!1):this.options.onGraphUpdated&&this.options.onGraphUpdated())})}renderer(){return this.graph}focusPosition(t={}){if(Object.values(t).length){if(t.id){const{x:i,y:o}=this.nodesMap.get(t.id)??{x:0,y:0};i&&o&&(t={x:i,y:o})}t&&(this.graph.centerAt(t.x,t.y,1e3),this.graph.zoom(8,2e3))}}render(){this.graph.width(this.options.width??800).height(this.options.height??400).cooldownTime(this.getCooldownTime()).d3Force("charge",m.forceManyBody().strength(this.options.nodeGap??-50)),this.options.cooldownTicks!==void 0&&this.graph.cooldownTicks(this.options.cooldownTicks),typeof this.options.nodeClickHandler=="function"&&this.graph.onNodeClick(t=>{this.options.nodeClickHandler(t)})}force(t,i){return this.graph.d3Force(t,i)}applyOptions(){this.options.keepDragPosition&&this.graph.onNodeDragEnd(t=>{t.fx=t.x,t.fy=t.y}),this.options.pointerInteraction||this.graph.enablePointerInteraction(!1),this.graph.nodeCanvasObject((t,i,o)=>{t===this.data.nodes[0]&&this.renderGroups(i,o);const e=this.getNodeSize(t)*2,s=typeof this.options.nodeBorderWidth=="function"?this.options.nodeBorderWidth(t):this.options.nodeBorderWidth;i.beginPath(),i.arc(t.x||0,t.y||0,e,0,2*Math.PI),i.fillStyle=this.getNodeColor(t),i.fill(),s&&s>0&&(i.beginPath(),i.arc(t.x||0,t.y||0,e,0,2*Math.PI),i.strokeStyle=this.getNodeBorderColor(t),i.lineWidth=s,i.stroke());const r=this.getNodeLabel(t);if(r&&this.shouldShowLabel(t,o)){const p=typeof this.options.nodeLabelColor=="function"?this.options.nodeLabelColor(t):this.options.nodeLabelColor??"#555",n=(this.options.labelFontSize||14)/o;i.font=`${n}px Arial`,i.fillStyle=p,i.textAlign="center",i.textBaseline="middle",i.fillText(r,t.x||0,(t.y||0)+e+n/2+2)}}),this.applyLinkOptions()}getNodeSize(t){return typeof this.options.nodeSize=="function"?this.options.nodeSize(t)||t?.marker?.radius:this.options.nodeSize||t?.marker?.radius||1}getNodeLabel(t){return typeof this.options.nodeLabel=="function"?this.options.nodeLabel(t):t?.label||t.id}shouldShowLabel(t,i){const o=this.getNodeSize(t)*2,s=(this.options.labelFontSize||14)/i,r=this.options.labelThreshold||1.5;return s<=o*r}updateData(t){const i=new Set(this.data.nodes.map(r=>r.id.toString())),o=t.nodes.filter(r=>!i.has(r.id.toString()));o.forEach(r=>{this.nodesMap.set(r.id.toString(),r)});const e=new Set(this.data.links.map(r=>this.createLinkKey(r.source,r.target))),s=t.links.filter(r=>!e.has(this.createLinkKey(r.source,r.target)));this.data={nodes:[...this.data.nodes,...o],links:[...this.data.links,...s]},this.refreshGraph()}getNodeColor(t){if(typeof this.options.nodeColor=="function"){const i=this.options.nodeColor(t);if(i)return i}return t?.color??""}getNodeBorderColor(t){return typeof this.options.nodeBorderColor=="function"?this.options.nodeBorderColor(t):this.options.nodeBorderColor||"#333"}applyLinkOptions(){this.options.linkWidth!==void 0&&this.graph.linkWidth(t=>this.getLinkProperty(this.options.linkWidth,t)??1),this.options.linkCurvature!==void 0&&this.graph.linkCurvature(this.getLinkCurvature.bind(this)),this.options.linkDirectionalParticles&&this.graph.linkDirectionalParticles(t=>this.getLinkProperty(this.options.linkDirectionalParticles,t)??0),this.options.linkDirectionalParticleSpeed!==void 0&&this.graph.linkDirectionalParticleSpeed(t=>this.getLinkProperty(this.options.linkDirectionalParticleSpeed,t)??0),this.options.linkDirectionalParticleWidth!==void 0&&this.graph.linkDirectionalParticleWidth(t=>this.getLinkProperty(this.options.linkDirectionalParticleWidth,t)??0),this.options.linkDirectionalParticleColor!==void 0&&this.graph.linkDirectionalParticleColor(t=>this.getLinkProperty(this.options.linkDirectionalParticleColor,t)??"#aaa")}getLinkCurvature(t){return typeof this.options.linkCurvature=="function"?this.options.linkCurvature(t):typeof this.options.linkCurvature=="string"?t[this.options.linkCurvature]||0:typeof this.options.linkCurvature=="number"?this.options.linkCurvature:t.curvature||0}getLinkProperty(t,i){return typeof t=="function"?t(i):t}calculateGroupBounds(){if(!this.options.showGroups)return;this.groupBounds.clear();const t=this.options.groupPadding||20,i=new Map;this.data.nodes.forEach(o=>{const e=this.getNodeGroupId(o);e&&(i.has(e)||i.set(e,[]),i.get(e).push(o))}),i.forEach((o,e)=>{if(o.length===0)return;let s=1/0,r=1/0,p=-1/0,u=-1/0;o.forEach(n=>{if(n.x!==void 0&&n.y!==void 0){const a=this.getNodeSize(n);s=Math.min(s,n.x-a),r=Math.min(r,n.y-a),p=Math.max(p,n.x+a),u=Math.max(u,n.y+a)}}),s!==1/0&&this.groupBounds.set(e,{minX:s-t,minY:r-t,maxX:p+t,maxY:u+t,nodes:o})})}getNodeGroupId(t){if(this.options.groupBy){if(typeof this.options.groupBy=="function")return this.options.groupBy(t);if(typeof this.options.groupBy=="string")return t[this.options.groupBy]}}renderGroups(t,i){this.options.showGroups&&(this.calculateGroupBounds(),this.groupBounds.forEach((o,e)=>{const s=this.getGroupBorderColor(e),r=this.options.groupBorderWidth||2,p=this.options.groupBorderOpacity||.3;t.save(),t.globalAlpha=p,t.strokeStyle=s,t.lineWidth=r/i,t.setLineDash([10/i,5/i]),t.strokeRect(o.minX,o.minY,o.maxX-o.minX,o.maxY-o.minY),t.restore();const u=this.options.groupLabelThreshold||.8;if(i<=u){const n=this.getGroupLabelColor(e),a=(this.options.groupLabelSize||16)/i;t.save(),t.font=`bold ${a}px Arial`,t.fillStyle=n,t.textAlign="center",t.textBaseline="middle";const g=(o.minX+o.maxX)/2,f=o.minY-a/2,c=t.measureText(e).width,y=a;t.globalAlpha=.8,t.fillStyle="rgba(255, 255, 255, 0.9)",t.fillRect(g-c/2-4,f-y/2-2,c+8,y+4),t.globalAlpha=1,t.fillStyle=n,t.fillText(e,g,f),t.restore()}}))}getGroupBorderColor(t){return typeof this.options.groupBorderColor=="function"?this.options.groupBorderColor(t):this.options.groupBorderColor||"#666"}getGroupLabelColor(t){return typeof this.options.groupLabelColor=="function"?this.options.groupLabelColor(t):this.options.groupLabelColor||"#333"}getNodeById(t){return this.nodesMap.get(t.toString())}hasNode(t){return this.nodesMap.has(t.toString())}getCooldownTime(){if(this.options.cooldownTime!==void 0)return this.options.cooldownTime;const i=this.data.nodes.length*(125/100);return Math.max(4e3,i)}getDataSize(){const{nodes:t,links:i}=this.graph.graphData();return{nodes:t.length,links:i.length}}getAllNodeIds(){return Array.from(this.nodesMap.keys())}updateNode(t,i){const o=this.nodesMap.get(t.toString());if(o){Object.assign(o,i);const e=this.data.nodes.findIndex(s=>s.id.toString()===t.toString());return e!==-1&&(this.data.nodes[e]=o),this.refreshGraph(),!0}return!1}removeNode(t){const i=t.toString();return this.nodesMap.has(i)?(this.nodesMap.delete(i),this.data.nodes=this.data.nodes.filter(o=>o.id.toString()!==i),this.data.links=this.data.links.filter(o=>{const e=typeof o.source=="object"?o.source.id:o.source,s=typeof o.target=="object"?o.target.id:o.target;return e?.toString()!==i&&s?.toString()!==i}),this.graph.cooldownTime(this.getCooldownTime()),this.refreshGraph(),!0):!1}async addData(t){t.nodes.forEach(i=>{this.nodesMap.has(i.id.toString())||this.nodesMap.set(i.id.toString(),i)}),t.links.forEach(i=>{const o=this.createLinkKey(i.source,i.target);this.linkMap.has(o)?console.log("link already exists",i):this.linkMap.set(o,i)}),this.data={nodes:Array.from(this.nodesMap.values()),links:Array.from(this.linkMap.values())},this.graph.cooldownTime(this.getCooldownTime()),this.graph.graphData(this.data)}setLabelThreshold(t){this.options.labelThreshold=t,this.render()}setOptions(t){this.options={...this.options,...t},this.applyOptions()}refreshGraph(){this.graphData(this.data)}reinitialize(){this.initGraph()}reset(){this.graph.pauseAnimation();const t=this.graph.d3Force("simulation");t&&t.stop(),this.data={nodes:[],links:[]},this.nodesMap.clear(),this.graph=new l(this.container),this.initGraph()}getData(){return this.data}getNodesData(){return this.data.nodes}getLinksData(){return this.data.links}createLinkKey(t,i){const o=t===void 0?"undefined":typeof t=="object"?t.id:t,e=i===void 0?"undefined":typeof i=="object"?i.id:i;return`${o}-${e}`}graphData(t){return this.nodesMap.clear(),this.linkMap.clear(),t.nodes.forEach(i=>{this.nodesMap.has(i.id.toString())||this.nodesMap.set(i.id.toString(),i)}),t.links.forEach(i=>{const o=this.createLinkKey(i.source,i.target);this.linkMap.has(o)||this.linkMap.set(o,i)}),this.data={nodes:Array.from(this.nodesMap.values()),links:Array.from(this.linkMap.values())},this.graph.cooldownTime(this.getCooldownTime()),this.graph.graphData(this.data),this}showGroups(t){return this.options.showGroups=t,t&&Object.entries({groupBy:"topic",groupBorderColor:"#666",groupBorderWidth:2,groupBorderOpacity:.3,groupLabelColor:"#333",groupLabelSize:16,groupLabelThreshold:.8,groupPadding:20}).forEach(([o,e])=>{this.options[o]===void 0&&(this.options[o]=e)}),this.applyOptions(),this.refreshGraph(),this}setGroupBy(t){return this.options.groupBy=t,this.applyOptions(),this.refreshGraph(),this}setGroupOptions(t){return t.borderColor!==void 0&&(this.options.groupBorderColor=t.borderColor),t.borderWidth!==void 0&&(this.options.groupBorderWidth=t.borderWidth),t.borderOpacity!==void 0&&(this.options.groupBorderOpacity=t.borderOpacity),t.labelColor!==void 0&&(this.options.groupLabelColor=t.labelColor),t.labelSize!==void 0&&(this.options.groupLabelSize=t.labelSize),t.labelThreshold!==void 0&&(this.options.groupLabelThreshold=t.labelThreshold),t.padding!==void 0&&(this.options.groupPadding=t.padding),this.applyOptions(),this.refreshGraph(),this}getGroups(){const t=new Set;return this.data.nodes.forEach(i=>{const o=this.getNodeGroupId(i);o&&t.add(o)}),Array.from(t)}getNodesInGroup(t){return this.data.nodes.filter(i=>this.getNodeGroupId(i)===t)}getOptions(){return{...this.options}}destroy(){this.worker&&(this.worker.terminate(),this.worker=null),this.graph._destructor()}}h.ForceGraph=C,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})}));
|
package/dist/index.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ export declare class ForceGraph<TNode extends NodeData & {
|
|
|
40
40
|
private options;
|
|
41
41
|
private worker;
|
|
42
42
|
private groupBounds;
|
|
43
|
+
private isFirstRender;
|
|
43
44
|
constructor(container: HTMLElement, initialData?: GraphData<TNode, TLink>, options?: GraphOptions<TNode, TLink>);
|
|
44
45
|
private initGraph;
|
|
45
46
|
renderer(): default_2<TNode, TLink>;
|
|
@@ -188,6 +189,8 @@ export declare interface GraphOptions<N extends NodeData = NodeData, L extends L
|
|
|
188
189
|
linkDirectionalParticleSpeed?: number | ((link: L) => number);
|
|
189
190
|
linkDirectionalParticleWidth?: number | ((link: L) => number);
|
|
190
191
|
linkDirectionalParticleColor?: string | ((link: L) => string);
|
|
192
|
+
onRenderComplete?: () => void;
|
|
193
|
+
onGraphUpdated?: () => void;
|
|
191
194
|
showGroups?: boolean;
|
|
192
195
|
groupBy?: string | ((node: N) => string | undefined);
|
|
193
196
|
groupBorderColor?: string | ((groupId: string) => string);
|
|
@@ -197,6 +200,8 @@ export declare interface GraphOptions<N extends NodeData = NodeData, L extends L
|
|
|
197
200
|
groupLabelSize?: number;
|
|
198
201
|
groupLabelThreshold?: number;
|
|
199
202
|
groupPadding?: number;
|
|
203
|
+
cooldownTime?: number;
|
|
204
|
+
cooldownTicks?: number;
|
|
200
205
|
}
|
|
201
206
|
|
|
202
207
|
export declare interface LinkData<N extends NodeData = NodeData> extends LinkObject<N> {
|