@expertrees/vue 0.1.0 → 0.1.1
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/README.md +163 -0
- package/package.json +17 -3
package/README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# @expertrees/vue
|
|
2
|
+
|
|
3
|
+
Vue 3 component and composable for [@expertrees/core](https://www.npmjs.com/package/@expertrees/core) — a hierarchical knowledge graph visualizer with a star map aesthetic.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm add @expertrees/core @expertrees/vue
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Component usage
|
|
12
|
+
|
|
13
|
+
```vue
|
|
14
|
+
<script setup lang="ts">
|
|
15
|
+
import { SkillTree } from '@expertrees/vue'
|
|
16
|
+
import type { SkillGraph } from '@expertrees/core'
|
|
17
|
+
|
|
18
|
+
const graph: SkillGraph = {
|
|
19
|
+
id: 'my-skills',
|
|
20
|
+
label: 'My Skills',
|
|
21
|
+
nodes: [
|
|
22
|
+
{ id: 'eng', label: 'Engineering', depth: 0, childIds: ['fe', 'be'] },
|
|
23
|
+
{ id: 'fe', label: 'Frontend', depth: 1, parentId: 'eng', childIds: ['vue'] },
|
|
24
|
+
{ id: 'be', label: 'Backend', depth: 1, parentId: 'eng' },
|
|
25
|
+
{ id: 'vue', label: 'Vue 3', depth: 2, parentId: 'fe' },
|
|
26
|
+
],
|
|
27
|
+
edges: [],
|
|
28
|
+
}
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<template>
|
|
32
|
+
<SkillTree
|
|
33
|
+
:data="graph"
|
|
34
|
+
style="width: 100%; height: 600px"
|
|
35
|
+
@node:click="node => console.log(node)"
|
|
36
|
+
@context:enter="(node, stack) => console.log('entered', node.label)"
|
|
37
|
+
/>
|
|
38
|
+
</template>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Component props
|
|
42
|
+
|
|
43
|
+
| Prop | Type | Default | Description |
|
|
44
|
+
|------|------|---------|-------------|
|
|
45
|
+
| `data` | `SkillGraph` | required | Graph data |
|
|
46
|
+
| `theme` | `ThemeInput` | — | Visual theme overrides |
|
|
47
|
+
| `lod` | `LodThreshold[]` | — | Level-of-detail config |
|
|
48
|
+
| `initialContextNodeId` | `string` | — | Start inside a specific bubble |
|
|
49
|
+
|
|
50
|
+
### Component events
|
|
51
|
+
|
|
52
|
+
| Event | Payload | When |
|
|
53
|
+
|-------|---------|------|
|
|
54
|
+
| `node:click` | `SkillNode` | User clicks a node |
|
|
55
|
+
| `node:hover` | `SkillNode` | Mouse enters a node |
|
|
56
|
+
| `node:blur` | `SkillNode` | Mouse leaves a node |
|
|
57
|
+
| `canvas:click` | — | Click on empty canvas |
|
|
58
|
+
| `zoom:change` | `number` | Every zoom frame |
|
|
59
|
+
| `context:enter` | `(SkillNode, NavigationFrame[])` | Entering a bubble |
|
|
60
|
+
| `context:exit` | `(NavigationFrame, NavigationFrame[])` | Exiting a bubble |
|
|
61
|
+
| `graph:ready` | `SkillGraph` | Engine mounted and ready |
|
|
62
|
+
|
|
63
|
+
### Imperative ref API
|
|
64
|
+
|
|
65
|
+
```vue
|
|
66
|
+
<script setup lang="ts">
|
|
67
|
+
import { ref } from 'vue'
|
|
68
|
+
import { SkillTree } from '@expertrees/vue'
|
|
69
|
+
|
|
70
|
+
const tree = ref()
|
|
71
|
+
|
|
72
|
+
function unlock() {
|
|
73
|
+
tree.value.setNodeState('vue', 'unlocked')
|
|
74
|
+
}
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<template>
|
|
78
|
+
<SkillTree ref="tree" :data="graph" style="width: 100%; height: 600px" />
|
|
79
|
+
<button @click="unlock">Unlock Vue</button>
|
|
80
|
+
</template>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Composable usage
|
|
86
|
+
|
|
87
|
+
Use `useSkillTree` directly for full control over the canvas and layout.
|
|
88
|
+
|
|
89
|
+
```vue
|
|
90
|
+
<script setup lang="ts">
|
|
91
|
+
import { useSkillTree } from '@expertrees/vue'
|
|
92
|
+
import type { SkillGraph } from '@expertrees/core'
|
|
93
|
+
|
|
94
|
+
declare const graph: SkillGraph
|
|
95
|
+
|
|
96
|
+
const {
|
|
97
|
+
canvasRef,
|
|
98
|
+
hoveredNode,
|
|
99
|
+
selectedNode,
|
|
100
|
+
zoom,
|
|
101
|
+
navigationStack,
|
|
102
|
+
canGoBack,
|
|
103
|
+
goBack,
|
|
104
|
+
jumpToNavDepth,
|
|
105
|
+
setNodeState,
|
|
106
|
+
enterContext,
|
|
107
|
+
} = useSkillTree({
|
|
108
|
+
data: graph,
|
|
109
|
+
on: {
|
|
110
|
+
'node:click': node => console.log(node),
|
|
111
|
+
},
|
|
112
|
+
})
|
|
113
|
+
</script>
|
|
114
|
+
|
|
115
|
+
<template>
|
|
116
|
+
<div style="position: relative; width: 100%; height: 600px">
|
|
117
|
+
<canvas ref="canvasRef" style="width: 100%; height: 100%" />
|
|
118
|
+
|
|
119
|
+
<!-- Breadcrumbs -->
|
|
120
|
+
<nav style="position: absolute; top: 8px; left: 8px">
|
|
121
|
+
<button
|
|
122
|
+
v-for="(frame, i) in navigationStack"
|
|
123
|
+
:key="frame.nodeId ?? 'root'"
|
|
124
|
+
@click="jumpToNavDepth(i + 1)"
|
|
125
|
+
>
|
|
126
|
+
{{ frame.label }}
|
|
127
|
+
</button>
|
|
128
|
+
</nav>
|
|
129
|
+
|
|
130
|
+
<!-- Side panel -->
|
|
131
|
+
<aside v-if="hoveredNode" style="position: absolute; right: 0; top: 0">
|
|
132
|
+
<h3>{{ hoveredNode.label }}</h3>
|
|
133
|
+
</aside>
|
|
134
|
+
</div>
|
|
135
|
+
</template>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### `useSkillTree` return values
|
|
139
|
+
|
|
140
|
+
| Name | Type | Description |
|
|
141
|
+
|------|------|-------------|
|
|
142
|
+
| `canvasRef` | `Ref<HTMLCanvasElement \| null>` | Bind to `<canvas ref="canvasRef">` |
|
|
143
|
+
| `hoveredNode` | `Ref<SkillNode \| null>` | Currently hovered node |
|
|
144
|
+
| `selectedNode` | `Ref<SkillNode \| null>` | Currently selected node |
|
|
145
|
+
| `zoom` | `Ref<number>` | Current zoom level |
|
|
146
|
+
| `navigationStack` | `Ref<readonly NavigationFrame[]>` | Full nav stack; last entry is active context |
|
|
147
|
+
| `canGoBack` | `ComputedRef<boolean>` | Whether a parent context exists |
|
|
148
|
+
| `goBack()` | `() => void` | Exit to parent context |
|
|
149
|
+
| `jumpToNavDepth(n)` | `(number) => void` | Jump to stack depth `n` in one animation |
|
|
150
|
+
| `enterContext(id)` | `(string) => void` | Programmatically enter a bubble |
|
|
151
|
+
| `setNodeState(id, state)` | `(string, NodeState) => void` | Update a node's semantic state |
|
|
152
|
+
| `addEvidence(id, ev)` | `(string, Evidence) => void` | Attach evidence to a node |
|
|
153
|
+
| `removeEvidence(id, evId)` | `(string, string) => void` | Remove evidence |
|
|
154
|
+
| `updateTheme(theme)` | `(ThemeInput) => void` | Hot-swap the visual theme |
|
|
155
|
+
| `zoomIn()` | `() => void` | Programmatic zoom in |
|
|
156
|
+
| `zoomOut()` | `() => void` | Programmatic zoom out |
|
|
157
|
+
| `getGraph()` | `() => SkillGraph` | Serialize current graph state |
|
|
158
|
+
|
|
159
|
+
The composable is **reactive to `data` changes** — passing a new `SkillGraph` reference reinitializes the engine automatically.
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
MIT — [github.com/0xMack/expertrees](https://github.com/0xMack/expertrees)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expertrees/vue",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Vue 3 component and composable for @expertrees/core",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -14,11 +14,25 @@
|
|
|
14
14
|
"require": "./dist/index.cjs"
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
|
-
"files": [
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/0xMack/expertrees.git",
|
|
24
|
+
"directory": "packages/vue"
|
|
25
|
+
},
|
|
18
26
|
"publishConfig": {
|
|
19
27
|
"access": "public"
|
|
20
28
|
},
|
|
21
|
-
"keywords": [
|
|
29
|
+
"keywords": [
|
|
30
|
+
"knowledge-graph",
|
|
31
|
+
"skill-tree",
|
|
32
|
+
"vue",
|
|
33
|
+
"vue3",
|
|
34
|
+
"visualization"
|
|
35
|
+
],
|
|
22
36
|
"scripts": {
|
|
23
37
|
"build": "vite build",
|
|
24
38
|
"dev": "vite build --watch",
|