{"_id":"@1samare/node-tree","_rev":"3-8a76b9021a6098ed49133bfc531cc9be","name":"@1samare/node-tree","dist-tags":{"latest":"0.6.1"},"versions":{"0.1.0":{"name":"@1samare/node-tree","version":"0.1.0","keywords":["tree","layout","vue2","mind-map","org-chart","bidirectional-tree"],"license":"MIT","_id":"@1samare/node-tree@0.1.0","maintainers":[{"name":"1samare","email":"1930768719@qq.com"}],"dist":{"shasum":"d63e20324512d0965348939082882043df4f2074","tarball":"https://registry.npmjs.org/@1samare/node-tree/-/node-tree-0.1.0.tgz","fileCount":24,"integrity":"sha512-eR5P/jtKcYIwAeAGlfSwKKZDilGktvy3QuZjSztJqwPwS8e7UJ+DqC7KPFRN7V8fTV/Ao6zD4T6YXZUpYznCOQ==","signatures":[{"sig":"MEQCIDSLJzF90Nr38Nimi1YJcZQgw0ZKKOebNmYgA58+mmZyAiBfbtrI+zaRrLZbPsC2oWbWReRepgQW2GFmFAnIfw8cvA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":122187},"main":"./dist/node-tree.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/node-tree.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/node-tree.js","require":"./dist/node-tree.cjs"},"./core":{"types":"./dist/types/core/index.d.ts","import":"./dist/core.js"},"./vue2":{"types":"./dist/types/vue2/index.d.ts","import":"./dist/vue2.js"},"./style.css":"./dist/style.css"},"scripts":{"dev":"vite --config playground/vue2/vite.config.ts","test":"vitest run","build":"vite build && npm run build:types","typecheck":"tsc --noEmit","build:types":"tsc -p tsconfig.build.json"},"_npmUser":{"name":"1samare","email":"1930768719@qq.com"},"_npmVersion":"10.9.3","description":"A high-performance bidirectional tree layout component with Vue 2 adapter.","directories":{},"_nodeVersion":"22.18.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^2.7.16","vite":"^4.5.14","vitest":"^0.34.6","typescript":"^5.9.3","vue-template-compiler":"^2.7.16"},"peerDependencies":{"vue":"^2.7.0"},"_npmOperationalInternal":{"tmp":"tmp/node-tree_0.1.0_1781779062468_0.9741428639889504","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@1samare/node-tree","version":"0.6.0","keywords":["tree","layout","vue2","mind-map","org-chart","bidirectional-tree"],"license":"MIT","_id":"@1samare/node-tree@0.6.0","maintainers":[{"name":"1samare","email":"1930768719@qq.com"}],"dist":{"shasum":"f2547b71c6c25365c4036d3d7883bd07cfc77e00","tarball":"https://registry.npmjs.org/@1samare/node-tree/-/node-tree-0.6.0.tgz","fileCount":24,"integrity":"sha512-WxF4Hj8Szyw0DB+z/vqEQYZ/lXp18N3FzbZ/MUaUp9yJjZGbfHtJ3GozrnUwhI7wFFpBXJ7T2wPHKamzIctaFg==","signatures":[{"sig":"MEUCIBx7ELAsXX7vyc3vwhY2+KXEDlsYt5sAAmRzL7DFE6+JAiEAz/AtbxD8WHhpK68dGK/V+GVUyL6TNecI/CX+Irk6EG4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":127464},"main":"./dist/node-tree.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/node-tree.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/node-tree.js","require":"./dist/node-tree.cjs"},"./core":{"types":"./dist/types/core/index.d.ts","import":"./dist/core.js","require":"./dist/core.cjs"},"./vue2":{"types":"./dist/types/vue2/index.d.ts","import":"./dist/vue2.js","require":"./dist/vue2.cjs"},"./style.css":"./dist/style.css"},"gitHead":"fca55967ff3cba8fde09ac15c65708d03ce3eedc","scripts":{"dev":"vite --config playground/vue2/vite.config.ts","test":"vitest run","build":"vite build && npm run build:types","typecheck":"tsc --noEmit","build:types":"tsc -p tsconfig.build.json"},"_npmUser":{"name":"1samare","email":"1930768719@qq.com"},"_npmVersion":"10.9.3","description":"A high-performance bidirectional tree layout component with Vue 2 adapter.","directories":{},"_nodeVersion":"22.18.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^2.7.16","vite":"^4.5.14","vitest":"^0.34.6","typescript":"^5.9.3","vue-template-compiler":"^2.7.16"},"peerDependencies":{"vue":"^2.7.0"},"_npmOperationalInternal":{"tmp":"tmp/node-tree_0.6.0_1782182572682_0.6509056646527207","host":"s3://npm-registry-packages-npm-production"}},"0.6.1":{"name":"@1samare/node-tree","version":"0.6.1","description":"A high-performance bidirectional tree layout component with Vue 2 adapter.","license":"MIT","keywords":["tree","layout","vue2","mind-map","org-chart","bidirectional-tree"],"type":"module","main":"./dist/node-tree.cjs","module":"./dist/node-tree.js","types":"./dist/types/index.d.ts","typesVersions":{"*":{"vue2":["dist/types/vue2/index.d.ts"],"core":["dist/types/core/index.d.ts"]}},"exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/node-tree.js","require":"./dist/node-tree.cjs"},"./core":{"types":"./dist/types/core/index.d.ts","import":"./dist/core.js","require":"./dist/core.cjs"},"./vue2":{"types":"./dist/types/vue2/index.d.ts","import":"./dist/vue2.js","require":"./dist/vue2.cjs"},"./style.css":"./dist/style.css"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"scripts":{"build":"vite build && npm run build:types && npm run build:legacy-shims","build:legacy-shims":"node --input-type=module -e \"import { copyFileSync } from 'node:fs'; copyFileSync('dist/style.css', 'style.css')\"","build:types":"tsc -p tsconfig.build.json","test":"vitest run","typecheck":"tsc --noEmit","dev":"vite --config playground/vue2/vite.config.ts"},"peerDependencies":{"vue":"^2.7.0"},"devDependencies":{"typescript":"^5.9.3","vite":"^4.5.14","vitest":"^0.34.6","vue":"^2.7.16","vue-template-compiler":"^2.7.16"},"_id":"@1samare/node-tree@0.6.1","gitHead":"fca55967ff3cba8fde09ac15c65708d03ce3eedc","_nodeVersion":"22.18.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-nr0B9WEz34doG64pNftwpA3S4JKya9CFaxVQvkoUcyCr8rnJ2snKEH5O/rtFCtlMVMOP9mNUiHWwoMYno9PlFA==","shasum":"3add17f15f1fec7ce1ec806616c7d2d12251190a","tarball":"https://registry.npmjs.org/@1samare/node-tree/-/node-tree-0.6.1.tgz","fileCount":29,"unpackedSize":134420,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCj8qxKn1bwIhAIVK3HIt4sakvqSChtkkkyVpSb601vBwIgIcZhFOU6RlWaWQaQ3xgTiSz6ujwDb8LKGD1vwpaorCw="}]},"_npmUser":{"name":"1samare","email":"1930768719@qq.com"},"directories":{},"maintainers":[{"name":"1samare","email":"1930768719@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/node-tree_0.6.1_1782183523903_0.6507102199736607"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-18T10:37:42.243Z","modified":"2026-06-23T02:58:44.141Z","0.1.0":"2026-06-18T10:37:42.626Z","0.6.0":"2026-06-23T02:42:52.834Z","0.6.1":"2026-06-23T02:58:44.023Z"},"license":"MIT","keywords":["tree","layout","vue2","mind-map","org-chart","bidirectional-tree"],"description":"A high-performance bidirectional tree layout component with Vue 2 adapter.","maintainers":[{"name":"1samare","email":"1930768719@qq.com"}],"readme":"# @1samare/node-tree\n\n高性能双向树布局组件，附带 Vue 2 适配层与纯布局 core。\n\n## 安装\n\n```bash\nnpm install @1samare/node-tree vue@^2.7\n```\n\n## 快速开始\n\n```ts\nimport Vue from 'vue'\nimport NodeTree from '@1samare/node-tree/vue2'\nimport '@1samare/node-tree/style.css'\n\nVue.use(NodeTree)\n```\n\n```html\n<node-tree :data=\"treeData\" layout-direction=\"horizontal\" />\n```\n\n## 引入方式\n\n| 路径 | 说明 |\n|------|------|\n| `@1samare/node-tree` | 默认导出（core + Vue2 组件） |\n| `@1samare/node-tree/vue2` | Vue 2 插件与 `NodeTree` 组件 |\n| `@1samare/node-tree/core` | 纯布局算法（`layoutForest`、`insertTreeNode` 等） |\n| `@1samare/node-tree/style.css` | 组件样式 |\n\n## Props\n\n| Prop | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `data` | `TreeNodeData \\| TreeNodeData[]` | 必填 | 树数据，支持单根或多根（forest） |\n| `layoutDirection` | `'horizontal' \\| 'vertical'` | `'horizontal'` | 布局方向：`horizontal` 左右，`vertical` 上下 |\n| `nodeWidth` | `number` | `320` | 节点宽度 |\n| `nodeMinHeight` | `number` | `72` | 节点最小高度 |\n| `horizontalGap` | `number` | `96` | 层间主轴间距 |\n| `verticalGap` | `number` | `24` | 兄弟节点最小交叉轴间距（最小间隙） |\n| `rootGap` | `number` | `80` | 多根树之间的最小间距 |\n| `padding` | `number` | `48` | 画布内边距 |\n| `scale` | `number` | `1` | 当前缩放比例，支持 `.sync` / `update:scale` |\n| `minScale` | `number` | `0.1` | 最小缩放 |\n| `maxScale` | `number` | `2` | 最大缩放 |\n| `scaleStep` | `number` | `0.1` | 缩放步进 |\n| `zoomable` | `boolean` | `true` | 是否允许缩放；为 `false` 时隐藏缩放 UI、锁定 `scale=1` |\n| `showToolbar` | `boolean` | `true` | 是否显示工具栏（无缩略图时） |\n| `showMiniMap` | `boolean` | `true` | 是否显示缩略图（小地图） |\n| `draggable` | `boolean` | `true` | 是否允许拖拽平移画布 |\n| `allowAdd` | `boolean` | `true` | 是否在连接器上显示「添加子节点」按钮 |\n| `createChildNode` | `(parent, side) => TreeNodeData \\| undefined` | — | 点击添加时自动生成子节点数据 |\n| `loadChildren` | `(node) => Promise<TreeNodeData[]>` | — | 异步加载子节点 |\n| `onAddChild` | `(node, side) => void` | — | 已废弃，请使用 `addNode` 或 `add-node-request` |\n| `collapsedIds` | `string[]` | `[]` | 收起状态 key 列表 |\n| `defaultCollapseChildren` | `boolean` | `true` | 初始是否收起已有子节点 |\n| `virtual` | `boolean` | `true` | 是否启用视口虚拟渲染 |\n| `overscan` | `number` | `240` | 虚拟渲染 overscan 像素 |\n| `initialCenter` | `boolean` | `true` | 挂载后是否自动居中根节点 |\n| `centerDuration` | `number` | `180` | 居中动画时长（ms） |\n\n### 树数据字段\n\n```ts\ninterface TreeNodeData {\n  id: string\n  title: string\n  owner?: string\n  progress?: number\n  status?: 'normal' | 'risk' | 'delayed' | 'unset'\n  hasChild?: boolean\n  leftChildren?: TreeNodeData[]   // horizontal 左侧 / vertical 上方\n  rightChildren?: TreeNodeData[]  // horizontal 右侧 / vertical 下方\n  children?: TreeNodeData[]       // rightChildren 的兼容别名\n}\n```\n\n## Methods（通过 `ref` 调用）\n\n| 方法 | 说明 |\n|------|------|\n| `zoomIn()` | 放大一步（受 `zoomable` 控制） |\n| `zoomOut()` | 缩小一步（受 `zoomable` 控制） |\n| `setScale(scale)` | 设置缩放比例 |\n| `resetView()` | 重置视图（`zoomable` 时恢复 100% 并居中） |\n| `addNode(parentId, side, nodeData)` | 命令式新增子节点，组件内部合并到当前树 |\n| `centerNodeById(nodeId, duration?)` | 将指定节点居中到视口 |\n\n```html\n<node-tree ref=\"tree\" :data=\"treeData\" />\n```\n\n```ts\nthis.$refs.tree.zoomIn()\nthis.$refs.tree.addNode('root-id', 'right', {\n  id: 'new-1',\n  title: '新节点'\n})\n```\n\n## Events\n\n| 事件 | 参数 | 说明 |\n|------|------|------|\n| `node-click` | `(data, layoutNode)` | 点击节点 |\n| `node-added` | `(nodeData, parentId, side)` | 通过 `addNode` 成功添加节点 |\n| `add-node-request` | `(parentData, side)` | 点击添加按钮且未提供 `createChildNode` 时触发 |\n| `update:scale` | `(scale)` | 缩放变化 |\n| `update:collapsedIds` | `(ids)` | 收起状态变化 |\n| `toggle` | `(data, layoutNode, collapsed)` | 展开/收起 |\n| `load-start` / `load-success` / `load-error` | — | 异步加载生命周期 |\n\n## Slots\n\n### `node`（scoped slot）\n\n自定义节点 DOM：\n\n```html\n<node-tree :data=\"treeData\">\n  <template #node=\"{ data, node, toggle, loading, loadChildren, isVisible }\">\n    <div class=\"my-card\">{{ data.title }}</div>\n  </template>\n</node-tree>\n```\n\n## Core API\n\n若只需布局算法：\n\n```ts\nimport { layoutForest, insertTreeNode } from '@1samare/node-tree/core'\n\nconst layout = layoutForest(treeData, {\n  layoutDirection: 'horizontal',\n  nodeWidth: 320,\n  verticalGap: 24\n})\n\nconst nextTree = insertTreeNode(treeData, 'parent-id', 'right', {\n  id: 'child-id',\n  title: 'Child'\n})\n```\n\n## 本地开发\n\n```bash\nnpm install\nnpm run dev      # 启动 playground\nnpm run test     # 运行测试\nnpm run build    # 构建 dist\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}