Spaces:
Running
Running
Collapsible nodes.
Browse files- web/src/App.svelte +10 -0
- web/src/LynxKiteNode.svelte +29 -15
web/src/App.svelte
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
Background,
|
7 |
MiniMap,
|
8 |
MarkerType,
|
|
|
9 |
type Node,
|
10 |
type Edge,
|
11 |
} from '@xyflow/svelte';
|
@@ -22,6 +23,8 @@
|
|
22 |
type: 'basic',
|
23 |
data: { title: 'Compute PageRank', params: { damping: 0.85, iterations: 3 } },
|
24 |
position: { x: 0, y: 0 },
|
|
|
|
|
25 |
},
|
26 |
{
|
27 |
id: '2',
|
@@ -29,6 +32,13 @@
|
|
29 |
data: { label: 'World' },
|
30 |
position: { x: 150, y: 150 },
|
31 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
]);
|
33 |
|
34 |
const edges = writable<Edge[]>([
|
|
|
6 |
Background,
|
7 |
MiniMap,
|
8 |
MarkerType,
|
9 |
+
Position,
|
10 |
type Node,
|
11 |
type Edge,
|
12 |
} from '@xyflow/svelte';
|
|
|
23 |
type: 'basic',
|
24 |
data: { title: 'Compute PageRank', params: { damping: 0.85, iterations: 3 } },
|
25 |
position: { x: 0, y: 0 },
|
26 |
+
sourcePosition: Position.Right,
|
27 |
+
targetPosition: Position.Left,
|
28 |
},
|
29 |
{
|
30 |
id: '2',
|
|
|
32 |
data: { label: 'World' },
|
33 |
position: { x: 150, y: 150 },
|
34 |
},
|
35 |
+
{
|
36 |
+
id: '3',
|
37 |
+
type: 'basic',
|
38 |
+
data: { title: 'Import Parquet', params: { filename: '/tmp/x.parquet' } },
|
39 |
+
position: { x: -300, y: 0 },
|
40 |
+
sourcePosition: Position.Right,
|
41 |
+
},
|
42 |
]);
|
43 |
|
44 |
const edges = writable<Edge[]>([
|
web/src/LynxKiteNode.svelte
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<script lang="ts">
|
2 |
-
import { Handle,
|
3 |
|
4 |
type $$Props = NodeProps;
|
5 |
|
@@ -19,24 +19,37 @@
|
|
19 |
export let positionAbsoluteY: $$Props['positionAbsoluteY'] = undefined; positionAbsoluteY;
|
20 |
|
21 |
const { updateNodeData } = useSvelteFlow();
|
|
|
|
|
|
|
|
|
|
|
22 |
</script>
|
23 |
|
24 |
<div class="node-container">
|
25 |
<div class="lynxkite-node">
|
26 |
-
<div class="title"
|
27 |
-
|
28 |
-
<div class="param">
|
29 |
-
<label>
|
30 |
-
{name}<br>
|
31 |
-
<input
|
32 |
-
value={value}
|
33 |
-
on:input={(evt) => updateNodeData(id, { params: { ...data.params, [name]: evt.currentTarget.value } })}
|
34 |
-
/>
|
35 |
-
</label>
|
36 |
</div>
|
37 |
-
{
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
</div>
|
41 |
</div>
|
42 |
|
@@ -59,9 +72,10 @@
|
|
59 |
background: white;
|
60 |
}
|
61 |
.title {
|
62 |
-
background: #ff8800;
|
63 |
font-weight: bold;
|
64 |
padding: 8px;
|
|
|
65 |
max-width: 300px;
|
66 |
}
|
67 |
</style>
|
|
|
1 |
<script lang="ts">
|
2 |
+
import { Handle, type NodeProps, useSvelteFlow } from '@xyflow/svelte';
|
3 |
|
4 |
type $$Props = NodeProps;
|
5 |
|
|
|
19 |
export let positionAbsoluteY: $$Props['positionAbsoluteY'] = undefined; positionAbsoluteY;
|
20 |
|
21 |
const { updateNodeData } = useSvelteFlow();
|
22 |
+
|
23 |
+
let expanded = true;
|
24 |
+
function titleClicked() {
|
25 |
+
expanded = !expanded;
|
26 |
+
}
|
27 |
</script>
|
28 |
|
29 |
<div class="node-container">
|
30 |
<div class="lynxkite-node">
|
31 |
+
<div class="title" on:click={titleClicked}>
|
32 |
+
{data.title}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
</div>
|
34 |
+
{#if expanded}
|
35 |
+
{#each Object.entries(data.params) as [name, value]}
|
36 |
+
<div class="param">
|
37 |
+
<label>
|
38 |
+
{name}<br>
|
39 |
+
<input
|
40 |
+
value={value}
|
41 |
+
on:input={(evt) => updateNodeData(id, { params: { ...data.params, [name]: evt.currentTarget.value } })}
|
42 |
+
/>
|
43 |
+
</label>
|
44 |
+
</div>
|
45 |
+
{/each}
|
46 |
+
{/if}
|
47 |
+
{#if sourcePosition}
|
48 |
+
<Handle type="source" position={sourcePosition} />
|
49 |
+
{/if}
|
50 |
+
{#if targetPosition}
|
51 |
+
<Handle type="target" position={targetPosition} />
|
52 |
+
{/if}
|
53 |
</div>
|
54 |
</div>
|
55 |
|
|
|
72 |
background: white;
|
73 |
}
|
74 |
.title {
|
75 |
+
background: #ff8800;
|
76 |
font-weight: bold;
|
77 |
padding: 8px;
|
78 |
+
min-width: 170px;
|
79 |
max-width: 300px;
|
80 |
}
|
81 |
</style>
|