@logixode/force-graph-lib 0.1.2 → 0.1.3

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@logixode/force-graph-lib",
3
3
  "private": false,
4
- "version": "0.1.2",
4
+ "version": "0.1.3",
5
5
  "description": "Force-directed graph visualization library.",
6
6
  "author": "Rohmad Kurniadi",
7
7
  "license": "MIT",
@@ -19,80 +19,55 @@
19
19
  ],
20
20
  "type": "module",
21
21
  "files": [
22
- "dist/force-graph-lib.es.js",
22
+ "dist/force-graph-lib.js",
23
23
  "dist/force-graph-lib.umd.js",
24
24
  "dist/index.d.ts"
25
25
  ],
26
26
  "main": "./dist/force-graph-lib.umd.js",
27
- "module": "./dist/force-graph-lib.es.js",
27
+ "module": "./dist/force-graph-lib.js",
28
28
  "types": "./dist/index.d.ts",
29
29
  "exports": {
30
30
  ".": {
31
31
  "types": "./dist/index.d.ts",
32
- "import": "./dist/force-graph-lib.es.js",
32
+ "import": "./dist/force-graph-lib.js",
33
33
  "require": "./dist/force-graph-lib.umd.js"
34
34
  }
35
35
  },
36
36
  "scripts": {
37
- "dev": "vite",
38
- "build": "run-p type-check \"build-only {@}\" --",
39
- "build:lib": "VITE_BUILD_TARGET=lib vite build && npx tsc --project tsconfig.lib.json --noEmit",
40
- "preview": "vite preview",
41
- "test:unit": "vitest",
42
- "test:e2e": "playwright test",
43
- "build-only": "vite build",
44
- "type-check": "vue-tsc --build",
45
- "lint": "eslint . --fix",
46
- "format": "prettier --write src/"
37
+ "dev": "bunx --bun vite",
38
+ "build": "bunx --bun vite build && npx tsc --project tsconfig.lib.json --noEmit",
39
+ "preview": "bunx --bun vite preview",
40
+ "docs:dev": "bunx --bun vitepress dev",
41
+ "docs:build": "bunx --bun vitepress build",
42
+ "docs:preview": "bunx --bun vitepress preview"
47
43
  },
48
44
  "dependencies": {
49
- "@formkit/auto-animate": "^0.8.2",
50
- "@tailwindcss/vite": "^4.1.11",
51
- "@tanstack/vue-query": "^5.83.1",
52
- "@vueuse/core": "^13.6.0",
45
+ "@formkit/auto-animate": "^0.9.0",
46
+ "@tanstack/vue-query": "^5.87.1",
47
+ "@types/node": "^24.3.1",
48
+ "@vueuse/core": "^13.9.0",
53
49
  "axios": "^1.11.0",
54
50
  "class-variance-authority": "^0.7.1",
55
51
  "clsx": "^2.1.1",
56
- "d3-force-clustering": "^1.0.0",
57
- "lucide-vue-next": "^0.525.0",
58
- "reka-ui": "^2.4.1",
52
+ "lucide-vue-next": "^0.543.0",
53
+ "reka-ui": "^2.5.0",
59
54
  "tailwind-merge": "^3.3.1",
60
- "tailwindcss": "^4.1.11",
61
- "tw-animate-css": "^1.3.5",
62
- "vue-router": "^4.5.1",
63
- "vue-sonner": "^2.0.2"
55
+ "tw-animate-css": "^1.3.8",
56
+ "vite-plugin-dts": "^4.5.4",
57
+ "vue-sonner": "^2.0.8"
64
58
  },
65
59
  "peerDependencies": {
66
60
  "d3": "^7.9.0",
67
- "force-graph": "^1.50.1",
68
- "vue": "^3.5.17"
61
+ "d3-force-clustering": "^1.0.0",
62
+ "force-graph": "^1.51.1"
69
63
  },
70
64
  "devDependencies": {
71
- "@playwright/test": "^1.53.1",
72
- "@tailwindcss/cli": "^4.1.11",
73
- "@tsconfig/node22": "^22.0.2",
74
65
  "@types/d3": "^7.4.3",
75
- "@types/jsdom": "^21.1.7",
76
- "@types/node": "^22.16.5",
77
- "@vitejs/plugin-vue": "^6.0.0",
78
- "@vitest/eslint-plugin": "^1.2.7",
79
- "@vue/eslint-config-prettier": "^10.2.0",
80
- "@vue/eslint-config-typescript": "^14.5.1",
81
- "@vue/test-utils": "^2.4.6",
82
- "@vue/tsconfig": "^0.7.0",
83
- "eslint": "^9.29.0",
84
- "eslint-plugin-playwright": "^2.2.0",
85
- "eslint-plugin-vue": "~10.2.0",
86
- "jiti": "^2.4.2",
87
- "jsdom": "^26.1.0",
88
- "npm-run-all2": "^8.0.4",
89
- "prettier": "3.5.3",
90
- "typescript": "~5.8.0",
91
- "unplugin-vue-router": "^0.14.0",
92
- "vite": "^7.0.0",
93
- "vite-plugin-dts": "^4.5.4",
94
- "vite-plugin-vue-devtools": "^7.7.7",
95
- "vitest": "^3.2.4",
96
- "vue-tsc": "^2.2.10"
66
+ "autoprefixer": "^10.4.21",
67
+ "postcss": "^8.5.6",
68
+ "tailwindcss": "3",
69
+ "typescript": "~5.8.3",
70
+ "vite": "^7.1.2",
71
+ "vitepress": "^2.0.0-alpha.12"
97
72
  }
98
73
  }
@@ -1,3 +0,0 @@
1
- (function(f,y){typeof exports=="object"&&typeof module<"u"?y(exports,require("force-graph"),require("d3")):typeof define=="function"&&define.amd?define(["exports","force-graph","d3"],y):(f=typeof globalThis<"u"?globalThis:f||self,y(f.ForceGraphLib={},f.ForceGraph,f.d3))})(this,function(f,y,B){"use strict";function G(r){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const i in r)if(i!=="default"){const e=Object.getOwnPropertyDescriptor(r,i);Object.defineProperty(t,i,e.get?e:{enumerable:!0,get:()=>r[i]})}}return t.default=r,Object.freeze(t)}const v=G(B);function w(r,t){(t==null||t>r.length)&&(t=r.length);for(var i=0,e=Array(t);i<t;i++)e[i]=r[i];return e}function A(r){if(Array.isArray(r))return r}function I(r){if(Array.isArray(r))return w(r)}function P(r){if(typeof Symbol<"u"&&r[Symbol.iterator]!=null||r["@@iterator"]!=null)return Array.from(r)}function O(r,t){var i=r==null?null:typeof Symbol<"u"&&r[Symbol.iterator]||r["@@iterator"];if(i!=null){var e,n,a,s,h=[],u=!0,o=!1;try{if(a=(i=i.call(r)).next,t!==0)for(;!(u=(e=a.call(i)).done)&&(h.push(e.value),h.length!==t);u=!0);}catch(l){o=!0,n=l}finally{try{if(!u&&i.return!=null&&(s=i.return(),Object(s)!==s))return}finally{if(o)throw n}}return h}}function z(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.
2
- In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function N(){throw new TypeError(`Invalid attempt to spread non-iterable instance.
3
- In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function L(r,t){return A(r)||O(r,t)||T(r,t)||z()}function M(r){return I(r)||P(r)||T(r)||N()}function T(r,t){if(r){if(typeof r=="string")return w(r,t);var i={}.toString.call(r).slice(8,-1);return i==="Object"&&r.constructor&&(i=r.constructor.name),i==="Map"||i==="Set"?Array.from(r):i==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i)?w(r,t):void 0}}function D(){var r=arguments.length>0&&arguments[0]!==void 0?arguments[0]:function(o){return o.cluster},t,i=[],e=k(1),n=k(.2),a=0,s=new Map;function h(o){var l=new Map(M(s.entries()).map(function(p){var d=L(p,2),m=d[0],b=d[1];return[m,E(b,e,t)]})),g=new Map(M(s.entries()).map(function(p){var d=L(p,2),m=d[0],b=d[1];return[m,n(m,b)]})),c=["x",t>1&&"y",t>2&&"z"].filter(function(p){return p}),C=c.map(function(p){return"v".concat(p)});i.forEach(function(p){var d=r(p);if(l.has(d)){var m=l.get(d),b=c.map(function(S){return m[S]-p[S]});if(!(W.apply(void 0,M(b))<=a)){var x=g.get(d)*o;C.forEach(function(S,F){return p[S]+=b[F]*x})}}})}function u(){s.clear(),i.forEach(function(o){var l=r(o);s.has(l)||s.set(l,[]),s.get(l).push(o)}),s.forEach(function(o,l){return o.length<=1&&s.delete(l)})}return h.initialize=function(o){i=o;for(var l=arguments.length,g=new Array(l>1?l-1:0),c=1;c<l;c++)g[c-1]=arguments[c];t=g.find(function(C){return[1,2,3].includes(C)})||2,u()},h.clusterId=function(o){return arguments.length?(r=o,u(),h):r},h.weight=function(o){return arguments.length?(e=typeof o=="function"?o:k(+o),h):e},h.strength=function(o){return arguments.length?(n=typeof o=="function"?o:k(+o),h):n},h.distanceMin=function(o){return arguments.length?(a=o,h):a},h}function W(r){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,i=arguments.length>2&&arguments[2]!==void 0?arguments[2]:0;return Math.sqrt(r*r+t*t+i*i)}function k(r){return function(){return r}}function E(r,t,i){var e=0,n=0,a=0,s=0;r.forEach(function(u){var o=t(u);n+=u.x*o,i>1&&(a+=u.y*o),i>2&&(s+=u.z*o),e+=o});var h={};return h.x=n/e,i>1&&(h.y=a/e),i>2&&(h.z=s/e),h}class j{container;graph;data={nodes:[],links:[]};nodesMap=new Map;linkMap=new Map;options;worker=null;groupBounds=new Map;constructor(t,i={nodes:[],links:[]},e={}){this.container=t,this.data=i,this.graph=new y(this.container),i.nodes.forEach(s=>{this.nodesMap.set(s.id.toString(),s)});const n={labelThreshold:1.5,showGroups:!1,...e},a=n.showGroups?{groupBy:"topic",groupBorderColor:"#666",groupBorderWidth:2,groupBorderOpacity:.3,groupLabelColor:"#333",groupLabelSize:16,groupLabelThreshold:.8,groupPadding:20}:{};this.options={...n,...a},this.initGraph()}initGraph(){console.log(this.options.width,this.options.width),this.graph.width(this.options.width??800).height(this.options.height??400).onNodeClick(t=>{console.log("Node clicked:",t),this.options.nodeClickHandler&&this.options.nodeClickHandler(t),this.focusPosition({x:t.x,y:t.y})}).cooldownTime(this.calculateCooldownTime()).d3Force("cluster",this.options.cluster?D().clusterId(this.options.cluster):null).d3Force("collide",this.options.collide?v.forceCollide().radius(t=>this.options.collide?this.options.collide(t):t.marker.radius):null),this.options.keepDragPosition&&this.graph.onNodeDragEnd(t=>{t.fx=t.x,t.fy=t.y}),this.graphData(this.data),this.applyOptions(),this.render(),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:e}=this.nodesMap.get(t.id)??{x:0,y:0};i&&e&&(t={x:i,y:e})}t&&(this.graph.centerAt(t.x,t.y,1e3),this.graph.zoom(8,2e3))}}render(){this.graph.d3Force("charge",v.forceManyBody().strength(-100)).d3Force("link",v.forceLink().id(t=>t.index??"").distance(30)).d3Force("center",v.forceCenter())}applyOptions(){this.graph.nodeCanvasObject((t,i,e)=>{t===this.data.nodes[0]&&this.renderGroups(i,e);const n=this.getNodeSize(t)*2,a=typeof this.options.nodeBorderWidth=="function"?this.options.nodeBorderWidth(t):this.options.nodeBorderWidth;i.beginPath(),i.arc(t.x||0,t.y||0,n,0,2*Math.PI),i.fillStyle=this.getNodeColor(t),i.fill(),a&&a>0&&(i.beginPath(),i.arc(t.x||0,t.y||0,n,0,2*Math.PI),i.strokeStyle=this.getNodeBorderColor(t),i.lineWidth=a,i.stroke());const s=this.getNodeLabel(t);if(s&&e>=(this.options.labelThreshold||1.5)){const h=typeof this.options.nodeLabelColor=="function"?this.options.nodeLabelColor(t):this.options.nodeLabelColor??"#555";i.font=`${Math.max(n,8)}px Arial`,i.fillStyle=h,i.textAlign="center",i.textBaseline="middle",i.fillText(s,t.x||0,(t.y||0)+n+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):this.graph.zoom()<(this.options.labelThreshold||1.5)?"":t.label||t.id}updateData(t){const i=new Set(this.data.nodes.map(s=>s.id.toString())),e=t.nodes.filter(s=>!i.has(s.id.toString()));e.forEach(s=>{this.nodesMap.set(s.id.toString(),s)});const n=new Set(this.data.links.map(s=>this.createLinkKey(s.source,s.target))),a=t.links.filter(s=>!n.has(this.createLinkKey(s.source,s.target)));this.data={nodes:[...this.data.nodes,...e],links:[...this.data.links,...a]},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(e=>{const n=this.getNodeGroupId(e);n&&(i.has(n)||i.set(n,[]),i.get(n).push(e))}),i.forEach((e,n)=>{if(e.length===0)return;let a=1/0,s=1/0,h=-1/0,u=-1/0;e.forEach(o=>{if(o.x!==void 0&&o.y!==void 0){const l=this.getNodeSize(o);a=Math.min(a,o.x-l),s=Math.min(s,o.y-l),h=Math.max(h,o.x+l),u=Math.max(u,o.y+l)}}),a!==1/0&&this.groupBounds.set(n,{minX:a-t,minY:s-t,maxX:h+t,maxY:u+t,nodes:e})})}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((e,n)=>{const a=this.getGroupBorderColor(n),s=this.options.groupBorderWidth||2,h=this.options.groupBorderOpacity||.3;t.save(),t.globalAlpha=h,t.strokeStyle=a,t.lineWidth=s/i,t.setLineDash([10/i,5/i]),t.strokeRect(e.minX,e.minY,e.maxX-e.minX,e.maxY-e.minY),t.restore();const u=this.options.groupLabelThreshold||.8;if(i<=u){const o=this.getGroupLabelColor(n),l=(this.options.groupLabelSize||16)/i;t.save(),t.font=`bold ${l}px Arial`,t.fillStyle=o,t.textAlign="center",t.textBaseline="middle";const g=(e.minX+e.maxX)/2,c=e.minY-l/2,p=t.measureText(n).width,d=l;t.globalAlpha=.8,t.fillStyle="rgba(255, 255, 255, 0.9)",t.fillRect(g-p/2-4,c-d/2-2,p+8,d+4),t.globalAlpha=1,t.fillStyle=o,t.fillText(n,g,c),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())}getNodeCount(){return this.nodesMap.size}calculateCooldownTime(){const t=this.data.nodes.length,i=t*5/2,e=Math.max(2500,i);return console.log(`Dynamic Cooldown Time: ${t} nodes × 150ms = ${i}ms, final: ${e}ms`),e}getCooldownTime(){return this.calculateCooldownTime()}updateCooldownTime(){this.graph.cooldownTime(this.calculateCooldownTime())}getLinkCount(){return this.graph.graphData().links.length}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 e=this.nodesMap.get(t.toString());if(e){Object.assign(e,i);const n=this.data.nodes.findIndex(a=>a.id.toString()===t.toString());return n!==-1&&(this.data.nodes[n]=e),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(e=>e.id.toString()!==i),this.data.links=this.data.links.filter(e=>{const n=typeof e.source=="object"?e.source.id:e.source,a=typeof e.target=="object"?e.target.id:e.target;return n.toString()!==i&&a.toString()!==i}),this.graph.cooldownTime(this.calculateCooldownTime()),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 e=this.createLinkKey(i.source,i.target);this.linkMap.has(e)?console.log("link already exists",i):this.linkMap.set(e,i)}),this.data={nodes:Array.from(this.nodesMap.values()),links:Array.from(this.linkMap.values())},console.log("this.data",this.data,t),this.graph.cooldownTime(this.calculateCooldownTime()),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 y(this.container),this.initGraph()}getData(){return this.data}getNodesData(){return this.data.nodes}getLinksData(){return this.data.links}createLinkKey(t,i){const e=typeof t=="object"?t.id:t,n=typeof i=="object"?i.id:i;return`${e}-${n}`}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 e=this.createLinkKey(i.source,i.target);this.linkMap.has(e)||this.linkMap.set(e,i)}),this.data={nodes:Array.from(this.nodesMap.values()),links:Array.from(this.linkMap.values())},this.graph.cooldownTime(this.calculateCooldownTime()),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(([e,n])=>{this.options[e]===void 0&&(this.options[e]=n)}),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 e=this.getNodeGroupId(i);e&&t.add(e)}),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()}}f.ForceGraph=j,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});