From e383381ffce3da39a415fbc0ff3efd54f8a04420 Mon Sep 17 00:00:00 2001 From: Damian Tarnawski Date: Tue, 3 Sep 2024 23:18:37 +0200 Subject: [PATCH] Remove leftover stuff --- bun.lockb | Bin 404152 -> 404160 bytes web/components/routes/PublicHomeRoute.tsx | 12 - web/components/routes/force-graph-client.tsx | 336 ------------------- 3 files changed, 348 deletions(-) delete mode 100644 web/components/routes/force-graph-client.tsx diff --git a/bun.lockb b/bun.lockb index 17a8ed529aada364bdcffc175922ed6838c2947b..8b4cf25d3f6d5b4c9a178578368438dac8c8f463 100755 GIT binary patch delta 42149 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

SYJ)m7e+>C^Kqvm=Oi!s4Ty}( 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 P#>uIn1=IOZlkGYHtaqTs delta 42214 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 diff --git a/web/components/routes/PublicHomeRoute.tsx b/web/components/routes/PublicHomeRoute.tsx index 31a87ffc..de55ca15 100644 --- a/web/components/routes/PublicHomeRoute.tsx +++ b/web/components/routes/PublicHomeRoute.tsx @@ -1,6 +1,5 @@ "use client" import * as react from "react" -import type * as force_graph from "./force-graph-client" import { useCoState } from "@/lib/providers/jazz-provider" import { PublicGlobalGroup } from "@/lib/schema/master/public-group" import { ID } from "jazz-tools" @@ -9,7 +8,6 @@ import { Button } from "../ui/button" import Link from "next/link" let graph_data_promise = import("./graph-data.json").then(a => a.default) -// let ForceGraphClient = react.lazy(() => import("./force-graph-client-lazy")) const ForceGraphClient = dynamic(() => import("./force-graph-client-lazy"), { ssr: false }) export function PublicHomeRoute() { @@ -29,16 +27,6 @@ export function PublicHomeRoute() { ) const topics = globalGroup?.root.topics?.map(topic => topic?.prettyName) || [] - // let graph_items = react.useMemo(() => { - // return raw_graph_data.map( - // (item): force_graph.ConnectionItem => ({ - // key: item.name, - // title: item.prettyName, - // connections: item.connectedTopics - // }) - // ) - // }, [raw_graph_data]) - react.useEffect(() => { if (topics.length === 0) return diff --git a/web/components/routes/force-graph-client.tsx b/web/components/routes/force-graph-client.tsx deleted file mode 100644 index 0ad2e00a..00000000 --- a/web/components/routes/force-graph-client.tsx +++ /dev/null @@ -1,336 +0,0 @@ -"use client" - -import * as react from "react" -import * as fg from "@nothing-but/force-graph" -import { ease, trig } from "@nothing-but/utils" - -import * as schedule from "@/lib/utils/schedule" -import * as ws from "@/lib/utils/window-size" -import * as canvas from "@/lib/utils/canvas" - -import * as anim from "./anim" - -export type ConnectionItem = { - key: string - title: string - connections: string[] -} - -export type ForceGraphClientProps = { - items: ConnectionItem[] -} - -export default function ForceGraphClient(props: ForceGraphClientProps) { - return ( - -
{JSON.stringify(props.items, null, 4)}
-
- ) -} - -export type RawNode = { - name: string - prettyName: string - connections: string[] -} - -type HSL = [hue: number, saturation: number, lightness: number] - -const COLORS: readonly HSL[] = [ - [3, 86, 64], - [31, 90, 69], - [15, 87, 66] -] - -/* use a plain object instead of Map for faster lookups */ -type ColorMap = { [key: string]: string } -type HSLMap = Map - -const MAX_COLOR_ITERATIONS = 10 - -/** - * Add a color to a node and all its connected nodes. - */ -const visitColorNode = ( - prev: fg.graph.Node, - node: fg.graph.Node, - hsl_map: HSLMap, - add: HSL, - iteration: number = 1 -): void => { - if (iteration > MAX_COLOR_ITERATIONS) return - - const color = hsl_map.get(node) - - if (!color) { - hsl_map.set(node, [...add]) - } else { - const add_strength = MAX_COLOR_ITERATIONS / iteration - color[0] = (color[0] + add[0] * add_strength) / (1 + add_strength) - color[1] = (color[1] + add[1] * add_strength) / (1 + add_strength) - color[2] = (color[2] + add[2] * add_strength) / (1 + add_strength) - } - - for (const edge of node.edges) { - const other_node = edge.a === node ? edge.b : edge.a - if (other_node === prev) continue - visitColorNode(node, other_node, hsl_map, add, iteration + 1) - } -} - -const generateColorMap = (nodes: readonly fg.graph.Node[]): ColorMap => { - const hls_map: HSLMap = new Map() - - for (let i = 0; i < nodes.length; i++) { - const node = nodes[i]! - const color = COLORS[i % COLORS.length]! - visitColorNode(node, node, hls_map, color) - } - - const color_map: ColorMap = {} - for (const [node, [hue, saturation, lightness]] of hls_map.entries()) { - color_map[node.key as string] = `${hue} ${saturation}% ${lightness}%` - } - - return color_map -} - -const generateNodesFromRawData = (raw_data: RawNode[]): [fg.graph.Node[], fg.graph.Edge[]] => { - const nodes_map = new Map() - const edges: fg.graph.Edge[] = [] - - for (const raw of raw_data) { - const node = fg.graph.zeroNode() - node.key = raw.name - node.label = raw.prettyName - nodes_map.set(raw.name, node) - } - - for (const raw of raw_data) { - const node_a = nodes_map.get(raw.name)! - - for (const name_b of raw.connections) { - const node_b = nodes_map.get(name_b)! - const edge = fg.graph.connect(node_a, node_b) - edges.push(edge) - } - } - - const nodes = Array.from(nodes_map.values()) - - fg.graph.randomizeNodePositions(nodes, graph_options.grid_size) - - return [nodes, edges] -} - -const filterNodes = ( - graph: fg.graph.Graph, - nodes: readonly fg.graph.Node[], - edges: readonly fg.graph.Edge[], - filter: string -): void => { - if (filter === "") { - graph.nodes = nodes.slice() - graph.edges = edges.slice() - fg.graph.resetGraphGrid(graph.grid, graph.nodes) - return - } - - // regex matching all letters of the filter (out of order) - const regex = new RegExp(filter.split("").join(".*"), "i") - - graph.nodes = nodes.filter(node => regex.test(node.label)) - graph.edges = edges.filter(edge => regex.test(edge.a.label) && regex.test(edge.b.label)) - - fg.graph.resetGraphGrid(graph.grid, graph.nodes) -} - -const graph_options: fg.graph.Options = { - min_move: 0.001, - inertia_strength: 0.3, - origin_strength: 0.01, - repel_distance: 40, - repel_strength: 2, - link_strength: 0.015, - grid_size: 500 -} - -const TITLE_SIZE_PX = 400 - -const simulateGraph = ( - alpha: number, - graph: fg.graph.Graph, - canvas: fg.canvas.CanvasState, - vw: number, - vh: number -): void => { - alpha = alpha / 10 // slow things down a bit - - fg.graph.simulate(graph, alpha) - - /* - Push nodes away from the center (the title) - */ - const grid_radius = graph.grid.size / 2 - const origin_x = grid_radius + canvas.translate.x - const origin_y = grid_radius + canvas.translate.y - const vmax = Math.max(vw, vh) - const push_radius = - (Math.min(TITLE_SIZE_PX, vw / 2, vh / 2) / vmax) * (graph.grid.size / canvas.scale) + - 80 /* additional margin for when scrolled in */ - - for (const node of graph.nodes) { - const dist_x = node.position.x - origin_x - const dist_y = (node.position.y - origin_y) * 2 - const dist = Math.sqrt(dist_x * dist_x + dist_y * dist_y) - if (dist > push_radius) continue - - const strength = ease.in_expo((push_radius - dist) / push_radius) - - node.velocity.x += strength * (node.position.x - origin_x) * 10 * alpha - node.velocity.y += strength * (node.position.y - origin_y) * 10 * alpha - } -} - -const drawGraph = (canvas: fg.canvas.CanvasState, color_map: ColorMap): void => { - fg.canvas.resetFrame(canvas) - fg.canvas.drawEdges(canvas) - - /* - Draw text nodes - */ - const { ctx, graph } = canvas - - ctx.textAlign = "center" - ctx.textBaseline = "middle" - - const max_size = Math.max(canvas.ctx.canvas.width, canvas.ctx.canvas.height) - - for (const node of graph.nodes) { - const { x, y } = node.position - const opacity = 0.6 + ((node.mass - 1) / 50) * 4 - - ctx.font = `${max_size / 200 + (((node.mass - 1) / 5) * (max_size / 100)) / canvas.scale}px sans-serif` - - ctx.fillStyle = - node.anchor || canvas.hovered_node === node - ? `rgba(129, 140, 248, ${opacity})` - : `hsl(${color_map[node.key as string]} / ${opacity})` - - ctx.fillText(node.label, (x / graph.grid.size) * max_size, (y / graph.grid.size) * max_size) - } -} - -export type ForceGraphProps = { - onNodeClick: (name: string) => void - /** - * Filter the displayed nodes by name. - * - * `""` means no filter - */ - filter_query: string - raw_nodes: RawNode[] -} - -export const createForceGraph = (props: ForceGraphProps): react.JSX.Element => { - if (props.raw_nodes.length === 0) { - return <> - } - - let [nodes, edges] = generateNodesFromRawData(props.raw_nodes) - - let color_map = generateColorMap(nodes) - let bump_end = anim.bump(0) - let graph = fg.graph.makeGraph(graph_options, nodes.slice(), edges.slice()) - - /* - Filter nodes when the filter query changes - */ - let schedule_filter_nodes = schedule.scheduleIdle(filterNodes) - react.useEffect(() => { - schedule_filter_nodes.trigger(graph, nodes, edges, props.filter_query) - bump_end = anim.bump(bump_end) - }, [props.filter_query]) - - let canvas_el = react.useRef(null) - - react.useEffect(() => { - let el = canvas_el.current - if (!el) return - - let ctx = el.getContext("2d") - if (!ctx) throw new Error("no context") - - let canvas_state = fg.canvas.canvasState({ - ctx, - graph, - max_scale: 3, - init_scale: 1.7, - init_grid_pos: trig.ZERO - }) - - let window_size = ws.useWindowSize() - - let alpha = 0 // 0 - 1 - - let frame_iter_limit = anim.frameIterationsLimit() - - let loop = anim.animationLoop(time => { - let is_active = gestures.mode.type === fg.canvas.Mode.DraggingNode - let iterations = anim.calcIterations(frame_iter_limit, time) - - for (let i = Math.min(iterations, 2); i >= 0; i--) { - alpha = anim.updateAlpha(alpha, is_active || time < bump_end) - simulateGraph(alpha, graph, canvas_state, window_size.width, window_size.height) - } - drawGraph(canvas_state, color_map) - }) - anim.loopStart(loop) - - let ro = new ResizeObserver(() => { - if (canvas.resizeCanvasToDisplaySize(el)) { - fg.canvas.updateTranslate(canvas_state, canvas_state.translate.x, canvas_state.translate.y) - } - }) - ro.observe(el) - - let gestures = fg.canvas.canvasGestures({ - canvas: canvas_state, - onGesture: e => { - switch (e.type) { - case fg.canvas.GestureEventType.Translate: - bump_end = anim.bump(bump_end) - break - case fg.canvas.GestureEventType.NodeClick: - props.onNodeClick(e.node.key as string) - break - case fg.canvas.GestureEventType.NodeDrag: - fg.graph.changeNodePosition(canvas_state.graph.grid, e.node, e.pos.x, e.pos.y) - break - } - } - }) - - return () => { - anim.loopClear(loop) - ro.disconnect() - fg.canvas.cleanupCanvasGestures(gestures) - schedule_filter_nodes.clear() - } - }, [canvas_el.current]) - - return ( -
- -
- ) -}