@visuallyjs/browser-ui-svelte 1.1.4 → 1.2.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/AreaChartComponent.svelte +24 -15
- package/BarChartComponent.svelte +24 -12
- package/BubbleChartComponent.svelte +23 -11
- package/ColorPickerComponent.svelte +2 -2
- package/ColumnChartComponent.svelte +23 -11
- package/ControlsComponent.svelte +12 -34
- package/DecoratorComponent.svelte +15 -23
- package/DiagramComponent.svelte +2 -2
- package/DiagramPaletteComponent.svelte +24 -31
- package/DiagramProvider.svelte +3 -1
- package/EdgeTypePickerComponent.svelte +1 -1
- package/ExportControlsComponent.svelte +15 -33
- package/GaugeChartComponent.svelte +2 -7
- package/InspectorComponent.svelte +24 -36
- package/LineChartComponent.svelte +23 -13
- package/MiniviewComponent.svelte +28 -48
- package/OverlayWrapperComponent.svelte +35 -0
- package/PaletteComponent.svelte +28 -41
- package/PaperComponent.svelte +365 -0
- package/PaperProvider.svelte +11 -0
- package/PieChartComponent.svelte +23 -8
- package/SankeyChartComponent.svelte +35 -14
- package/ScatterChartComponent.svelte +23 -11
- package/ShapePaletteComponent.svelte +11 -22
- package/SurfaceComponent.svelte +100 -5
- package/SurfacePopup.svelte +32 -0
- package/SurfaceProvider.svelte +3 -1
- package/WrapperComponent.svelte +3 -1
- package/XYChartComponent.svelte +33 -12
- package/charts/definitions.d.ts +119 -0
- package/charts/definitions.js +1 -0
- package/components.d.ts +4 -0
- package/components.js +4 -0
- package/definitions.d.ts +111 -259
- package/diagram-store.d.ts +0 -5
- package/diagram-store.js +0 -15
- package/index.d.ts +4 -0
- package/index.js +4 -0
- package/package.json +1 -1
- package/surface-store.d.ts +19 -4
- package/surface-store.js +43 -12
- package/use-diagram.svelte.d.ts +8 -0
- package/use-diagram.svelte.js +18 -0
- package/use-surface.svelte.d.ts +7 -0
- package/use-surface.svelte.js +18 -0
- package/use-visuallyjs-update.svelte.d.ts +19 -0
- package/use-visuallyjs-update.svelte.js +37 -0
- package/use-zoom.svelte.d.ts +1 -3
- package/use-zoom.svelte.js +14 -11
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount, type Snippet } from "svelte";
|
|
3
|
+
import {
|
|
4
|
+
BrowserUISvelteModel,
|
|
5
|
+
newInstance,
|
|
6
|
+
type PaperComponentProps
|
|
7
|
+
} from "./index";
|
|
8
|
+
import {
|
|
9
|
+
isNode,
|
|
10
|
+
isGroup,
|
|
11
|
+
renderPaper,
|
|
12
|
+
uuid,
|
|
13
|
+
EVENT_RENDER_END,
|
|
14
|
+
CLASS_DEFAULT_GROUP,
|
|
15
|
+
CLASS_DEFAULT_NODE, Paper,
|
|
16
|
+
type BrowserElement,
|
|
17
|
+
type ObjectData,
|
|
18
|
+
Vertex,
|
|
19
|
+
partition,
|
|
20
|
+
type VertexUpdatedParams,
|
|
21
|
+
extend, EVENT_GRAPH_CLEARED, EVENT_NODE_UPDATED, EVENT_GROUP_UPDATED,
|
|
22
|
+
type NodeRemovedParams, EVENT_NODE_REMOVED,
|
|
23
|
+
type GroupRemovedParams, EVENT_GROUP_REMOVED,
|
|
24
|
+
type PaperOptions,
|
|
25
|
+
OVERLAY_TYPE_CUSTOM,
|
|
26
|
+
type Connection,
|
|
27
|
+
type EdgeUpdatedParams,
|
|
28
|
+
type EdgeRemovedParams,
|
|
29
|
+
EVENT_EDGE_UPDATED,
|
|
30
|
+
EVENT_EDGE_REMOVED,
|
|
31
|
+
ELEMENT_DIV
|
|
32
|
+
} from "@visuallyjs/browser-ui";
|
|
33
|
+
import { internal_getPaperContext } from "./surface-store";
|
|
34
|
+
|
|
35
|
+
import DefaultNodeComponent from './DefaultNodeComponent.svelte'
|
|
36
|
+
import DefaultGroupComponent from './DefaultGroupComponent.svelte'
|
|
37
|
+
import WrapperComponent from "./WrapperComponent.svelte";
|
|
38
|
+
import OverlayWrapperComponent from "./OverlayWrapperComponent.svelte";
|
|
39
|
+
|
|
40
|
+
let container:HTMLElement;
|
|
41
|
+
|
|
42
|
+
let {
|
|
43
|
+
className,
|
|
44
|
+
renderOptions,
|
|
45
|
+
viewOptions,
|
|
46
|
+
modelOptions,
|
|
47
|
+
model,
|
|
48
|
+
data,
|
|
49
|
+
url,
|
|
50
|
+
shapeLibrary,
|
|
51
|
+
injector,
|
|
52
|
+
children
|
|
53
|
+
}:PaperComponentProps = $props();
|
|
54
|
+
|
|
55
|
+
const paperContext = internal_getPaperContext(false);
|
|
56
|
+
|
|
57
|
+
let paper:Paper;
|
|
58
|
+
|
|
59
|
+
export function getPaper() {
|
|
60
|
+
return paper
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function getModel() {
|
|
64
|
+
return paper?.model
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
type ComponentHolder = {
|
|
68
|
+
component:any,
|
|
69
|
+
props:any,
|
|
70
|
+
vertex:Vertex,
|
|
71
|
+
def:any,
|
|
72
|
+
id:string
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const componentMap:Map<string, ComponentHolder> = new Map();
|
|
76
|
+
const id = uuid();
|
|
77
|
+
|
|
78
|
+
// list of vertices to render
|
|
79
|
+
let _vertices:Array<ComponentHolder> = []
|
|
80
|
+
|
|
81
|
+
type OverlayHolder = {
|
|
82
|
+
component: any,
|
|
83
|
+
props: any,
|
|
84
|
+
edge: any,
|
|
85
|
+
id: string,
|
|
86
|
+
el:BrowserElement
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let _overlays: Array<OverlayHolder> = []
|
|
90
|
+
|
|
91
|
+
// state wrapper around the vertex list
|
|
92
|
+
let vertexState = $state({
|
|
93
|
+
vertices:_vertices
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
let overlayState = $state({
|
|
97
|
+
overlays: _overlays
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
// manages updating the vertex state cleanly.
|
|
101
|
+
function _updateVertexState() {
|
|
102
|
+
vertexState.vertices.length = 0
|
|
103
|
+
vertexState.vertices.push(..._vertices.slice())
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function _updateOverlayState() {
|
|
107
|
+
overlayState.overlays.length = 0
|
|
108
|
+
overlayState.overlays.push(..._overlays.slice())
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function _initialiseSvelteOverlays() {
|
|
112
|
+
const edgeTypes = viewOptions?.edges || {}
|
|
113
|
+
for (let type in edgeTypes) {
|
|
114
|
+
const edgeDefinition = edgeTypes[type];
|
|
115
|
+
if (edgeDefinition.overlays) {
|
|
116
|
+
edgeDefinition.overlays = edgeDefinition.overlays.map((ov: any) => {
|
|
117
|
+
if (ov.component != null) {
|
|
118
|
+
return {
|
|
119
|
+
type: OVERLAY_TYPE_CUSTOM,
|
|
120
|
+
options: {
|
|
121
|
+
create: (c: Connection<BrowserElement>) => {
|
|
122
|
+
const el = document.createElement(ELEMENT_DIV);
|
|
123
|
+
const overlayProps = {
|
|
124
|
+
data: c.edge.data,
|
|
125
|
+
model: paper.model,
|
|
126
|
+
ui: paper,
|
|
127
|
+
edge: c.edge,
|
|
128
|
+
vertex: c.edge, // Some components might expect vertex
|
|
129
|
+
...ov.props
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const holder: OverlayHolder = {
|
|
133
|
+
component: ov.component,
|
|
134
|
+
props: overlayProps,
|
|
135
|
+
edge: c.edge,
|
|
136
|
+
id: uuid(),
|
|
137
|
+
el
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
_overlays.push(holder);
|
|
141
|
+
_updateOverlayState();
|
|
142
|
+
return el;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return ov;
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function render ( id:string, data:ObjectData, model:BrowserUISvelteModel, type:string,
|
|
154
|
+
paper:Paper, def:any, modelObject:Vertex, eventInfo:any) {
|
|
155
|
+
|
|
156
|
+
const hasComponent = def.component != null
|
|
157
|
+
let component;
|
|
158
|
+
if (!hasComponent) {
|
|
159
|
+
if (isNode(modelObject)) {
|
|
160
|
+
component = DefaultNodeComponent;
|
|
161
|
+
} else if (isGroup(modelObject)) {
|
|
162
|
+
component = DefaultGroupComponent;
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
component = def.component;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (component) {
|
|
169
|
+
let propsToSet:Record<string, any> = {
|
|
170
|
+
data: modelObject.data,
|
|
171
|
+
model,
|
|
172
|
+
ui:paper,
|
|
173
|
+
componentId: modelObject.getFullId(),
|
|
174
|
+
vertex: modelObject,
|
|
175
|
+
eventInfo,
|
|
176
|
+
className:hasComponent ? null : (isGroup(modelObject) ? CLASS_DEFAULT_GROUP : CLASS_DEFAULT_NODE)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (injector != null) {
|
|
180
|
+
const injectedProps = injector(modelObject);
|
|
181
|
+
if (injectedProps != null) {
|
|
182
|
+
for (let key in injectedProps) {
|
|
183
|
+
propsToSet[key] = injectedProps[key];
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const props = $state(propsToSet)
|
|
189
|
+
const componentHolder:ComponentHolder = {
|
|
190
|
+
component, props, vertex:modelObject, def, id:modelObject.id
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
_vertices.push(componentHolder)
|
|
194
|
+
_updateVertexState()
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function cleanupVertex(objId:string, el:BrowserElement) {
|
|
200
|
+
el.parentNode && el.parentNode.removeChild(el);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
onMount(async () => {
|
|
204
|
+
model = model || newInstance(modelOptions || {});
|
|
205
|
+
|
|
206
|
+
const templateRenderer = {
|
|
207
|
+
asynchronous: true,
|
|
208
|
+
reactive: true,
|
|
209
|
+
usesWrapperElement:true,
|
|
210
|
+
update: (el:BrowserElement, data:Object, vertex:Vertex) => {
|
|
211
|
+
const component = componentMap.get(vertex.id);
|
|
212
|
+
if (component) {
|
|
213
|
+
component.props.data = vertex.data
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
render,
|
|
217
|
+
cleanupVertex,
|
|
218
|
+
cleanupPort: (objId:string, el:BrowserElement) => {},
|
|
219
|
+
rerender: (
|
|
220
|
+
id:string,
|
|
221
|
+
data:ObjectData,
|
|
222
|
+
model:BrowserUISvelteModel,
|
|
223
|
+
type:string,
|
|
224
|
+
paper:Paper,
|
|
225
|
+
def:any,
|
|
226
|
+
modelObject:Vertex,
|
|
227
|
+
eventInfo:any,
|
|
228
|
+
originalElement:BrowserElement
|
|
229
|
+
) => {
|
|
230
|
+
|
|
231
|
+
// split into vertices we want to keep and the one we want to discard
|
|
232
|
+
const p = partition(_vertices, (v) => v.vertex !== modelObject)
|
|
233
|
+
// assign the ones we want to keep, update state
|
|
234
|
+
_vertices = p.left
|
|
235
|
+
_updateVertexState()
|
|
236
|
+
|
|
237
|
+
// remove the old DOM element
|
|
238
|
+
if (p.right.length > 0) {
|
|
239
|
+
cleanupVertex(modelObject.id, originalElement)
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// on next tick, render again. it's important to wait for the next tick or the
|
|
243
|
+
// vertices state array gets messed up
|
|
244
|
+
setTimeout(() => {
|
|
245
|
+
render(id, data, model, type, paper, def, modelObject, eventInfo)
|
|
246
|
+
})
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const params = (renderOptions || {}) as PaperOptions;
|
|
251
|
+
params.view = (viewOptions || {}) as any;
|
|
252
|
+
params.id = id;
|
|
253
|
+
|
|
254
|
+
if (shapeLibrary != null) {
|
|
255
|
+
params.shapes = {
|
|
256
|
+
library: shapeLibrary,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
_initialiseSvelteOverlays();
|
|
261
|
+
|
|
262
|
+
paper = renderPaper(model, container, templateRenderer, params);
|
|
263
|
+
|
|
264
|
+
// with continuous anchors it's necessary to do this, for
|
|
265
|
+
// asynchronous-y reasons. $redrawEveryConnection only redraws
|
|
266
|
+
// edges and does not update element positions so it's
|
|
267
|
+
// reasonably quick.
|
|
268
|
+
paper.bind(EVENT_RENDER_END, () => setTimeout(() => paper.$redrawEveryConnection()))
|
|
269
|
+
|
|
270
|
+
if (paperContext != null) {
|
|
271
|
+
paperContext.set(paper);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const updateVertex = (vertexId: string, eventPayload: VertexUpdatedParams) => {
|
|
275
|
+
|
|
276
|
+
let mergeData = () => {
|
|
277
|
+
let data = {}
|
|
278
|
+
if (eventPayload.originalData || eventPayload.updates) {
|
|
279
|
+
data = extend(eventPayload.originalData, eventPayload.updates)
|
|
280
|
+
}
|
|
281
|
+
return data
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
const entry = _vertices.find((v) => v.vertex.id === vertexId);
|
|
285
|
+
if (entry != null) {
|
|
286
|
+
entry.props.data = mergeData()
|
|
287
|
+
_updateVertexState()
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const removeVertex = (id: string) => {
|
|
292
|
+
_vertices = _vertices.filter(n => n.vertex.id !== id)
|
|
293
|
+
_updateVertexState()
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
model.bind<VertexUpdatedParams>(EVENT_NODE_UPDATED, (p: VertexUpdatedParams) => {
|
|
297
|
+
updateVertex(p.vertex.getFullId(), p)
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
model.bind<VertexUpdatedParams>(EVENT_GROUP_UPDATED, (p: VertexUpdatedParams) => {
|
|
301
|
+
updateVertex(p.vertex.getFullId(), p)
|
|
302
|
+
});
|
|
303
|
+
//
|
|
304
|
+
model.bind<NodeRemovedParams>(EVENT_NODE_REMOVED, (p: NodeRemovedParams) => {
|
|
305
|
+
removeVertex(p.node.id)
|
|
306
|
+
});
|
|
307
|
+
//
|
|
308
|
+
model.bind<GroupRemovedParams>(EVENT_GROUP_REMOVED, (p: GroupRemovedParams) => {
|
|
309
|
+
removeVertex(p.group.id)
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
const updateOverlays = (edgeId: string, eventPayload: EdgeUpdatedParams) => {
|
|
313
|
+
_overlays.forEach(o => {
|
|
314
|
+
if (o.edge.id === edgeId) {
|
|
315
|
+
o.props.data = eventPayload.edge.data;
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
_updateOverlayState();
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
const removeOverlays = (edgeId: string) => {
|
|
322
|
+
_overlays = _overlays.filter(o => o.edge.id !== edgeId);
|
|
323
|
+
_updateOverlayState();
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
model.bind<EdgeUpdatedParams>(EVENT_EDGE_UPDATED, (p) => updateOverlays(p.edge.id, p));
|
|
327
|
+
model.bind<EdgeRemovedParams>(EVENT_EDGE_REMOVED, (p) => removeOverlays(p.edge.id));
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
model.bind(EVENT_GRAPH_CLEARED, () => {
|
|
331
|
+
_vertices = []
|
|
332
|
+
_updateVertexState()
|
|
333
|
+
_overlays = []
|
|
334
|
+
_updateOverlayState()
|
|
335
|
+
})
|
|
336
|
+
|
|
337
|
+
if (url != null) {
|
|
338
|
+
model.load({ url });
|
|
339
|
+
} else if (data != null) {
|
|
340
|
+
model.load({ data });
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
</script>
|
|
345
|
+
|
|
346
|
+
<div class={className} bind:this={container}>
|
|
347
|
+
{#each vertexState.vertices as vertex (vertex.id)}
|
|
348
|
+
<WrapperComponent component={vertex.component}
|
|
349
|
+
data={vertex.props.data}
|
|
350
|
+
ui={paper}
|
|
351
|
+
def={vertex.def}
|
|
352
|
+
vertex={vertex.vertex}
|
|
353
|
+
className={vertex.props.className}/>
|
|
354
|
+
{/each}
|
|
355
|
+
|
|
356
|
+
{#each overlayState.overlays as overlay (overlay.id)}
|
|
357
|
+
<OverlayWrapperComponent component={overlay.component}
|
|
358
|
+
data={overlay.props.data}
|
|
359
|
+
ui={paper}
|
|
360
|
+
edge={overlay.edge}
|
|
361
|
+
className="vjs-svelte-overlay"
|
|
362
|
+
el={overlay.el}/>
|
|
363
|
+
{/each}
|
|
364
|
+
{@render children?.()}
|
|
365
|
+
</div>
|
package/PieChartComponent.svelte
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import { onMount } from "svelte";
|
|
4
4
|
|
|
5
|
-
import {PieChart, type BrowserElement} from "@visuallyjs/browser-ui"
|
|
6
|
-
import {type PieChartComponentProps} from "./definitions";
|
|
5
|
+
import {PieChart, type BrowserElement, type PieChartOptions} from "@visuallyjs/browser-ui"
|
|
6
|
+
import {type PieChartComponentProps} from "./charts/definitions";
|
|
7
|
+
import {useVisuallyJsModel} from "./surface-store";
|
|
7
8
|
|
|
8
9
|
let container:BrowserElement;
|
|
9
10
|
|
|
@@ -16,20 +17,34 @@
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
$effect(() => {
|
|
19
|
-
if (chart) {
|
|
20
|
+
if (chart && dataSourceFilter != null) {
|
|
20
21
|
chart.setDataSourceFilter(dataSourceFilter)
|
|
21
22
|
}
|
|
22
23
|
})
|
|
23
24
|
|
|
25
|
+
function init(opts:PieChartOptions) {
|
|
26
|
+
chart = new PieChart(container, opts)
|
|
27
|
+
|
|
28
|
+
if (url != null) {
|
|
29
|
+
chart.load({url});
|
|
30
|
+
} else if (data != null) {
|
|
31
|
+
chart.load({data});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
24
35
|
onMount(async () => {
|
|
25
36
|
|
|
26
|
-
|
|
37
|
+
const opts:PieChartOptions = Object.assign({dataSourceFilter}, options)
|
|
27
38
|
|
|
28
|
-
if (url
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
if (url == null && data == null) {
|
|
40
|
+
useVisuallyJsModel().then(m => {
|
|
41
|
+
opts.dataSource = m
|
|
42
|
+
init(opts)
|
|
43
|
+
})
|
|
44
|
+
} else {
|
|
45
|
+
init(opts)
|
|
32
46
|
}
|
|
47
|
+
|
|
33
48
|
})
|
|
34
49
|
|
|
35
50
|
</script>
|
|
@@ -2,41 +2,62 @@
|
|
|
2
2
|
|
|
3
3
|
import { onMount } from "svelte";
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
|
|
5
|
+
import {
|
|
6
|
+
SankeyChart,
|
|
7
|
+
type BrowserElement,
|
|
8
|
+
type SankeyOptions
|
|
9
|
+
} from "@visuallyjs/browser-ui"
|
|
10
|
+
import {type SankeyChartComponentProps} from "./charts/definitions";
|
|
11
|
+
import {useVisuallyJsModel} from "./surface-store";
|
|
7
12
|
|
|
8
13
|
let container:BrowserElement;
|
|
9
14
|
|
|
10
15
|
let {options, className = "", jsonData, csvData, url, interactive, pivot }:SankeyChartComponentProps = $props();
|
|
11
16
|
|
|
12
|
-
let chart:SankeyChart;
|
|
17
|
+
let chart:SankeyChart|null = $state(null);
|
|
13
18
|
|
|
14
19
|
$effect(() => {
|
|
15
|
-
|
|
20
|
+
if (pivot != null && chart != null) {
|
|
21
|
+
chart.pivot(pivot as string)
|
|
22
|
+
}
|
|
16
23
|
})
|
|
17
24
|
|
|
18
25
|
export function getChart() {
|
|
19
26
|
return chart;
|
|
20
27
|
}
|
|
21
28
|
|
|
22
|
-
|
|
29
|
+
function init(opts:SankeyOptions) {
|
|
30
|
+
|
|
31
|
+
chart = new SankeyChart(container, opts)
|
|
32
|
+
|
|
33
|
+
if (url != null) {
|
|
34
|
+
chart.load({url});
|
|
35
|
+
} else if (csvData != null) {
|
|
36
|
+
chart.load({csvData});
|
|
37
|
+
} else if (jsonData != null) {
|
|
38
|
+
chart.load({jsonData})
|
|
39
|
+
}
|
|
40
|
+
}
|
|
23
41
|
|
|
24
|
-
|
|
42
|
+
|
|
43
|
+
onMount(async () => {
|
|
44
|
+
const _options:SankeyOptions = Object.assign({}, options)
|
|
25
45
|
if (interactive != null) {
|
|
26
46
|
_options.interactive = interactive
|
|
27
47
|
}
|
|
28
48
|
if (pivot != null) {
|
|
29
49
|
_options.pivot = pivot
|
|
30
50
|
}
|
|
31
|
-
chart = new SankeyChart(container, _options)
|
|
32
51
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
52
|
+
if (url == null && csvData == null && jsonData == null) {
|
|
53
|
+
useVisuallyJsModel().then(m => {
|
|
54
|
+
_options.dataSource = m
|
|
55
|
+
init(_options)
|
|
56
|
+
})
|
|
57
|
+
} else {
|
|
58
|
+
init(_options)
|
|
59
|
+
}
|
|
60
|
+
|
|
40
61
|
})
|
|
41
62
|
|
|
42
63
|
</script>
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import { onMount } from "svelte";
|
|
4
4
|
|
|
5
|
-
import {type BrowserElement, ScatterChart} from "@visuallyjs/browser-ui"
|
|
6
|
-
import {type ScatterChartComponentProps} from "./definitions";
|
|
5
|
+
import {type BrowserElement, type ScatterChartOptions, ScatterChart} from "@visuallyjs/browser-ui"
|
|
6
|
+
import {type ScatterChartComponentProps} from "./charts/definitions";
|
|
7
|
+
import {useVisuallyJsModel} from "./surface-store";
|
|
7
8
|
|
|
8
9
|
let container:BrowserElement;
|
|
9
10
|
|
|
@@ -17,21 +18,32 @@
|
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
$effect(() => {
|
|
20
|
-
if (chart) {
|
|
21
|
+
if (chart && dataSourceFilter != null) {
|
|
21
22
|
chart.setDataSourceFilter(dataSourceFilter)
|
|
22
23
|
}
|
|
23
24
|
})
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
function init(opts:ScatterChartOptions) {
|
|
27
|
+
chart = new ScatterChart(container, opts)
|
|
28
|
+
if (url != null) {
|
|
29
|
+
chart.load({url});
|
|
30
|
+
} else if (data != null) {
|
|
31
|
+
chart.load({data});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
26
34
|
|
|
27
|
-
|
|
35
|
+
onMount(async () => {
|
|
36
|
+
const opts:ScatterChartOptions = Object.assign({dataSourceFilter}, options)
|
|
37
|
+
if (url == null && data == null) {
|
|
38
|
+
useVisuallyJsModel().then(m => {
|
|
39
|
+
opts.dataSource = m
|
|
40
|
+
init(opts)
|
|
41
|
+
})
|
|
42
|
+
} else {
|
|
43
|
+
init(opts)
|
|
44
|
+
}
|
|
45
|
+
})
|
|
28
46
|
|
|
29
|
-
if (url != null) {
|
|
30
|
-
chart.load({url});
|
|
31
|
-
} else if (data != null) {
|
|
32
|
-
chart.load({data});
|
|
33
|
-
}
|
|
34
|
-
})
|
|
35
47
|
|
|
36
48
|
</script>
|
|
37
49
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
import { onMount } from "svelte"
|
|
2
|
+
|
|
4
3
|
import {log, ShapePalette, Surface} from "@visuallyjs/browser-ui"
|
|
5
4
|
import {type ShapePaletteComponentProps} from "./definitions";
|
|
5
|
+
import {useSurface} from "./use-surface.svelte";
|
|
6
|
+
import {useDiagram} from "./use-diagram.svelte";
|
|
6
7
|
|
|
7
8
|
let {
|
|
8
9
|
className = "",
|
|
@@ -24,30 +25,22 @@
|
|
|
24
25
|
preparedShapes
|
|
25
26
|
}:ShapePaletteComponentProps = $props()
|
|
26
27
|
|
|
27
|
-
let surface:Surface
|
|
28
28
|
let container:HTMLElement
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
sc.listen(s => {
|
|
34
|
-
surface = s
|
|
35
|
-
_maybeInit()
|
|
36
|
-
})
|
|
37
|
-
} else {
|
|
38
|
-
log(`WARN: ShapePaletteComponent did not find a Surface context - ensure the ShapePaletteComponent is declared inside a SurfaceComponent or SurfaceProvider`)
|
|
39
|
-
}
|
|
29
|
+
let initialised = false
|
|
30
|
+
const surface = useSurface()
|
|
31
|
+
const diagram = useDiagram()
|
|
32
|
+
const surfaceRef = $derived(surface.current || diagram.current?.$ui as Surface)
|
|
40
33
|
|
|
41
|
-
|
|
42
|
-
if (!initialised &&
|
|
34
|
+
$effect(() => {
|
|
35
|
+
if (!initialised && surfaceRef != null && container != null) {
|
|
43
36
|
initialised = true
|
|
44
37
|
|
|
45
|
-
const shapeLibrary =
|
|
38
|
+
const shapeLibrary = surfaceRef.getShapeLibrary()
|
|
46
39
|
if (shapeLibrary == null) {
|
|
47
40
|
log("WARN: no shape library set on surface; ShapePaletteComponent cannot render")
|
|
48
41
|
} else {
|
|
49
42
|
|
|
50
|
-
new ShapePalette(
|
|
43
|
+
new ShapePalette(surfaceRef, {
|
|
51
44
|
container,
|
|
52
45
|
dataGenerator,
|
|
53
46
|
autoExitDrawMode,
|
|
@@ -71,10 +64,6 @@
|
|
|
71
64
|
}
|
|
72
65
|
|
|
73
66
|
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
onMount(async () => {
|
|
77
|
-
_maybeInit()
|
|
78
67
|
})
|
|
79
68
|
|
|
80
69
|
|