WIP
This commit is contained in:
+51
-6
@@ -1,23 +1,68 @@
|
|||||||
import "./GraphBrowser.css";
|
import "./GraphBrowser.css";
|
||||||
import { type Component, createSignal, onMount } from "solid-js";
|
import { type Component, createSignal, onMount } from "solid-js";
|
||||||
import { createGraph, type Edge, type Graph, type Node } from "#/lib/Graph.ts";
|
import {
|
||||||
import type { Vector } from "#/lib/Vector.ts";
|
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<{
|
export const GraphBrowser: Component<{
|
||||||
graph: Graph<{ position: Vector; label: string }>;
|
graph: Graph<{ position: Vector; label: string }>;
|
||||||
}> = (props) => {
|
}> = (props) => {
|
||||||
let canvasRef!: HTMLCanvasElement;
|
let canvasRef!: HTMLCanvasElement;
|
||||||
|
|
||||||
const [width, setWidth] = createSignal(100);
|
const [width, setWidth] = createSignal(300);
|
||||||
const [height, setHeight] = createSignal(100);
|
const [height, setHeight] = createSignal(300);
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
const ctx: CanvasRenderingContext2D = canvasRef.getContext("2d", {
|
const ctx: CanvasRenderingContext2D = canvasRef.getContext("2d", {
|
||||||
alpha: false,
|
alpha: false,
|
||||||
})!;
|
})!;
|
||||||
|
ctx.translate(width() / 2, height() / 2);
|
||||||
|
|
||||||
setWidth(canvasRef.parentElement!.offsetWidth);
|
placeNodes(props.graph);
|
||||||
setHeight(width());
|
drawGraph(props.graph, ctx);
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
+6
-1
@@ -39,11 +39,16 @@ const nodes: Array<TestNode> = [
|
|||||||
{ position: createVector(), label: "foo" },
|
{ position: createVector(), label: "foo" },
|
||||||
{ position: createVector(), label: "bar" },
|
{ position: createVector(), label: "bar" },
|
||||||
{ position: createVector(), label: "lol" },
|
{ position: createVector(), label: "lol" },
|
||||||
|
{ position: createVector(), label: "hai" },
|
||||||
|
{ position: createVector(), label: "sea" },
|
||||||
|
{ position: createVector(), label: "vot" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const edges: Array<Edge<TestNode>> = [
|
const edges: Array<Edge<TestNode>> = [
|
||||||
[nodes[0], nodes[1]],
|
[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);
|
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 Edge<T> = [Node<T>, Node<T>];
|
||||||
export type Graph<T> = Map<Node<T>, Array<Node<T>>>;
|
export type Graph<T> = Map<Node<T>, Array<Node<T>>>;
|
||||||
|
|
||||||
type PositionPartial = {
|
export type PositionPartial = {
|
||||||
position: Vector;
|
position: Vector;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function drawNode(
|
export function drawNode(
|
||||||
node: Node<PositionPartial>,
|
node: Node<PositionPartial>,
|
||||||
ctx: CanvasRenderingContext2D,
|
ctx: CanvasRenderingContext2D,
|
||||||
color: string,
|
color: string = "#fff",
|
||||||
): void {
|
): void {
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
ctx.strokeStyle = color;
|
ctx.strokeStyle = color;
|
||||||
@@ -41,7 +41,7 @@ export function getNodeByPosition(
|
|||||||
export function drawEdge(
|
export function drawEdge(
|
||||||
edge: Edge<PositionPartial>,
|
edge: Edge<PositionPartial>,
|
||||||
ctx: CanvasRenderingContext2D,
|
ctx: CanvasRenderingContext2D,
|
||||||
color: string,
|
color: string = "#fff",
|
||||||
): void {
|
): void {
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
ctx.strokeStyle = color;
|
ctx.strokeStyle = color;
|
||||||
@@ -85,11 +85,9 @@ export function createGraph<T>(
|
|||||||
|
|
||||||
export function originDFS<T>(origin: Node<T>, graph: Graph<T>): Array<Node<T>> {
|
export function originDFS<T>(origin: Node<T>, graph: Graph<T>): Array<Node<T>> {
|
||||||
const visited: Array<Node<T>> = [origin];
|
const visited: Array<Node<T>> = [origin];
|
||||||
|
|
||||||
if (!graph.has(origin)) {
|
if (!graph.has(origin)) {
|
||||||
return visited;
|
return visited;
|
||||||
}
|
}
|
||||||
|
|
||||||
innerDFS(origin, graph, visited);
|
innerDFS(origin, graph, visited);
|
||||||
|
|
||||||
return visited;
|
return visited;
|
||||||
|
|||||||
Reference in New Issue
Block a user