vizcraft 0.3.0 → 1.0.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/CHANGELOG.md +6 -0
- package/LICENSE.txt +21 -0
- package/README.md +104 -2
- package/dist/builder.d.ts +62 -2
- package/dist/builder.js +605 -106
- package/dist/edgeLabels.d.ts +15 -0
- package/dist/edgeLabels.js +26 -0
- package/dist/edgePaths.d.ts +43 -0
- package/dist/edgePaths.js +253 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/runtimePatcher.d.ts +3 -3
- package/dist/runtimePatcher.js +231 -31
- package/dist/shapes.d.ts +25 -3
- package/dist/shapes.js +1009 -0
- package/dist/styles.d.ts +1 -1
- package/dist/styles.js +24 -0
- package/dist/types.d.ts +179 -1
- package/package.json +1 -1
- package/dist/anim/player.test.d.ts +0 -1
- package/dist/anim/player.test.js +0 -49
- package/dist/index.test.d.ts +0 -1
- package/dist/index.test.js +0 -66
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# vizcraft
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [`73ee1fb`](https://github.com/ChipiKaf/vizcraft/commit/73ee1fbd204bf1ba0447c764eba2c1b9d6981ee5) Thanks [@ChipiKaf](https://github.com/ChipiKaf)! - Added new shapes, connection ports, path based edges, Edge marker types, Multi-position edge labels, Containers and The overlay builder
|
|
8
|
+
|
|
3
9
|
## 0.3.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Chipili Kafwilo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -101,15 +101,54 @@ b.node('n1')
|
|
|
101
101
|
.at(x, y) // Absolute position
|
|
102
102
|
// OR
|
|
103
103
|
.cell(col, row) // Grid position
|
|
104
|
-
.circle(radius) //
|
|
104
|
+
.circle(radius) // Circle shape
|
|
105
|
+
.rect(w, h, [rx]) // Rectangle (optional corner radius)
|
|
106
|
+
.diamond(w, h) // Diamond shape
|
|
107
|
+
.cylinder(w, h, [arcHeight]) // Cylinder (database symbol)
|
|
108
|
+
.hexagon(r, [orientation]) // Hexagon ('pointy' or 'flat')
|
|
109
|
+
.ellipse(rx, ry) // Ellipse / oval
|
|
110
|
+
.arc(r, start, end, [closed]) // Arc / pie slice
|
|
111
|
+
.blockArrow(len, bodyW, headW, headLen, [dir]) // Block arrow
|
|
112
|
+
.callout(w, h, [opts]) // Speech bubble / callout
|
|
113
|
+
.cloud(w, h) // Cloud / thought bubble
|
|
114
|
+
.cross(size, [barWidth]) // Cross / plus sign
|
|
115
|
+
.cube(w, h, [depth]) // 3D isometric cube
|
|
116
|
+
.path(d, w, h) // Custom SVG path
|
|
117
|
+
.document(w, h, [wave]) // Document (wavy bottom)
|
|
118
|
+
.note(w, h, [foldSize]) // Note (folded corner)
|
|
119
|
+
.parallelogram(w, h, [skew]) // Parallelogram (I/O)
|
|
120
|
+
.star(points, outerR, [innerR]) // Star / badge
|
|
121
|
+
.trapezoid(topW, bottomW, h) // Trapezoid
|
|
122
|
+
.triangle(w, h, [direction]) // Triangle
|
|
105
123
|
.label('Text', { dy: 5 }) // Label with offset
|
|
106
124
|
.class('css-class') // Custom CSS class
|
|
107
125
|
.data({ ... }) // Attach custom data
|
|
126
|
+
.port('out', { x: 50, y: 0 }) // Named connection port
|
|
127
|
+
.container(config?) // Mark as container / group node
|
|
128
|
+
.parent('containerId') // Make child of a container
|
|
108
129
|
```
|
|
109
130
|
|
|
131
|
+
### Container / Group Nodes
|
|
132
|
+
|
|
133
|
+
Group related nodes into visual containers (swimlanes, sub-processes, etc.).
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
b.node('lane')
|
|
137
|
+
.at(250, 170)
|
|
138
|
+
.rect(460, 300)
|
|
139
|
+
.label('Process Phase')
|
|
140
|
+
.container({ headerHeight: 36 });
|
|
141
|
+
|
|
142
|
+
b.node('step1').at(150, 220).rect(100, 50).parent('lane');
|
|
143
|
+
b.node('step2').at(350, 220).rect(100, 50).parent('lane');
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Container children are nested inside the container `<g>` in the SVG and follow the container when moved at runtime.
|
|
147
|
+
|
|
110
148
|
### Edges
|
|
111
149
|
|
|
112
150
|
Edges connect nodes and can be styled, directed, or animated.
|
|
151
|
+
All edges are rendered as `<path>` elements supporting three routing modes.
|
|
113
152
|
|
|
114
153
|
```typescript
|
|
115
154
|
b.edge('n1', 'n2')
|
|
@@ -117,8 +156,65 @@ b.edge('n1', 'n2')
|
|
|
117
156
|
.straight() // (Default) Straight line
|
|
118
157
|
.label('Connection')
|
|
119
158
|
.animate('flow'); // Add animation
|
|
159
|
+
|
|
160
|
+
// Curved edge
|
|
161
|
+
b.edge('a', 'b').curved().arrow();
|
|
162
|
+
|
|
163
|
+
// Orthogonal (right-angle) edge
|
|
164
|
+
b.edge('a', 'c').orthogonal().arrow();
|
|
165
|
+
|
|
166
|
+
// Waypoints — intermediate points the edge passes through
|
|
167
|
+
b.edge('x', 'y').curved().via(150, 50).via(200, 100).arrow();
|
|
168
|
+
|
|
169
|
+
// Per-edge styling (overrides CSS defaults)
|
|
170
|
+
b.edge('a', 'b').stroke('#ff0000', 3).fill('none').opacity(0.8);
|
|
171
|
+
|
|
172
|
+
// Multi-position edge labels (start / mid / end)
|
|
173
|
+
b.edge('a', 'b')
|
|
174
|
+
.label('1', { position: 'start' })
|
|
175
|
+
.label('*', { position: 'end' })
|
|
176
|
+
.arrow();
|
|
177
|
+
|
|
178
|
+
// Edge markers / arrowhead types
|
|
179
|
+
b.edge('a', 'b').markerEnd('arrowOpen'); // Open arrow (inheritance)
|
|
180
|
+
b.edge('a', 'b').markerStart('diamond').markerEnd('arrow'); // UML composition
|
|
181
|
+
b.edge('a', 'b').markerStart('diamondOpen').markerEnd('arrow'); // UML aggregation
|
|
182
|
+
b.edge('a', 'b').arrow('both'); // Bidirectional arrows
|
|
183
|
+
b.edge('a', 'b').markerStart('circleOpen').markerEnd('arrow'); // Association
|
|
184
|
+
b.edge('a', 'b').markerEnd('bar'); // ER cardinality
|
|
185
|
+
|
|
186
|
+
// Connection ports — edges attach to specific points on nodes
|
|
187
|
+
b.node('srv')
|
|
188
|
+
.at(100, 100)
|
|
189
|
+
.rect(80, 60)
|
|
190
|
+
.port('out-1', { x: 40, y: -15 })
|
|
191
|
+
.port('out-2', { x: 40, y: 15 });
|
|
192
|
+
b.node('db').at(400, 100).cylinder(80, 60).port('in', { x: -40, y: 0 });
|
|
193
|
+
b.edge('srv', 'db').fromPort('out-1').toPort('in').arrow();
|
|
194
|
+
|
|
195
|
+
// Default ports (no .port() needed) — every shape has built-in ports
|
|
196
|
+
b.edge('a', 'b').fromPort('right').toPort('left').arrow();
|
|
120
197
|
```
|
|
121
198
|
|
|
199
|
+
| Method | Description |
|
|
200
|
+
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
201
|
+
| `.straight()` | Direct line (default). With waypoints → polyline. |
|
|
202
|
+
| `.curved()` | Smooth bezier curve. With waypoints → Catmull-Rom spline. |
|
|
203
|
+
| `.orthogonal()` | Right-angle elbows. |
|
|
204
|
+
| `.routing(mode)` | Set mode programmatically. |
|
|
205
|
+
| `.via(x, y)` | Add an intermediate waypoint (chainable). |
|
|
206
|
+
| `.label(text, opts?)` | Add a text label. Chain multiple calls for multi-position labels. `opts.position` can be `'start'`, `'mid'` (default), or `'end'`. |
|
|
207
|
+
| `.arrow([enabled])` | Shorthand for arrow markers. `true`/no-arg → markerEnd arrow. `'both'` → both ends. `'start'`/`'end'` → specific end. `false` → none. |
|
|
208
|
+
| `.markerEnd(type)` | Set marker type at the target end. See `EdgeMarkerType`. |
|
|
209
|
+
| `.markerStart(type)` | Set marker type at the source end. See `EdgeMarkerType`. |
|
|
210
|
+
| `.fromPort(portId)` | Connect from a specific named port on the source node. |
|
|
211
|
+
| `.toPort(portId)` | Connect to a specific named port on the target node. |
|
|
212
|
+
| `.stroke(color, width?)` | Set stroke color and optional width. |
|
|
213
|
+
| `.fill(color)` | Set fill color. |
|
|
214
|
+
| `.opacity(value)` | Set opacity (0–1). |
|
|
215
|
+
|
|
216
|
+
**`EdgeMarkerType`** values: `'none'`, `'arrow'`, `'arrowOpen'`, `'diamond'`, `'diamondOpen'`, `'circle'`, `'circleOpen'`, `'square'`, `'bar'`, `'halfArrow'`.
|
|
217
|
+
|
|
122
218
|
### Animations
|
|
123
219
|
|
|
124
220
|
See the full Animations guide [docs here](https://vizcraft-docs.vercel.app/docs/animations).
|
|
@@ -265,13 +361,19 @@ VizCraft generates standard SVG elements with predictable classes, making it eas
|
|
|
265
361
|
fill: #ff6b6b;
|
|
266
362
|
}
|
|
267
363
|
|
|
268
|
-
/* Edge styling */
|
|
364
|
+
/* Edge styling (CSS defaults) */
|
|
269
365
|
.viz-edge {
|
|
270
366
|
stroke: #ccc;
|
|
271
367
|
stroke-width: 2;
|
|
272
368
|
}
|
|
273
369
|
```
|
|
274
370
|
|
|
371
|
+
Edges can also be styled **per-edge** via the builder (inline SVG attributes override CSS):
|
|
372
|
+
|
|
373
|
+
```ts
|
|
374
|
+
b.edge('a', 'b').stroke('#e74c3c', 3).fill('none').opacity(0.8);
|
|
375
|
+
```
|
|
376
|
+
|
|
275
377
|
## 🤝 Contributing
|
|
276
378
|
|
|
277
379
|
Contributions are welcome! This is a monorepo managed with Turbo.
|
package/dist/builder.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { VizScene, VizNode, VizEdge, NodeLabel, EdgeLabel, AnimationConfig, OverlayId, OverlayParams, VizGridConfig } from './types';
|
|
1
|
+
import type { VizScene, VizNode, VizEdge, NodeLabel, EdgeLabel, AnimationConfig, OverlayId, OverlayParams, VizGridConfig, ContainerConfig, EdgeRouting, EdgeMarkerType } from './types';
|
|
2
2
|
import { OverlayBuilder } from './overlayBuilder';
|
|
3
3
|
import type { AnimationSpec } from './anim/spec';
|
|
4
4
|
import { type AnimationBuilder, type AnimatableProps, type TweenOptions } from './anim/animationBuilder';
|
|
@@ -57,6 +57,28 @@ interface NodeBuilder {
|
|
|
57
57
|
circle(r: number): NodeBuilder;
|
|
58
58
|
rect(w: number, h: number, rx?: number): NodeBuilder;
|
|
59
59
|
diamond(w: number, h: number): NodeBuilder;
|
|
60
|
+
cylinder(w: number, h: number, arcHeight?: number): NodeBuilder;
|
|
61
|
+
hexagon(r: number, orientation?: 'pointy' | 'flat'): NodeBuilder;
|
|
62
|
+
ellipse(rx: number, ry: number): NodeBuilder;
|
|
63
|
+
arc(r: number, startAngle: number, endAngle: number, closed?: boolean): NodeBuilder;
|
|
64
|
+
blockArrow(length: number, bodyWidth: number, headWidth: number, headLength: number, direction?: 'right' | 'left' | 'up' | 'down'): NodeBuilder;
|
|
65
|
+
callout(w: number, h: number, opts?: {
|
|
66
|
+
rx?: number;
|
|
67
|
+
pointerSide?: 'bottom' | 'top' | 'left' | 'right';
|
|
68
|
+
pointerHeight?: number;
|
|
69
|
+
pointerWidth?: number;
|
|
70
|
+
pointerPosition?: number;
|
|
71
|
+
}): NodeBuilder;
|
|
72
|
+
cloud(w: number, h: number): NodeBuilder;
|
|
73
|
+
cross(size: number, barWidth?: number): NodeBuilder;
|
|
74
|
+
cube(w: number, h: number, depth?: number): NodeBuilder;
|
|
75
|
+
path(d: string, w: number, h: number): NodeBuilder;
|
|
76
|
+
document(w: number, h: number, waveHeight?: number): NodeBuilder;
|
|
77
|
+
note(w: number, h: number, foldSize?: number): NodeBuilder;
|
|
78
|
+
parallelogram(w: number, h: number, skew?: number): NodeBuilder;
|
|
79
|
+
star(points: number, outerR: number, innerR?: number): NodeBuilder;
|
|
80
|
+
trapezoid(topW: number, bottomW: number, h: number): NodeBuilder;
|
|
81
|
+
triangle(w: number, h: number, direction?: 'up' | 'down' | 'left' | 'right'): NodeBuilder;
|
|
60
82
|
label(text: string, opts?: Partial<NodeLabel>): NodeBuilder;
|
|
61
83
|
fill(color: string): NodeBuilder;
|
|
62
84
|
stroke(color: string, width?: number): NodeBuilder;
|
|
@@ -68,6 +90,18 @@ interface NodeBuilder {
|
|
|
68
90
|
animateTo(props: AnimatableProps, opts: TweenOptions): NodeBuilder;
|
|
69
91
|
data(payload: unknown): NodeBuilder;
|
|
70
92
|
onClick(handler: (id: string, node: VizNode) => void): NodeBuilder;
|
|
93
|
+
/**
|
|
94
|
+
* Define a named connection port on the node.
|
|
95
|
+
* @param id Unique port id (e.g. `'top'`, `'out-1'`)
|
|
96
|
+
* @param offset Position relative to the node center `{ x, y }`
|
|
97
|
+
* @param direction Optional outgoing tangent in degrees (0=right, 90=down, 180=left, 270=up)
|
|
98
|
+
*/
|
|
99
|
+
port(id: string, offset: {
|
|
100
|
+
x: number;
|
|
101
|
+
y: number;
|
|
102
|
+
}, direction?: number): NodeBuilder;
|
|
103
|
+
container(config?: ContainerConfig): NodeBuilder;
|
|
104
|
+
parent(parentId: string): NodeBuilder;
|
|
71
105
|
done(): VizBuilder;
|
|
72
106
|
node(id: string): NodeBuilder;
|
|
73
107
|
edge(from: string, to: string, id?: string): EdgeBuilder;
|
|
@@ -79,9 +113,35 @@ interface NodeBuilder {
|
|
|
79
113
|
}
|
|
80
114
|
interface EdgeBuilder {
|
|
81
115
|
straight(): EdgeBuilder;
|
|
116
|
+
curved(): EdgeBuilder;
|
|
117
|
+
orthogonal(): EdgeBuilder;
|
|
118
|
+
routing(mode: EdgeRouting): EdgeBuilder;
|
|
119
|
+
via(x: number, y: number): EdgeBuilder;
|
|
82
120
|
label(text: string, opts?: Partial<EdgeLabel>): EdgeBuilder;
|
|
83
|
-
|
|
121
|
+
/**
|
|
122
|
+
* Set arrow markers. Convenience method.
|
|
123
|
+
* - `arrow(true)` or `arrow()` sets markerEnd to 'arrow'
|
|
124
|
+
* - `arrow(false)` sets markerEnd to 'none'
|
|
125
|
+
* - `arrow('both')` sets both markerStart and markerEnd to 'arrow'
|
|
126
|
+
* - `arrow('start')` sets markerStart to 'arrow'
|
|
127
|
+
* - `arrow('end')` sets markerEnd to 'arrow'
|
|
128
|
+
*/
|
|
129
|
+
arrow(enabled?: boolean | 'both' | 'start' | 'end'): EdgeBuilder;
|
|
130
|
+
/** Set the marker type at the end (target) of the edge. */
|
|
131
|
+
markerEnd(type: EdgeMarkerType): EdgeBuilder;
|
|
132
|
+
/** Set the marker type at the start (source) of the edge. */
|
|
133
|
+
markerStart(type: EdgeMarkerType): EdgeBuilder;
|
|
134
|
+
/** Connect the edge to a specific port on the source node. */
|
|
135
|
+
fromPort(portId: string): EdgeBuilder;
|
|
136
|
+
/** Connect the edge to a specific port on the target node. */
|
|
137
|
+
toPort(portId: string): EdgeBuilder;
|
|
84
138
|
connect(anchor: 'center' | 'boundary'): EdgeBuilder;
|
|
139
|
+
/** Sets the fill color of the edge path. */
|
|
140
|
+
fill(color: string): EdgeBuilder;
|
|
141
|
+
/** Sets the stroke color and optional width of the edge path. */
|
|
142
|
+
stroke(color: string, width?: number): EdgeBuilder;
|
|
143
|
+
/** Sets the opacity of the edge. */
|
|
144
|
+
opacity(value: number): EdgeBuilder;
|
|
85
145
|
class(name: string): EdgeBuilder;
|
|
86
146
|
hitArea(px: number): EdgeBuilder;
|
|
87
147
|
animate(type: string, config?: AnimationConfig): EdgeBuilder;
|