Skip to main content
 首页 » 编程设计

json之Sankey图过渡

2025年02月15日20zfyouxi

我想知道是否有一种简单的方法来修改Sankey diagram example,以便顺利过渡到新数据。例如,假设我有不同的数据文件(energy1.json,energy2.json ...),则d3如何为第一个数据集绘制Sankey图,然后等待,然后重新排列框的位置以表示第二个数据集?

请您参考如下方法:

这个有可能。这是使用csv文件的一种方法。在这里工作的Sankey:https://www.betterment.com/resources/investment-strategy/portfolio-management/portfolio-diversification/

  • 在d3.csv调用之外定义一个全局数组。
    var portfolioValues = []; 
    
  • 解析csv以创建节点/链接结构时,将值推送到全局数组。
    d3.csv("etf-geo.csv", function(error, data) { 
        graph = {"nodes" : [], "links" : []}; 
        data.forEach(function (d, i) { 
            var item = { source: d.source, target: d.target, values: [] }; 
            for (var j=0; j < 101; j++) { 
                item.values.push(d['value'+j.toString()]); 
            } 
            portfolioValues.push(item); 
            graph.nodes.push({ "name": d.source }); 
            graph.nodes.push({ "name": d.target }); 
            graph.links.push({ 
                source: portfolioValues[i].source, 
                target: portfolioValues[i].target, 
                value: portfolioValues[i].values[startingAllocation] 
            }); 
        }); 
     
    //this handy little function returns only the distinct / unique nodes 
    graph.nodes = d3.keys( 
        d3.nest() 
            .key(function (d) { return d.name; }) 
            .map(graph.nodes) 
    ); 
     
    // it appears d3 with force layout wants a numeric source and target 
    // so loop through each link replacing the text with its index from node 
    graph.links.forEach(function (d, i) { 
        graph.links[i].source = graph.nodes.indexOf(graph.links[i].source); 
        graph.links[i].target = graph.nodes.indexOf(graph.links[i].target); 
        portfolioValues[i].source = graph.links[i].source; 
        portfolioValues[i].target = graph.links[i].target; 
    }); 
     
    // now loop through each nodes to make nodes an array of objects 
    // rather than an array of strings 
    graph.nodes.forEach(function (d, i) { 
        graph.nodes[i] = { "name": d }; 
    }); 
     
    // construct sankey 
    sankey 
        .nodes(graph.nodes) 
        .links(graph.links) 
        .layout(); 
    
  • 监听更改并将用户输入传递给您的更新功能。
    $(".sankey-slider").bind("slider:changed", function (event, data) { 
     
    slideValue = data.value; 
     
    updateData(parseInt(slideValue)); 
     
     }); 
    
  • 创建一个临时数组,然后从全局数组中检索正确的值。调用sankey函数以重新计算布局。
        var newLinks = []; 
     
        portfolioValues.forEach(function(p, i) { 
            newLinks.push({ 
              source: p.source, 
              target: p.target, 
              value: p.values[allocation] 
            }); 
        }); 
     
        graph.links = newLinks; 
     
        sankey 
        .nodes(graph.nodes) 
        .links(graph.links) 
        .size([width, height]) 
        .layout(); 
    
  • 选择每个需要更改的元素并传递新的数据值。
    d3.selectAll(".link") 
      .data(graph.links) 
      .attr("d", path) 
      .attr("id", function(d,i){ 
        d.id = i; 
        return "link-"+i; 
      }) 
      .style("stroke-width", function(d) { return Math.max(1, d.dy); }) 
      .sort(function(a, b) { return b.dy - a.dy; }); 
     
    d3.selectAll(".node").attr("transform", function(d) { 
      return "translate(" + d.x + "," + d.y + ")"; }); 
     
    d3.selectAll("rect") 
    .attr("height", function(d) { return d.dy; }) 
    .on("mouseover",highlight_node_links) 
    .on("mouseout",onNodeMouseout); 
    

  • 在这里工作sankey:
    https://www.betterment.com/resources/investment-strategy/portfolio-management/portfolio-diversification/