@expertrees/angular 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 +144 -0
- package/dist/README.md +144 -0
- package/package.json +9 -3
package/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# @expertrees/angular
|
|
2
|
+
|
|
3
|
+
Angular standalone component 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/angular
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { Component } from '@angular/core'
|
|
15
|
+
import { ExpertreeCanvasComponent } from '@expertrees/angular'
|
|
16
|
+
import type { SkillGraph, SkillNode, NavigationFrame } 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: ['ng'] },
|
|
24
|
+
{ id: 'be', label: 'Backend', depth: 1, parentId: 'eng' },
|
|
25
|
+
{ id: 'ng', label: 'Angular', depth: 2, parentId: 'fe' },
|
|
26
|
+
],
|
|
27
|
+
edges: [],
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@Component({
|
|
31
|
+
standalone: true,
|
|
32
|
+
imports: [ExpertreeCanvasComponent],
|
|
33
|
+
template: `
|
|
34
|
+
<expertree-canvas
|
|
35
|
+
[data]="graph"
|
|
36
|
+
width="100%"
|
|
37
|
+
height="600px"
|
|
38
|
+
(nodeClick)="onNodeClick($event)"
|
|
39
|
+
(contextEnter)="onContextEnter($event)"
|
|
40
|
+
/>
|
|
41
|
+
`,
|
|
42
|
+
})
|
|
43
|
+
export class AppComponent {
|
|
44
|
+
graph = graph
|
|
45
|
+
|
|
46
|
+
onNodeClick(node: SkillNode) {
|
|
47
|
+
console.log('clicked', node.label)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
onContextEnter({ node, stack }: { node: SkillNode; stack: readonly NavigationFrame[] }) {
|
|
51
|
+
console.log('entered', node.label, stack)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Inputs
|
|
57
|
+
|
|
58
|
+
| Input | Type | Default | Description |
|
|
59
|
+
|-------|------|---------|-------------|
|
|
60
|
+
| `data` | `SkillGraph` | required | Graph data |
|
|
61
|
+
| `theme` | `ThemeInput` | — | Visual theme overrides |
|
|
62
|
+
| `lod` | `LodThreshold[]` | — | Level-of-detail config |
|
|
63
|
+
| `initialContextNodeId` | `string` | — | Start inside a specific bubble |
|
|
64
|
+
| `width` | `string` | `'100%'` | Canvas width (CSS) |
|
|
65
|
+
| `height` | `string` | `'100%'` | Canvas height (CSS) |
|
|
66
|
+
|
|
67
|
+
## Outputs
|
|
68
|
+
|
|
69
|
+
| Output | Payload | When |
|
|
70
|
+
|--------|---------|------|
|
|
71
|
+
| `nodeClick` | `SkillNode` | User clicks a node |
|
|
72
|
+
| `nodeHover` | `SkillNode` | Mouse enters a node |
|
|
73
|
+
| `nodeBlur` | `SkillNode` | Mouse leaves a node |
|
|
74
|
+
| `canvasClick` | `void` | Click on empty canvas |
|
|
75
|
+
| `zoomChange` | `number` | Every zoom frame |
|
|
76
|
+
| `contextEnter` | `{ node: SkillNode, stack: readonly NavigationFrame[] }` | Entering a bubble |
|
|
77
|
+
| `contextExit` | `{ frame: NavigationFrame, stack: readonly NavigationFrame[] }` | Exiting a bubble |
|
|
78
|
+
| `graphReady` | `SkillGraph` | Engine mounted and ready |
|
|
79
|
+
|
|
80
|
+
## Imperative API via template ref
|
|
81
|
+
|
|
82
|
+
Access engine methods directly through a template reference variable.
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
@Component({
|
|
86
|
+
standalone: true,
|
|
87
|
+
imports: [ExpertreeCanvasComponent],
|
|
88
|
+
template: `
|
|
89
|
+
<expertree-canvas #tree [data]="graph" width="100%" height="600px" />
|
|
90
|
+
|
|
91
|
+
<!-- Breadcrumbs -->
|
|
92
|
+
<nav>
|
|
93
|
+
<button
|
|
94
|
+
*ngFor="let frame of navStack; let i = index"
|
|
95
|
+
(click)="tree.jumpToNavDepth(i + 1)"
|
|
96
|
+
>
|
|
97
|
+
{{ frame.label }}
|
|
98
|
+
</button>
|
|
99
|
+
</nav>
|
|
100
|
+
|
|
101
|
+
<button (click)="tree.setNodeState('ng', 'unlocked')">Unlock Angular</button>
|
|
102
|
+
<button (click)="tree.goBack()">Back</button>
|
|
103
|
+
`,
|
|
104
|
+
})
|
|
105
|
+
export class AppComponent {
|
|
106
|
+
graph = graph
|
|
107
|
+
navStack: NavigationFrame[] = []
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Template ref methods
|
|
112
|
+
|
|
113
|
+
| Method | Signature | Description |
|
|
114
|
+
|--------|-----------|-------------|
|
|
115
|
+
| `setNodeState` | `(id, NodeState) => void` | Update a node's semantic state |
|
|
116
|
+
| `addEvidence` | `(id, Evidence) => void` | Attach evidence to a node |
|
|
117
|
+
| `removeEvidence` | `(id, evidenceId) => void` | Remove evidence |
|
|
118
|
+
| `updateTheme` | `(ThemeInput) => void` | Hot-swap the visual theme |
|
|
119
|
+
| `zoomIn` | `() => void` | Programmatic zoom in |
|
|
120
|
+
| `zoomOut` | `() => void` | Programmatic zoom out |
|
|
121
|
+
| `goBack` | `() => void` | Exit to parent context |
|
|
122
|
+
| `enterContext` | `(nodeId) => void` | Programmatically enter a bubble |
|
|
123
|
+
| `jumpToNavDepth` | `(targetLength) => void` | Jump to stack depth in one animation |
|
|
124
|
+
| `getGraph` | `() => SkillGraph` | Serialize current graph state |
|
|
125
|
+
| `getNavigationStack` | `() => readonly NavigationFrame[]` | Current navigation stack |
|
|
126
|
+
|
|
127
|
+
## NgModule setup
|
|
128
|
+
|
|
129
|
+
If you are not using standalone components, import via a module:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { NgModule } from '@angular/core'
|
|
133
|
+
import { ExpertreeCanvasComponent } from '@expertrees/angular'
|
|
134
|
+
|
|
135
|
+
@NgModule({
|
|
136
|
+
imports: [ExpertreeCanvasComponent],
|
|
137
|
+
// ...
|
|
138
|
+
})
|
|
139
|
+
export class AppModule {}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
MIT — [github.com/0xMack/expertrees](https://github.com/0xMack/expertrees)
|
package/dist/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# @expertrees/angular
|
|
2
|
+
|
|
3
|
+
Angular standalone component 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/angular
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { Component } from '@angular/core'
|
|
15
|
+
import { ExpertreeCanvasComponent } from '@expertrees/angular'
|
|
16
|
+
import type { SkillGraph, SkillNode, NavigationFrame } 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: ['ng'] },
|
|
24
|
+
{ id: 'be', label: 'Backend', depth: 1, parentId: 'eng' },
|
|
25
|
+
{ id: 'ng', label: 'Angular', depth: 2, parentId: 'fe' },
|
|
26
|
+
],
|
|
27
|
+
edges: [],
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@Component({
|
|
31
|
+
standalone: true,
|
|
32
|
+
imports: [ExpertreeCanvasComponent],
|
|
33
|
+
template: `
|
|
34
|
+
<expertree-canvas
|
|
35
|
+
[data]="graph"
|
|
36
|
+
width="100%"
|
|
37
|
+
height="600px"
|
|
38
|
+
(nodeClick)="onNodeClick($event)"
|
|
39
|
+
(contextEnter)="onContextEnter($event)"
|
|
40
|
+
/>
|
|
41
|
+
`,
|
|
42
|
+
})
|
|
43
|
+
export class AppComponent {
|
|
44
|
+
graph = graph
|
|
45
|
+
|
|
46
|
+
onNodeClick(node: SkillNode) {
|
|
47
|
+
console.log('clicked', node.label)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
onContextEnter({ node, stack }: { node: SkillNode; stack: readonly NavigationFrame[] }) {
|
|
51
|
+
console.log('entered', node.label, stack)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Inputs
|
|
57
|
+
|
|
58
|
+
| Input | Type | Default | Description |
|
|
59
|
+
|-------|------|---------|-------------|
|
|
60
|
+
| `data` | `SkillGraph` | required | Graph data |
|
|
61
|
+
| `theme` | `ThemeInput` | — | Visual theme overrides |
|
|
62
|
+
| `lod` | `LodThreshold[]` | — | Level-of-detail config |
|
|
63
|
+
| `initialContextNodeId` | `string` | — | Start inside a specific bubble |
|
|
64
|
+
| `width` | `string` | `'100%'` | Canvas width (CSS) |
|
|
65
|
+
| `height` | `string` | `'100%'` | Canvas height (CSS) |
|
|
66
|
+
|
|
67
|
+
## Outputs
|
|
68
|
+
|
|
69
|
+
| Output | Payload | When |
|
|
70
|
+
|--------|---------|------|
|
|
71
|
+
| `nodeClick` | `SkillNode` | User clicks a node |
|
|
72
|
+
| `nodeHover` | `SkillNode` | Mouse enters a node |
|
|
73
|
+
| `nodeBlur` | `SkillNode` | Mouse leaves a node |
|
|
74
|
+
| `canvasClick` | `void` | Click on empty canvas |
|
|
75
|
+
| `zoomChange` | `number` | Every zoom frame |
|
|
76
|
+
| `contextEnter` | `{ node: SkillNode, stack: readonly NavigationFrame[] }` | Entering a bubble |
|
|
77
|
+
| `contextExit` | `{ frame: NavigationFrame, stack: readonly NavigationFrame[] }` | Exiting a bubble |
|
|
78
|
+
| `graphReady` | `SkillGraph` | Engine mounted and ready |
|
|
79
|
+
|
|
80
|
+
## Imperative API via template ref
|
|
81
|
+
|
|
82
|
+
Access engine methods directly through a template reference variable.
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
@Component({
|
|
86
|
+
standalone: true,
|
|
87
|
+
imports: [ExpertreeCanvasComponent],
|
|
88
|
+
template: `
|
|
89
|
+
<expertree-canvas #tree [data]="graph" width="100%" height="600px" />
|
|
90
|
+
|
|
91
|
+
<!-- Breadcrumbs -->
|
|
92
|
+
<nav>
|
|
93
|
+
<button
|
|
94
|
+
*ngFor="let frame of navStack; let i = index"
|
|
95
|
+
(click)="tree.jumpToNavDepth(i + 1)"
|
|
96
|
+
>
|
|
97
|
+
{{ frame.label }}
|
|
98
|
+
</button>
|
|
99
|
+
</nav>
|
|
100
|
+
|
|
101
|
+
<button (click)="tree.setNodeState('ng', 'unlocked')">Unlock Angular</button>
|
|
102
|
+
<button (click)="tree.goBack()">Back</button>
|
|
103
|
+
`,
|
|
104
|
+
})
|
|
105
|
+
export class AppComponent {
|
|
106
|
+
graph = graph
|
|
107
|
+
navStack: NavigationFrame[] = []
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Template ref methods
|
|
112
|
+
|
|
113
|
+
| Method | Signature | Description |
|
|
114
|
+
|--------|-----------|-------------|
|
|
115
|
+
| `setNodeState` | `(id, NodeState) => void` | Update a node's semantic state |
|
|
116
|
+
| `addEvidence` | `(id, Evidence) => void` | Attach evidence to a node |
|
|
117
|
+
| `removeEvidence` | `(id, evidenceId) => void` | Remove evidence |
|
|
118
|
+
| `updateTheme` | `(ThemeInput) => void` | Hot-swap the visual theme |
|
|
119
|
+
| `zoomIn` | `() => void` | Programmatic zoom in |
|
|
120
|
+
| `zoomOut` | `() => void` | Programmatic zoom out |
|
|
121
|
+
| `goBack` | `() => void` | Exit to parent context |
|
|
122
|
+
| `enterContext` | `(nodeId) => void` | Programmatically enter a bubble |
|
|
123
|
+
| `jumpToNavDepth` | `(targetLength) => void` | Jump to stack depth in one animation |
|
|
124
|
+
| `getGraph` | `() => SkillGraph` | Serialize current graph state |
|
|
125
|
+
| `getNavigationStack` | `() => readonly NavigationFrame[]` | Current navigation stack |
|
|
126
|
+
|
|
127
|
+
## NgModule setup
|
|
128
|
+
|
|
129
|
+
If you are not using standalone components, import via a module:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { NgModule } from '@angular/core'
|
|
133
|
+
import { ExpertreeCanvasComponent } from '@expertrees/angular'
|
|
134
|
+
|
|
135
|
+
@NgModule({
|
|
136
|
+
imports: [ExpertreeCanvasComponent],
|
|
137
|
+
// ...
|
|
138
|
+
})
|
|
139
|
+
export class AppModule {}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
MIT — [github.com/0xMack/expertrees](https://github.com/0xMack/expertrees)
|
package/package.json
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expertrees/angular",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Angular component for @expertrees/core",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"files": [
|
|
7
|
-
"dist"
|
|
7
|
+
"dist",
|
|
8
|
+
"README.md"
|
|
8
9
|
],
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/0xMack/expertrees.git",
|
|
13
|
+
"directory": "packages/angular"
|
|
14
|
+
},
|
|
9
15
|
"publishConfig": {
|
|
10
16
|
"access": "public"
|
|
11
17
|
},
|
|
@@ -24,7 +30,7 @@
|
|
|
24
30
|
"peerDependencies": {
|
|
25
31
|
"@angular/common": ">=17.0.0",
|
|
26
32
|
"@angular/core": ">=17.0.0",
|
|
27
|
-
"@expertrees/core": ">=0.1.
|
|
33
|
+
"@expertrees/core": ">=0.1.1"
|
|
28
34
|
},
|
|
29
35
|
"devDependencies": {
|
|
30
36
|
"@angular/common": "^17.0.0",
|