Spaces:
Running
Running
A vaguely LynxKite-like node.
Browse files- web/src/App.svelte +14 -7
- web/src/LynxKiteNode.svelte +67 -0
web/src/App.svelte
CHANGED
|
@@ -5,23 +5,27 @@
|
|
| 5 |
Controls,
|
| 6 |
Background,
|
| 7 |
MiniMap,
|
| 8 |
-
|
| 9 |
type Node,
|
| 10 |
type Edge,
|
| 11 |
} from '@xyflow/svelte';
|
| 12 |
-
|
| 13 |
import '@xyflow/svelte/dist/style.css';
|
| 14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
const nodes = writable<Node[]>([
|
| 16 |
{
|
| 17 |
id: '1',
|
| 18 |
-
|
|
|
|
| 19 |
position: { x: 0, y: 0 },
|
| 20 |
-
sourcePosition: Position.Left,
|
| 21 |
-
targetPosition: Position.Right,
|
| 22 |
},
|
| 23 |
{
|
| 24 |
id: '2',
|
|
|
|
| 25 |
data: { label: 'World' },
|
| 26 |
position: { x: 150, y: 150 },
|
| 27 |
},
|
|
@@ -32,13 +36,16 @@
|
|
| 32 |
id: '1-2',
|
| 33 |
source: '1',
|
| 34 |
target: '2',
|
|
|
|
|
|
|
|
|
|
| 35 |
},
|
| 36 |
]);
|
| 37 |
</script>
|
| 38 |
|
| 39 |
<div style:height="100vh">
|
| 40 |
-
<SvelteFlow {nodes} {edges} fitView>
|
| 41 |
-
<Background
|
| 42 |
<Controls />
|
| 43 |
<Background />
|
| 44 |
<MiniMap />
|
|
|
|
| 5 |
Controls,
|
| 6 |
Background,
|
| 7 |
MiniMap,
|
| 8 |
+
MarkerType,
|
| 9 |
type Node,
|
| 10 |
type Edge,
|
| 11 |
} from '@xyflow/svelte';
|
| 12 |
+
import LynxKiteNode from './LynxKiteNode.svelte';
|
| 13 |
import '@xyflow/svelte/dist/style.css';
|
| 14 |
|
| 15 |
+
const nodeTypes: NodeTypes = {
|
| 16 |
+
basic: LynxKiteNode,
|
| 17 |
+
};
|
| 18 |
+
|
| 19 |
const nodes = writable<Node[]>([
|
| 20 |
{
|
| 21 |
id: '1',
|
| 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',
|
| 28 |
+
// type: 'basic',
|
| 29 |
data: { label: 'World' },
|
| 30 |
position: { x: 150, y: 150 },
|
| 31 |
},
|
|
|
|
| 36 |
id: '1-2',
|
| 37 |
source: '1',
|
| 38 |
target: '2',
|
| 39 |
+
markerEnd: {
|
| 40 |
+
type: MarkerType.Arrow
|
| 41 |
+
},
|
| 42 |
},
|
| 43 |
]);
|
| 44 |
</script>
|
| 45 |
|
| 46 |
<div style:height="100vh">
|
| 47 |
+
<SvelteFlow {nodes} {edges} {nodeTypes} fitView>
|
| 48 |
+
<Background />
|
| 49 |
<Controls />
|
| 50 |
<Background />
|
| 51 |
<MiniMap />
|
web/src/LynxKiteNode.svelte
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<script lang="ts">
|
| 2 |
+
import { Handle, Position, type NodeProps, useSvelteFlow } from '@xyflow/svelte';
|
| 3 |
+
|
| 4 |
+
type $$Props = NodeProps;
|
| 5 |
+
|
| 6 |
+
export let id: $$Props['id'];
|
| 7 |
+
export let data: $$Props['data'];
|
| 8 |
+
export let dragHandle: $$Props['dragHandle'] = undefined; dragHandle;
|
| 9 |
+
export let type: $$Props['type'] = undefined; type;
|
| 10 |
+
export let selected: $$Props['selected'] = undefined; selected;
|
| 11 |
+
export let isConnectable: $$Props['isConnectable'] = undefined; isConnectable;
|
| 12 |
+
export let zIndex: $$Props['zIndex'] = undefined; zIndex;
|
| 13 |
+
export let width: $$Props['width'] = undefined; width;
|
| 14 |
+
export let height: $$Props['height'] = undefined; height;
|
| 15 |
+
export let dragging: $$Props['dragging']; dragging;
|
| 16 |
+
export let targetPosition: $$Props['targetPosition'] = undefined; targetPosition;
|
| 17 |
+
export let sourcePosition: $$Props['sourcePosition'] = undefined; sourcePosition;
|
| 18 |
+
export let positionAbsoluteX: $$Props['positionAbsoluteX'] = undefined; positionAbsoluteX;
|
| 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">{data.title}</div>
|
| 27 |
+
{#each Object.entries(data.params) as [name, value]}
|
| 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 |
+
{/each}
|
| 38 |
+
<Handle type="source" position={Position.Right} />
|
| 39 |
+
<Handle type="target" position={Position.Left} />
|
| 40 |
+
</div>
|
| 41 |
+
</div>
|
| 42 |
+
|
| 43 |
+
<style>
|
| 44 |
+
.param {
|
| 45 |
+
padding: 8px;
|
| 46 |
+
}
|
| 47 |
+
.param label {
|
| 48 |
+
font-size: 12px;
|
| 49 |
+
display: block;
|
| 50 |
+
}
|
| 51 |
+
.param input {
|
| 52 |
+
width: calc(100% - 8px);
|
| 53 |
+
}
|
| 54 |
+
.node-container {
|
| 55 |
+
padding: 5px;
|
| 56 |
+
}
|
| 57 |
+
.lynxkite-node {
|
| 58 |
+
box-shadow: 0px 5px 50px 0px rgba(0, 0, 0, 0.3);
|
| 59 |
+
background: white;
|
| 60 |
+
}
|
| 61 |
+
.title {
|
| 62 |
+
background: #ff8800; /* Brand color. */
|
| 63 |
+
font-weight: bold;
|
| 64 |
+
padding: 8px;
|
| 65 |
+
max-width: 300px;
|
| 66 |
+
}
|
| 67 |
+
</style>
|