|
|
|
@ -56,6 +56,7 @@ export const GraphInput = ({ graph, setGraph }) => {
|
|
|
|
{
|
|
|
|
{
|
|
|
|
id: crypto.randomUUID(9).split('-')[0],
|
|
|
|
id: crypto.randomUUID(9).split('-')[0],
|
|
|
|
label: '?',
|
|
|
|
label: '?',
|
|
|
|
|
|
|
|
balance: 0,
|
|
|
|
x,
|
|
|
|
x,
|
|
|
|
y,
|
|
|
|
y,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
@ -193,7 +194,7 @@ export const GraphInput = ({ graph, setGraph }) => {
|
|
|
|
))}
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="nodes">
|
|
|
|
<div class="nodes">
|
|
|
|
{graph.nodes.map(({ id, label, x, y }, index) => (
|
|
|
|
{graph.nodes.map(({ id, label, balance, x, y }, index) => (
|
|
|
|
<div
|
|
|
|
<div
|
|
|
|
class={[
|
|
|
|
class={[
|
|
|
|
'node',
|
|
|
|
'node',
|
|
|
|
@ -204,6 +205,49 @@ export const GraphInput = ({ graph, setGraph }) => {
|
|
|
|
.filter(Boolean)
|
|
|
|
.filter(Boolean)
|
|
|
|
.join(' ')}
|
|
|
|
.join(' ')}
|
|
|
|
style={{ '--x': x, '--y': y }}
|
|
|
|
style={{ '--x': x, '--y': y }}
|
|
|
|
|
|
|
|
onKeyDown={e => {
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
|
|
|
(e.key === 'Enter' || e.key === 'Escape') &&
|
|
|
|
|
|
|
|
interacting?.type === 'edit-node'
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
setInteracting(false)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<div class="popup">
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
|
|
|
onClick={() => {
|
|
|
|
|
|
|
|
setGraph(g => {
|
|
|
|
|
|
|
|
const newNodes = [...g.nodes]
|
|
|
|
|
|
|
|
newNodes[index] = {
|
|
|
|
|
|
|
|
...g.nodes[index],
|
|
|
|
|
|
|
|
balance: g.nodes[index].balance + 1,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return { ...g, nodes: newNodes }
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
|
|
|
onClick={() => {
|
|
|
|
|
|
|
|
setGraph(g => {
|
|
|
|
|
|
|
|
const newNodes = [...g.nodes]
|
|
|
|
|
|
|
|
newNodes[index] = {
|
|
|
|
|
|
|
|
...g.nodes[index],
|
|
|
|
|
|
|
|
balance: g.nodes[index].balance - 1,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return { ...g, nodes: newNodes }
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
|
|
|
class="node-ball"
|
|
|
|
onMouseDown={e => {
|
|
|
|
onMouseDown={e => {
|
|
|
|
if (interacting) return
|
|
|
|
if (interacting) return
|
|
|
|
|
|
|
|
|
|
|
|
@ -242,14 +286,6 @@ export const GraphInput = ({ graph, setGraph }) => {
|
|
|
|
index,
|
|
|
|
index,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}}
|
|
|
|
}}
|
|
|
|
onKeyDown={e => {
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
|
|
|
(e.key === 'Enter' || e.key === 'Escape') &&
|
|
|
|
|
|
|
|
interacting?.type === 'edit-node'
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
setInteracting(false)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
{interacting?.type === 'edit-node' && interacting.index === index ? (
|
|
|
|
{interacting?.type === 'edit-node' && interacting.index === index ? (
|
|
|
|
<input
|
|
|
|
<input
|
|
|
|
@ -274,6 +310,16 @@ export const GraphInput = ({ graph, setGraph }) => {
|
|
|
|
label
|
|
|
|
label
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
{balance !== 0 && (
|
|
|
|
|
|
|
|
<div class="balance">
|
|
|
|
|
|
|
|
{balance < 0 ? (
|
|
|
|
|
|
|
|
<>−{Math.abs(balance)}</>
|
|
|
|
|
|
|
|
) : (
|
|
|
|
|
|
|
|
<>+{Math.abs(balance)}</>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
))}
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|