From 0169014c2e325e303873090f96853d8cde9defc0 Mon Sep 17 00:00:00 2001 From: amcdnl Date: Thu, 6 Jul 2023 10:29:25 -0500 Subject: [PATCH] layouts working --- src/layout/circular2d.ts | 5 +++-- src/layout/forceDirected.ts | 20 ++++++++++---------- src/layout/forceUtils.ts | 6 +++--- src/layout/hierarchical.ts | 26 ++++++++++++-------------- src/store.ts | 8 ++++++-- 5 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/layout/circular2d.ts b/src/layout/circular2d.ts index 37db32fc..02ec3e4d 100644 --- a/src/layout/circular2d.ts +++ b/src/layout/circular2d.ts @@ -5,7 +5,7 @@ export interface CircularLayoutInputs extends LayoutFactoryProps { radius: 300; } -export const circular2d = ({ graph, radius }: CircularLayoutInputs) => { +export const circular2d = ({ graph, radius, drags }: CircularLayoutInputs) => { const layout = circular(graph, { scale: radius }); @@ -15,7 +15,8 @@ export const circular2d = ({ graph, radius }: CircularLayoutInputs) => { return true; }, getNodePosition(id: string) { - return layout?.[id]; + // If we dragged, we need to use that position + return (drags?.[id]?.position as any) || layout?.[id]; } }; }; diff --git a/src/layout/forceDirected.ts b/src/layout/forceDirected.ts index 01c1aec9..0c599dfb 100644 --- a/src/layout/forceDirected.ts +++ b/src/layout/forceDirected.ts @@ -36,28 +36,27 @@ export function forceDirected({ drags, clusterAttribute }: ForceDirectedLayoutInputs): LayoutStrategy { - const nodes: InternalGraphNode[] = []; - const links: InternalGraphEdge[] = []; const cluster = new Map(); + const nodes: InternalGraphNode[] = []; + const edges: InternalGraphEdge[] = []; - // Map the graph nodes / edges to D3 object - graph.forEachNode((_id, n) => { - // @ts-ignore + graph.forEachNode((id, n: any) => { nodes.push({ ...n, + id, // This is for the clustering radius: n.size || 1 }); }); graph.forEachEdge((id, l: any) => { - links.push({ ...l, id }); + edges.push({ ...l, id }); }); // Dynamically adjust node strength based on the number of edges const is2d = dimensions === 2; const nodeStrengthAdjustment = - is2d && links.length > 25 ? nodeStrength * 2 : nodeStrength; + is2d && edges.length > 25 ? nodeStrength * 2 : nodeStrength; // Create the simulation const sim = d3ForceSimulation() @@ -75,7 +74,7 @@ export function forceDirected({ 'dagRadial', forceRadial({ nodes, - links, + edges, mode, nodeLevelRatio }) @@ -118,7 +117,7 @@ export function forceDirected({ if (linkForce) { linkForce .id(d => d.id) - .links(links) + .links(edges) // When no mode passed, its a tree layout // so let's use a larger distance .distance(linkDistance); @@ -134,8 +133,9 @@ export function forceDirected({ return true; }, getNodePosition(id: string) { + console.log('here', drags?.[id], nodeMap.get(id)); // If we dragged, we need to use that position - return drags?.[id] || nodeMap.get(id); + return (drags?.[id]?.position as any) || nodeMap.get(id); } }; } diff --git a/src/layout/forceUtils.ts b/src/layout/forceUtils.ts index 9b0ba687..bd1416cf 100644 --- a/src/layout/forceUtils.ts +++ b/src/layout/forceUtils.ts @@ -16,7 +16,7 @@ export type DagMode = export interface ForceRadialInputs { nodes: InternalGraphNode[]; - links: InternalGraphEdge[]; + edges: InternalGraphEdge[]; mode: DagMode; nodeLevelRatio: number; } @@ -27,11 +27,11 @@ export interface ForceRadialInputs { */ export function forceRadial({ nodes, - links, + edges, mode = 'lr', nodeLevelRatio = 2 }: ForceRadialInputs) { - const { depths, maxDepth, invalid } = getNodeDepth(nodes, links); + const { depths, maxDepth, invalid } = getNodeDepth(nodes, edges); if (invalid) { return null; diff --git a/src/layout/hierarchical.ts b/src/layout/hierarchical.ts index 5b05f612..8c6267a4 100644 --- a/src/layout/hierarchical.ts +++ b/src/layout/hierarchical.ts @@ -1,11 +1,9 @@ import { InternalGraphEdge, InternalGraphNode } from 'types'; import { DepthNode, getNodeDepth } from './depthUtils'; -import { LayoutStrategy } from './types'; +import { LayoutFactoryProps, LayoutStrategy } from './types'; import { hierarchy, stratify, tree } from 'd3-hierarchy'; -import Graph from 'graphology'; -export interface HierarchicalLayoutInputs { - graph: Graph; +export interface HierarchicalLayoutInputs extends LayoutFactoryProps { mode?: 'td' | 'lr'; } @@ -24,20 +22,19 @@ const DIRECTION_MAP = { export function hierarchical({ graph, + drags, mode = 'td' }: HierarchicalLayoutInputs): LayoutStrategy { const nodes: InternalGraphNode[] = []; const edges: InternalGraphEdge[] = []; - // Itterate over the nodes and edges of the graph - // and put in a array for calcs - for (const n of graph.nodeEntries()) { - nodes.push(n as any); - } + graph.forEachNode((id, n: any) => { + nodes.push({ ...n, id }); + }); - for (const e of graph.edgeEntries()) { - edges.push(e as any); - } + graph.forEachEdge((id, l: any) => { + edges.push({ ...l, id }); + }); const { depths } = getNodeDepth(nodes, edges); const rootNodes = Object.keys(depths).map(d => depths[d]); @@ -55,7 +52,7 @@ export function hierarchical({ const mappedNodes = new Map( nodes.map(n => { - let { x, y } = treeNodes.find((t: any) => t.data.id === n.id); + const { x, y } = treeNodes.find((t: any) => t.data.id === n.id); return [ n.id, { @@ -73,7 +70,8 @@ export function hierarchical({ return true; }, getNodePosition(id: string) { - return mappedNodes.get(id); + // If we dragged, we need to use that position + return (drags?.[id]?.position as any) || mappedNodes.get(id); } }; } diff --git a/src/store.ts b/src/store.ts index 522a8cfe..83e2f938 100644 --- a/src/store.ts +++ b/src/store.ts @@ -76,8 +76,8 @@ export const createStore = ({ const originalVector = getVector(node); const newVector = new Vector3(position.x, position.y, position.z); const offset = newVector.sub(originalVector); - const nodes = [...state.nodes]; + if (state.selections?.includes(id)) { state.selections?.forEach(id => { const node = state.nodes.find(n => n.id === id); @@ -91,9 +91,13 @@ export const createStore = ({ const nodeIndex = state.nodes.indexOf(node); nodes[nodeIndex] = updateNodePosition(node, offset); } + return { ...state, - drags: { ...state.drags, [id]: node }, + drags: { + ...state.drags, + [id]: node + }, nodes }; }),