sachaw
sachaw
Explore posts from servers
SSolidJS
Created by sachaw on 4/29/2024 in #support
Force effect computation, or alternate approach?
Not working correctly yet, but is reacting to changes (although positions are reseting and simulation does not restart) https://gist.github.com/sachaw/f9c73aa1806ab26cd52b7c3237b02200
11 replies
SSolidJS
Created by sachaw on 4/29/2024 in #support
Force effect computation, or alternate approach?
I wanted to use Cosmograph, but had the same issue
11 replies
SSolidJS
Created by sachaw on 4/29/2024 in #support
Force effect computation, or alternate approach?
Nice, I'll have a look
11 replies
SSolidJS
Created by sachaw on 4/29/2024 in #support
Force effect computation, or alternate approach?
unlike many of the d3 primitives, the graph computation mutates it's internal state and isn't easy to hook into
11 replies
SSolidJS
Created by sachaw on 4/29/2024 in #support
Force effect computation, or alternate approach?
i'd be very interested if you know of any workarounds
11 replies
SSolidJS
Created by sachaw on 4/29/2024 in #support
Force effect computation, or alternate approach?
I tried D3 before this, which worked fine, but I need to be able to react to nodes or edges being pushed to my store and inseted reactively. The behaviour was either non-reactive or would reset the layout (positions) every time
11 replies
SSolidJS
Created by sachaw on 4/29/2024 in #support
Force effect computation, or alternate approach?
legend, I'll take a look. Does it support edge labels?
11 replies
SSolidJS
Created by sachaw on 4/29/2024 in #support
Force effect computation, or alternate approach?
Thanks, is there a different way I should handle this, I need to perform the calculation many times
11 replies
SSolidJS
Created by sachaw on 4/29/2024 in #support
Force effect computation, or alternate approach?
const MergedNodes = createMemo(() => {
//merge nodes and their positions
const mergedNodes = localState.serverStatus.mesh.nodes.map((node) => ({
...node,
...positions.get(node.id),
}));

return mergedNodes;
});

const MergedLinks = createMemo(() => {
//merge links and their positions
const mergedLinks = localState.serverStatus.mesh.edges.map((link) => {
const source = positions.get(link.source);
const target = positions.get(link.target);

if (source && target) {
return {
source,
target,
};
}
});

return mergedLinks;
});

return (
// biome-ignore lint/a11y/noSvgWithoutTitle: <explanation>
<svg
width={width}
height={height}
viewBox={`0 0 ${width} ${height}`}
style={{
"max-width": "100%",
height: "auto",
}}
>
<g stroke="#999" stroke-opacity={0.6}>
<For each={MergedLinks()}>
{(link) => (
<line
stroke-width={1}
x1={link?.source.x}
y1={link?.source.y}
x2={link?.target.x}
y2={link?.target.y}
/>
)}
</For>
</g>
<g stroke={"#fff"} stroke-width={1.5}>
<For each={MergedNodes()}>
{(node) => (
<circle r={5} fill={"green"} cx={node.x} cy={node.y}>
<title>{node.id}</title>
</circle>
)}
</For>
</g>
</svg>
);
};
const MergedNodes = createMemo(() => {
//merge nodes and their positions
const mergedNodes = localState.serverStatus.mesh.nodes.map((node) => ({
...node,
...positions.get(node.id),
}));

return mergedNodes;
});

const MergedLinks = createMemo(() => {
//merge links and their positions
const mergedLinks = localState.serverStatus.mesh.edges.map((link) => {
const source = positions.get(link.source);
const target = positions.get(link.target);

if (source && target) {
return {
source,
target,
};
}
});

return mergedLinks;
});

return (
// biome-ignore lint/a11y/noSvgWithoutTitle: <explanation>
<svg
width={width}
height={height}
viewBox={`0 0 ${width} ${height}`}
style={{
"max-width": "100%",
height: "auto",
}}
>
<g stroke="#999" stroke-opacity={0.6}>
<For each={MergedLinks()}>
{(link) => (
<line
stroke-width={1}
x1={link?.source.x}
y1={link?.source.y}
x2={link?.target.x}
y2={link?.target.y}
/>
)}
</For>
</g>
<g stroke={"#fff"} stroke-width={1.5}>
<For each={MergedNodes()}>
{(node) => (
<circle r={5} fill={"green"} cx={node.x} cy={node.y}>
<title>{node.id}</title>
</circle>
)}
</For>
</g>
</svg>
);
};
11 replies
SSolidJS
Created by sachaw on 4/29/2024 in #support
Force effect computation, or alternate approach?
import { useLocalState } from "@hooks/useLocalState.js";
import { ReactiveMap } from "@solid-primitives/map";
import {
type Component,
For,
createComputed,
createEffect,
createMemo,
} from "solid-js";

interface Position {
x: number;
y: number;
}

export const DebugWindow: Component = () => {
const { localState } = useLocalState();
const width = 928;
const height = 600;

const positions = new ReactiveMap<string, Position>();

createComputed(() => {});

//initialize position
createEffect(() => {
for (const node of localState.serverStatus.mesh.nodes) {
if (!positions.has(node.id)) {
positions.set(node.id, {
x: (Math.random() / 10) * width,
y: (Math.random() / 10) * height,
});
}
}
});

createEffect(() => {
const intervalId = setInterval(() => {
const alpha = 0.1;
const distance = 30;
const strength = 0.1;

// Update positions logic
for (const node of localState.serverStatus.mesh.nodes) {
const position = positions.get(node.id);
if (!position) {
return;
}
let forceX = 1;
let forceY = 1;

for (const link of localState.serverStatus.mesh.edges) {
if (link.source === node.id) {
const target = positions.get(link.target);
if (target) {
const dx = target.x - position.x;
const dy = target.y - position.y;
const distance = Math.sqrt(dx * dx + dy * dy);
const force = (strength * (distance - distance)) / distance;
forceX += force * dx;
forceY += force * dy;
}
}
}

position.x += forceX * alpha;
position.y += forceY * alpha;

positions.set(node.id, position);
}
}, 1000); // Update every 1 second

return () => clearInterval(intervalId);
});
import { useLocalState } from "@hooks/useLocalState.js";
import { ReactiveMap } from "@solid-primitives/map";
import {
type Component,
For,
createComputed,
createEffect,
createMemo,
} from "solid-js";

interface Position {
x: number;
y: number;
}

export const DebugWindow: Component = () => {
const { localState } = useLocalState();
const width = 928;
const height = 600;

const positions = new ReactiveMap<string, Position>();

createComputed(() => {});

//initialize position
createEffect(() => {
for (const node of localState.serverStatus.mesh.nodes) {
if (!positions.has(node.id)) {
positions.set(node.id, {
x: (Math.random() / 10) * width,
y: (Math.random() / 10) * height,
});
}
}
});

createEffect(() => {
const intervalId = setInterval(() => {
const alpha = 0.1;
const distance = 30;
const strength = 0.1;

// Update positions logic
for (const node of localState.serverStatus.mesh.nodes) {
const position = positions.get(node.id);
if (!position) {
return;
}
let forceX = 1;
let forceY = 1;

for (const link of localState.serverStatus.mesh.edges) {
if (link.source === node.id) {
const target = positions.get(link.target);
if (target) {
const dx = target.x - position.x;
const dy = target.y - position.y;
const distance = Math.sqrt(dx * dx + dy * dy);
const force = (strength * (distance - distance)) / distance;
forceX += force * dx;
forceY += force * dy;
}
}
}

position.x += forceX * alpha;
position.y += forceY * alpha;

positions.set(node.id, position);
}
}, 1000); // Update every 1 second

return () => clearInterval(intervalId);
});
11 replies
SSolidJS
Created by sachaw on 11/21/2023 in #support
Most concise upsert for store?
I've shrunk it to this:
const updateNodes = (node: Node) => {
const index = localState.nodes.findIndex((n) => n.id === node.id);

setLocalState(
"nodes",
index === -1 ? localState.nodes.length : index,
node,
);
};
const updateNodes = (node: Node) => {
const index = localState.nodes.findIndex((n) => n.id === node.id);

setLocalState(
"nodes",
index === -1 ? localState.nodes.length : index,
node,
);
};
3 replies
SSolidJS
Created by sachaw on 11/19/2023 in #support
Nicest way of having computed properties in a store?
Since Getters are working now, is there a concise way to have side effects when the store is updated, withoug having a dedicated createEffect. I want to be able to call a grpc endpoint on my server when certain state properties are updated.
13 replies
SSolidJS
Created by sachaw on 11/19/2023 in #support
Nicest way of having computed properties in a store?
Was a damn race condition
13 replies
SSolidJS
Created by sachaw on 11/19/2023 in #support
Nicest way of having computed properties in a store?
Must be something else in my application, this works as it should, I'll keep digging: https://playground.solidjs.com/anonymous/6515f38a-c74d-4b51-b37f-5a2ede1a2005
13 replies
SSolidJS
Created by sachaw on 11/19/2023 in #support
Nicest way of having computed properties in a store?
I'll try to do a recreation, give me a few
13 replies
SSolidJS
Created by sachaw on 11/19/2023 in #support
Nicest way of having computed properties in a store?
remove it or leave an empty array?
13 replies
SSolidJS
Created by sachaw on 11/19/2023 in #support
Nicest way of having computed properties in a store?
I was originally destructuring the state variable that I passed to the context provider, I have since changed that so it just passes localState, however it's stil not working:
createEffect(() => {
console.log(localState.currentOperator);
}, [localState.currentOperator]);
createEffect(() => {
console.log(localState.currentOperator);
}, [localState.currentOperator]);
This only ever gets fired once
13 replies
SSolidJS
Created by sachaw on 11/19/2023 in #support
Nicest way of having computed properties in a store?
This is injected into a provider
13 replies