You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Tweakpane与3d-force-graph的集成,点击节点时展示属性并保留现有缩放功能

Solution: Display Node Properties in Tweakpane on Node Click for 3D-Force-Graph

Let's integrate the node property display with your existing onNodeClick zoom functionality, using Tweakpane to create a clean, passive info panel that shows all node attributes plus adjacent connections. Here's a step-by-step implementation:

1. Initialize Tweakpane with Dynamic Folders

First, set up your Tweakpane instance with dedicated folders for node details and adjacent connections. We'll use a dynamic object to hold the selected node's data, which we'll update on each click:

// Initialize Tweakpane
const pane = new Pane();

// Create folders for organized display
const nodeDetailsFolder = pane.addFolder({ title: 'Selected Node Details', expanded: true });
const adjacentFolder = pane.addFolder({ title: 'Adjacent Nodes & Links', expanded: false });

// Dynamic object to store current node's properties (updated on click)
let currentNodeParams = {};

2. Create a Helper Function to Update the Panel

This function will clear old content, populate the panel with the selected node's properties, and fetch adjacent connections:

function updateNodeDetails(node) {
  // Clear existing controls to avoid duplication
  nodeDetailsFolder.clear();

  // Map basic node properties to our dynamic object
  currentNodeParams = {
    Label: node.label,
    ID: node.id,
    Description: node.description,
    Type: node.type,
    Size: node.size,
    Color: node.color,
    Position: { x: node.x.toFixed(2), y: node.y.toFixed(2), z: node.z.toFixed(2) }
  };

  // Add basic properties to the panel (set to read-only)
  nodeDetailsFolder.addBinding(currentNodeParams, 'Label').disabled(true);
  nodeDetailsFolder.addBinding(currentNodeParams, 'ID').disabled(true);
  nodeDetailsFolder.addBinding(currentNodeParams, 'Description').disabled(true);
  nodeDetailsFolder.addBinding(currentNodeParams, 'Type').disabled(true);
  nodeDetailsFolder.addBinding(currentNodeParams, 'Size', { disabled: true });
  nodeDetailsFolder.addBinding(currentNodeParams, 'Color', { disabled: true });
  nodeDetailsFolder.addBinding(currentNodeParams, 'Position', { disabled: true });

  // Add nested graph metrics from the `attributes` object
  const metricsFolder = nodeDetailsFolder.addFolder({ title: 'Graph Metrics', expanded: false });
  Object.entries(node.attributes).forEach(([key, value]) => {
    currentNodeParams[key] = value;
    metricsFolder.addBinding(currentNodeParams, key).disabled(true);
  });

  // Update adjacent connections section
  updateAdjacentNodesAndLinks(node);
}

function updateAdjacentNodesAndLinks(node) {
  adjacentFolder.clear();
  const graph = yourForceGraphInstance.graphData(); // Replace with your graph instance variable

  // Fetch connected nodes and links using 3d-force-graph's built-in methods
  const connectedNodes = graph.getConnectedNodes(node.id);
  const connectedLinks = graph.getNodeLinks(node.id);

  // Display adjacent nodes as a read-only text area
  const nodeLabels = connectedNodes.map(n => n.label).join('\n');
  adjacentFolder.addInput(
    { 'Adjacent Nodes': nodeLabels },
    'Adjacent Nodes',
    { readonly: true, rows: Math.min(connectedNodes.length, 5) }
  );

  // Display adjacent links (source → target pairs)
  const linkPairs = connectedLinks.map(link => `${link.source.label} → ${link.target.label}`).join('\n');
  adjacentFolder.addInput(
    { 'Adjacent Links': linkPairs },
    'Adjacent Links',
    { readonly: true, rows: Math.min(connectedLinks.length, 5) }
  );
}

3. Integrate with Your Existing onNodeClick Logic

Modify your existing click handler to run the zoom logic and update the Tweakpane panel:

yourForceGraphInstance
  .onNodeClick(node => {
    // Existing zoom-to-node logic
    const distance = 40;
    const distRatio = 1 + distance/Math.hypot(node.x, node.y, node.z);
    const newPos = node.x || node.y || node.z ? 
      { x: node.x * distRatio, y: node.y * distRatio, z: node.z * distRatio } : 
      { x: 0, y: 0, z: distance }; // Handle (0,0,0) node case

    // Move camera to focus on the node (adjust duration as needed)
    yourForceGraphInstance.cameraPosition(newPos, node, 300);

    // Update Tweakpane with node details
    updateNodeDetails(node);
  });

Key Notes

  • Read-only Controls: All panel elements are set to disabled or readonly to maintain passive display, as requested.
  • Dynamic Updates: The clear() method ensures old node data is removed before adding new content, preventing cluttered panels.
  • Adjacent Connections: Uses 3d-force-graph's built-in getConnectedNodes and getNodeLinks methods to fetch related data efficiently.
  • Formatting: Position values are rounded to 2 decimal places for readability, but you can adjust this as needed.

内容的提问来源于stack exchange,提问作者greg.gan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 09:37:33