WIP
This commit is contained in:
+51
-6
@@ -1,23 +1,68 @@
|
||||
import "./GraphBrowser.css";
|
||||
import { type Component, createSignal, onMount } from "solid-js";
|
||||
import { createGraph, type Edge, type Graph, type Node } from "#/lib/Graph.ts";
|
||||
import type { Vector } from "#/lib/Vector.ts";
|
||||
import {
|
||||
drawEdge,
|
||||
drawNode,
|
||||
type Graph,
|
||||
type Node,
|
||||
type PositionPartial,
|
||||
} from "#/lib/Graph.ts";
|
||||
import { createVector, type Vector } from "#/lib/Vector.ts";
|
||||
|
||||
function drawGraph<T extends PositionPartial>(
|
||||
graph: Graph<T>,
|
||||
ctx: CanvasRenderingContext2D,
|
||||
): void {
|
||||
for (const [node, neighbours] of graph.entries()) {
|
||||
drawNode(node, ctx);
|
||||
for (const neighbour of neighbours) {
|
||||
drawEdge([node, neighbour], ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function placeNodes<T extends PositionPartial>(graph: Graph<T>): void {
|
||||
const visited: Array<Node<T>> = [];
|
||||
const currentPosition = createVector();
|
||||
const radius = 24;
|
||||
|
||||
for (const [node, neighbours] of graph.entries()) {
|
||||
if (visited.includes(node)) {
|
||||
continue;
|
||||
}
|
||||
visited.push(node);
|
||||
|
||||
node.position.x = currentPosition.x;
|
||||
node.position.y = currentPosition.y;
|
||||
|
||||
neighbours.forEach((neighbour, index) => {
|
||||
const fraction = (index + 1) / neighbours.length;
|
||||
const rad = Math.PI * 2 * fraction;
|
||||
neighbour.position.x = currentPosition.x + radius * Math.cos(rad);
|
||||
neighbour.position.y = currentPosition.y + radius * Math.sin(rad);
|
||||
visited.push(neighbour);
|
||||
});
|
||||
|
||||
currentPosition.y += radius * 2;
|
||||
}
|
||||
}
|
||||
|
||||
export const GraphBrowser: Component<{
|
||||
graph: Graph<{ position: Vector; label: string }>;
|
||||
}> = (props) => {
|
||||
let canvasRef!: HTMLCanvasElement;
|
||||
|
||||
const [width, setWidth] = createSignal(100);
|
||||
const [height, setHeight] = createSignal(100);
|
||||
const [width, setWidth] = createSignal(300);
|
||||
const [height, setHeight] = createSignal(300);
|
||||
|
||||
onMount(() => {
|
||||
const ctx: CanvasRenderingContext2D = canvasRef.getContext("2d", {
|
||||
alpha: false,
|
||||
})!;
|
||||
ctx.translate(width() / 2, height() / 2);
|
||||
|
||||
setWidth(canvasRef.parentElement!.offsetWidth);
|
||||
setHeight(width());
|
||||
placeNodes(props.graph);
|
||||
drawGraph(props.graph, ctx);
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
+6
-1
@@ -39,11 +39,16 @@ const nodes: Array<TestNode> = [
|
||||
{ position: createVector(), label: "foo" },
|
||||
{ position: createVector(), label: "bar" },
|
||||
{ position: createVector(), label: "lol" },
|
||||
{ position: createVector(), label: "hai" },
|
||||
{ position: createVector(), label: "sea" },
|
||||
{ position: createVector(), label: "vot" },
|
||||
];
|
||||
|
||||
const edges: Array<Edge<TestNode>> = [
|
||||
[nodes[0], nodes[1]],
|
||||
[nodes[1], nodes[2]],
|
||||
[nodes[0], nodes[2]],
|
||||
[nodes[0], nodes[3]],
|
||||
[nodes[4], nodes[5]],
|
||||
];
|
||||
|
||||
const graph = createGraph<TestNode>(nodes, edges);
|
||||
|
||||
+3
-5
@@ -4,14 +4,14 @@ export type Node<T> = T;
|
||||
export type Edge<T> = [Node<T>, Node<T>];
|
||||
export type Graph<T> = Map<Node<T>, Array<Node<T>>>;
|
||||
|
||||
type PositionPartial = {
|
||||
export type PositionPartial = {
|
||||
position: Vector;
|
||||
};
|
||||
|
||||
export function drawNode(
|
||||
node: Node<PositionPartial>,
|
||||
ctx: CanvasRenderingContext2D,
|
||||
color: string,
|
||||
color: string = "#fff",
|
||||
): void {
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = color;
|
||||
@@ -41,7 +41,7 @@ export function getNodeByPosition(
|
||||
export function drawEdge(
|
||||
edge: Edge<PositionPartial>,
|
||||
ctx: CanvasRenderingContext2D,
|
||||
color: string,
|
||||
color: string = "#fff",
|
||||
): void {
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = color;
|
||||
@@ -85,11 +85,9 @@ export function createGraph<T>(
|
||||
|
||||
export function originDFS<T>(origin: Node<T>, graph: Graph<T>): Array<Node<T>> {
|
||||
const visited: Array<Node<T>> = [origin];
|
||||
|
||||
if (!graph.has(origin)) {
|
||||
return visited;
|
||||
}
|
||||
|
||||
innerDFS(origin, graph, visited);
|
||||
|
||||
return visited;
|
||||
|
||||
Reference in New Issue
Block a user