d3 | d3 pie chart | Display d3 tree | Search

This code prepares node and edge data for hierarchical visualization by establishing parent-child relationships and propagating branch information, effectively structuring the data as a tree.

Run example

npm run import -- "Format d3 tree"

Format d3 tree

function formatNodes(nodes, edges) {
    var nodeMap = {};
    nodes.forEach(function (x) {
        if (typeof x.size == 'undefined') {
            x.size = 1;
        }
        nodeMap[x.name] = x;
    });

    edges.forEach(function (x) {
        if (typeof nodeMap[x.source].children == 'undefined') {
            nodeMap[x.source].children = [];
        }
        nodeMap[x.target].parent = nodeMap[x.source];
        nodeMap[x.source].children.push(nodeMap[x.target]);
        // return { parent: nodeMap[x.target], source: nodeMap[x.source], target: nodeMap[x.target] };
    });
    edges.forEach(function (x) {
        if (typeof nodeMap[x.target].branch != 'undefined' && nodeMap[x.target].branch != ''
            && typeof nodeMap[x.source].branch == 'undefined' || nodeMap[x.source].branch == '') {
            nodeMap[x.source].branch = nodeMap[x.target].branch;
        }
    });
    
    return nodes;
};
module.exports = formatNodes;

What the code could have been:

/**
 * Formats node and edge data for graph representation.
 * @param {Object[]} nodes - Array of node objects.
 * @param {Object[]} edges - Array of edge objects.
 * @returns {Object[]} Formatted nodes with added properties.
 */
function formatNodes(nodes, edges) {
    // Create a node map for efficient lookup by name
    const nodeMap = {};
    
    // Initialize node properties and add to map
    nodes.forEach((node) => {
        if (typeof node.size === 'undefined') {
            node.size = 1;
        }
        nodeMap[node.name] = node;
    });
    
    // Establish parent-child relationships between nodes
    edges.forEach((edge) => {
        // Get the source and target nodes from the map
        const sourceNode = nodeMap[edge.source];
        const targetNode = nodeMap[edge.target];
        
        // Handle target node's parent and children
        if (!targetNode.parent) {
            targetNode.parent = sourceNode;
        }
        if (!sourceNode.children) {
            sourceNode.children = [];
        }
        sourceNode.children.push(targetNode);
    });
    
    // Transfer branch information from target to source nodes
    edges.forEach((edge) => {
        const sourceNode = nodeMap[edge.source];
        const targetNode = nodeMap[edge.target];
        
        // Only transfer branch if it's not already set or empty
        if (targetNode.branch && (!sourceNode.branch || sourceNode.branch === '')) {
            sourceNode.branch = targetNode.branch;
        }
    });
    
    // Return the formatted nodes
    return nodes;
}

module.exports = formatNodes;

This code processes a set of nodes and edges to prepare them for hierarchical visualization, likely a tree-like structure.

Here's a breakdown:

  1. Initialization:

  2. Node Processing:

  3. Edge Processing:

  4. Branch Propagation:

  5. Return:

In essence, this code transforms raw node and edge data into a hierarchical structure suitable for visualization as a tree diagram.