From 47618defb7188e0b5e8c5db03b09115e08e93d7c Mon Sep 17 00:00:00 2001 From: "Thomas F. K. Jorna" Date: Thu, 15 Jul 2021 15:34:15 +0200 Subject: added node size by connections --- app/components/graph/graph.tsx | 187 +++++++++++++++++++++-------------------- 1 file changed, 98 insertions(+), 89 deletions(-) (limited to 'app') diff --git a/app/components/graph/graph.tsx b/app/components/graph/graph.tsx index 7a4843b..38a4c80 100644 --- a/app/components/graph/graph.tsx +++ b/app/components/graph/graph.tsx @@ -11,9 +11,8 @@ import { flatten } from "ramda" //import rando from "../../data/rando.json" import rando from "../../data/randorev.json" - -import { ForceGraph2D, ForceGraph3D, ForceGraphVR, ForceGraphAR } from 'react-force-graph'; -import * as d3 from "d3-force"; +import { ForceGraph2D, ForceGraph3D, ForceGraphVR, ForceGraphAR } from "react-force-graph" +import * as d3 from "d3-force" const CONTAINER: ViewStyle = { justifyContent: "center", @@ -30,8 +29,8 @@ export interface GraphProps { * An optional style override useful for padding & margin. */ style?: StyleProp - physics - gData + physics + gData } /** @@ -41,91 +40,101 @@ export const Graph = observer(function Graph(props: GraphProps) { const { style, physics, gData } = props const styles = flatten([CONTAINER, style]) - const fgRef= useRef(); - - - const GROUPS: number =12; - //const gData = genRandomTree(200); - - //const [charge, setCharge] = useState(-30); - //const [link, setLink] = useState(-30); - - useEffect(()=> { - const fg = fgRef.current; - - //fg.d3Force('center').strength(0.05); - fg.d3Force('link').strength(physics.linkStrength); - fg.d3Force('link').iterations(physics.linkIts); - physics.collision ? fg.d3Force('collide', d3.forceCollide().radius(20)) : fg.d3Force('collide',null); - fg.d3Force('charge').strength(physics.charge); - }); - - const rootId = 0; - - const nodesById = useMemo(() => { - const nodesById = Object.fromEntries(rando.nodes.map(node => [node.id, node])); - - // link parent/children - rando.nodes.forEach(node => { - node.collapsed = node.id !== rootId; - node.childLinks = []; - }); - rando.links.forEach(link => nodesById[link.source].childLinks.push(link)); - - return nodesById; - }, [rando]); - - const getPrunedTree = useCallback(() => { - const visibleNodes = []; - const visibleLinks = []; - (function traverseTree(node = nodesById[rootId]) { - visibleNodes.push(node); - if (node.collapsed) return; - visibleLinks.push(...node.childLinks); - node.childLinks - .map(link => ((typeof link.target) === 'object') ? link.target : nodesById[link.target]) // get child node - .forEach(traverseTree); - })(); - - return { nodes: visibleNodes, links: visibleLinks }; - }, [nodesById]); - - const [prunedTree, setPrunedTree] = useState(getPrunedTree()); - - const handleNodeClick = useCallback(node => { - node.collapsed = !node.collapsed; // toggle collapse state - setPrunedTree(getPrunedTree()) - }, []); - - return ( + const fgRef = useRef() + + const GROUPS: number = 12 + //const gData = genRandomTree(200); + + //const [charge, setCharge] = useState(-30); + //const [link, setLink] = useState(-30); + + useEffect(() => { + const fg = fgRef.current + + //fg.d3Force('center').strength(0.05); + fg.d3Force("link").strength(physics.linkStrength) + fg.d3Force("link").iterations(physics.linkIts) + physics.collision + ? fg.d3Force("collide", d3.forceCollide().radius(20)) + : fg.d3Force("collide", null) + fg.d3Force("charge").strength(physics.charge) + }) + + const rootId = 0 + + const nodesById = useMemo(() => { + const nodesById = Object.fromEntries(rando.nodes.map((node) => [node.id, node])) + + // link parent/children + rando.nodes.forEach((node) => { + node.collapsed = node.id !== rootId + node.childLinks = [] + node.parentLink = [] + }) + rando.links.forEach((link) => nodesById[link.source].childLinks.push(link)) + + return nodesById + }, [rando]) + + const getPrunedTree = useCallback(() => { + const visibleNodes = [] + const visibleLinks = [] + ;(function traverseTree(node = nodesById[rootId]) { + visibleNodes.push(node) + if (node.collapsed) return + visibleLinks.push(...node.childLinks) + node.childLinks + .map((link) => (typeof link.target === "object" ? link.target : nodesById[link.target])) // get child node + .forEach(traverseTree) + })() + + return { nodes: visibleNodes, links: visibleLinks } + }, [nodesById]) + + const [prunedTree, setPrunedTree] = useState(getPrunedTree()) + + const handleNodeClick = useCallback((node) => { + node.collapsed = !node.collapsed // toggle collapse state + setPrunedTree(getPrunedTree()) + }, []) + + return ( - {!physics.threedim ? - d.id%GROUPS} - linkAutoColorBy={d => rando.nodes[d.source].id%GROUPS} - linkColor={"#ffffff"} - linkWidth={2} - linkDirectionalParticles={2} - nodeColor={node => !node.childLinks.length ? 'green' : node.collapsed ? 'red' : 'yellow'} - onNodeClick={handleNodeClick} - //d3VelocityDecay={visco} - /> - : - d.id%GROUPS} - linkAutoColorBy={d => rando.nodes[d.source].id%GROUPS} - linkColor={"#ffffff"} - linkWidth={2} - linkDirectionalParticles={2} - nodeColor={node => !node.childLinks.length ? 'green' : node.collapsed ? 'red' : 'yellow'} - onNodeClick={handleNodeClick} - //d3VelocityDecay={visco} - /> - } + {!physics.threedim ? ( + d.id%GROUPS} + linkAutoColorBy={(d) => rando.nodes[d.source].id % GROUPS} + linkColor={"#ffffff"} + linkWidth={2} + linkDirectionalParticles={2} + nodeColor={(node) => + !node.childLinks.length ? "green" : node.collapsed ? "red" : "yellow" + } + onNodeClick={handleNodeClick} + nodeLabel={(node) => "label"} + nodeVal ={(node)=> node.childLinks.length * 0.5 + 1} + //d3VelocityDecay={visco} + /> + ) : ( + d.id%GROUPS} + linkAutoColorBy={(d) => rando.nodes[d.source].id % GROUPS} + linkColor={"#ffffff"} + linkWidth={2} + linkDirectionalParticles={2} + nodeColor={(node) => + !node.childLinks.length ? "green" : node.collapsed ? "red" : "yellow" + } + onNodeClick={handleNodeClick} + nodeVal ={(node)=> node.childLinks.length + 1} + linkOpacity={0.8} + //d3VelocityDecay={visco} + /> + )} ) }) -- cgit v1.2.3