Mapping arrays from csv file for tree hierarchy visualization using NodeJS

后端 未结 1 760
悲哀的现实
悲哀的现实 2021-01-26 06:16

I\'m trying to show the relationship between SQL tables in visualization. I have three columns in a csv sheet (columns: Target, Source, JoinSource).

Column Targe

1条回答
  •  清酒与你
    2021-01-26 06:46

    Note: your original sample data had missing nodes in the tree hierarchy, which I've filled in manually.

    I've transformed the data into the form {id, parentId, name} where P3.1.1 will emit {id: "P3.1.1", parentId: "P3.1", name: "Earth"}. This can be fed to d3.stratify that will build the hierarchy for you. I also a {id: "P", name: "Target"} for the root node.
    d3-stratify:
    https://github.com/d3/d3-hierarchy/blob/master/README.md#stratify
    demo

    I used this demo for hierarchy with a few adjustments to build the SVG tree: d3-hierarchy (demo)
    label was changed to extract name property by default instead of id, and I've embedded the dimensions directly into the function.

    It uses d3 Tidy Tree (demo) to render a d3-hierarchy.

    data = `[P1 Apple, P2 Mango, P2.1 Pluto, P3.1.1 Earth, P10 Red, P10.1 Blue, P10.1.1 Copper, P3 PewPewPew, P3.1 Chopper, P3.2 Twenty, P3.1.2 Two]`
    .slice(1,-1).split(', ')
    .map(x=>x.match(/^((.*?)(?:\.)?(?:\d*)?) (.*)$/).slice(1))
    .map(([id, parentId, name])=>({id, parentId, name}))
    
    data.push({id: 'P', name:'Target'})
    
    document.body.appendChild(graph(d3.stratify()(data)))
    
    function graph(root, {
      label = d => d.data.name, 
      highlight = () => false,
      marginLeft = 40
    } = {}) {
    width=500;
    dx=12;
    dy=120;
    treeLink = d3.linkHorizontal().x(d => d.y).y(d => d.x);
    tree = d3.tree().nodeSize([dx, dy]);
      root = tree(root);
    
      let x0 = Infinity;
      let x1 = -x0;
      root.each(d => {
        if (d.x > x1) x1 = d.x;
        if (d.x < x0) x0 = d.x;
      });
    
      const svg = d3.create("svg")
          .attr("viewBox", [0, 0, width, x1 - x0 + dx * 2])
          .style("overflow", "visible");
      
      const g = svg.append("g")
          .attr("font-family", "sans-serif")
          .attr("font-size", 10)
          .attr("transform", `translate(${marginLeft},${dx - x0})`);
        
      const link = g.append("g")
        .attr("fill", "none")
        .attr("stroke", "#555")
        .attr("stroke-opacity", 0.4)
        .attr("stroke-width", 1.5)
      .selectAll("path")
        .data(root.links())
        .join("path")
          .attr("stroke", d => highlight(d.source) && highlight(d.target) ? "red" : null)
          .attr("stroke-opacity", d => highlight(d.source) && highlight(d.target) ? 1 : null)
          .attr("d", treeLink);
      
      const node = g.append("g")
          .attr("stroke-linejoin", "round")
          .attr("stroke-width", 3)
        .selectAll("g")
        .data(root.descendants())
        .join("g")
          .attr("transform", d => `translate(${d.y},${d.x})`);
    
      node.append("circle")
          .attr("fill", d => highlight(d) ? "red" : d.children ? "#555" : "#999")
          .attr("r", 2.5);
    
      node.append("text")
          .attr("fill", d => highlight(d) ? "red" : null)
          .attr("dy", "0.31em")
          .attr("x", d => d.children ? -6 : 6)
          .attr("text-anchor", d => d.children ? "end" : "start")
          .text(label)
        .clone(true).lower()
          .attr("stroke", "white");
      
      return svg.node();
    }
    
    

    0 讨论(0)
提交回复
热议问题