无法使用d3.hierarchy构建非平衡树结构的技术求助
Hey there! Let's get that unbalanced tree working with D3.js. The issue you're hitting is that your addNode function isn't fully implemented to build the nested hierarchy structure that d3.hierarchy expects. Let's fix this step by step.
First, Understand What d3.hierarchy Needs
D3's hierarchy function requires a nested object structure where each node has:
- A data property (like
namein your case) - An optional
childrenarray for its child nodes
Let's Build a Working Tree Structure
Looking at your array ['F', 'G', 'I', 'H', 'B', 'A', 'D', 'C', 'E'], I'll assume you want an unbalanced tree like this:
F ├─ G │ ├─ I │ └─ H └─ B ├─ A └─ D ├─ C └─ E
Here's a complete, tested code example to build this structure and render it with d3.cluster:
// Your original array const array = [ 'F', 'G', 'I', 'H', 'B', 'A', 'D', 'C', 'E' ]; // Function to build the unbalanced tree structure function buildUnbalancedTree(arr) { if (arr.length === 0) return null; // Root node is the first element const root = { name: arr[0], children: [] }; let currentLevelNodes = [root]; let arrIndex = 1; while (arrIndex < arr.length) { const nextLevelNodes = []; for (const node of currentLevelNodes) { // Define how many children each node gets (adjust this for your specific structure) switch(node.name) { case 'G': case 'B': // These nodes get 2 children each node.children.push({ name: arr[arrIndex++] }); node.children.push({ name: arr[arrIndex++] }); nextLevelNodes.push(...node.children); break; case 'D': // D also gets 2 children node.children.push({ name: arr[arrIndex++] }); node.children.push({ name: arr[arrIndex++] }); nextLevelNodes.push(...node.children); break; default: // All other nodes have no children break; } } currentLevelNodes = nextLevelNodes; } return root; } // Set up the cluster layout const clusterLayout = d3.cluster().size([400, 200]); // Build the hierarchy data and run the layout const rootData = buildUnbalancedTree(array); const rootHierarchy = d3.hierarchy(rootData); clusterLayout(rootHierarchy); // Update function to render the tree (complete with nodes and links) function update(root) { // Grab or create an SVG container const svg = d3.select('#tree-container') .append('svg') .attr('width', 450) .attr('height', 250); // Draw connecting links svg.selectAll('.tree-link') .data(root.links()) .enter() .append('path') .attr('class', 'tree-link') .attr('d', d3.linkHorizontal() .x(d => d.y) .y(d => d.x)) .style('fill', 'none') .style('stroke', '#888') .style('stroke-width', 1.5); // Draw nodes and labels const nodes = svg.selectAll('.tree-node') .data(root.descendants()) .enter() .append('g') .attr('class', 'tree-node') .attr('transform', d => `translate(${d.y}, ${d.x})`); nodes.append('circle') .attr('r', 6) .style('fill', '#fff') .style('stroke', '#222') .style('stroke-width', 2); nodes.append('text') .attr('x', d => d.children ? -12 : 12) .attr('dy', '.35em') .style('font-family', 'Arial') .style('font-size', '12px') .style('text-anchor', d => d.children ? 'end' : 'start') .text(d => d.data.name); } // Render the tree! update(rootHierarchy);
Key Notes to Adjust for Your Needs
- If your desired tree structure is different, modify the
switchstatement inbuildUnbalancedTreeto match how many children each node should have. d3.clusterautomatically handles unbalanced trees—you don't need special configuration for that, as long as your hierarchy structure is correct.- Make sure your HTML has a container element with the ID
tree-container(or update the selector in theupdatefunction to match your page).
内容的提问来源于stack exchange,提问作者Curious
相关产品推荐
相关产品推荐

