d3.js和Sankey图错误

时间:2015-11-26 04:35:51

标签: javascript d3.js sankey-diagram

我很难让我的第一个Sankey让数据变得非常简单:

{{ URL('/blog/'.$post->slug)}}

所以,我正在考虑以下列方式创建节点和链接 - 这是不成功的:

            Discharge   OBS ADM     FULL ADM    Total
Station 1   1725        610         708         3043
Station 2   1095        424         464         1983
Station 3   1652        24          27          1703

使用此index.html:

{
"nodes":[
{"name":"All Patients"},
{"name":"Station 1"},
{"name":"Station 2"},
{"name":"Station 3"},
{"name":"Discharge"},
{"name":"Obs Admission"},
{"name":"Full Admission"}
],
"links":[
{"source":"All Patients","target":"Station 1","value":3.043},
{"source":"All Patients","target":"Station 2","value":1.983},
{"source":"All Patients","target":"Station 3","value":1.703},
{"source":"Station 1","target":"Discharge","value":1.725},
{"source":"Station 2","target":"Discharge","value":1.095},
{"source":"Station 3","target":"Discharge","value":1.652},
{"source":"Station 1","target":"Obs Admission","value":.610},
{"source":"Station 2","target":"Obs Admission","value":.424},
{"source":"Station 3","target":"Obs Admission","value":.024},
{"source":"Station 1","target":"Full Admission","value":.708},
{"source":"Station 2","target":"Full Admission","value":.464},
{"source":"Station 3","target":"Full Admission","value":.027},
]}

这个sankey.js:

<!DOCTYPE html>
<meta charset="utf-8">
<title>SANKEY Experiment</title>
<style>

.node rect {
  cursor: move;
  fill-opacity: .9;
  shape-rendering: crispEdges;
}

.node text {
  pointer-events: none;
  text-shadow: 0 1px 0 #fff;
}

.link {
  fill: none;
  stroke: #000;
  stroke-opacity: .2;
}

.link:hover {
  stroke-opacity: .5;
}

</style>
<body>

<p id="chart">

<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="sankey.js"></script>
<script>

var units = "Widgets";

var margin = {top: 10, right: 10, bottom: 10, left: 10},
    width = 700 - margin.left - margin.right,
    height = 300 - margin.top - margin.bottom;

var formatNumber = d3.format(",.0f"),    // zero decimal places
    format = function(d) { return formatNumber(d) + " " + units; },
    color = d3.scale.category20();

// append the svg canvas to the page
var svg = d3.select("#chart").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", 
          "translate(" + margin.left + "," + margin.top + ")");

// Set the sankey diagram properties
var sankey = d3.sankey()
    .nodeWidth(36)
    .nodePadding(40)
    .size([width, height]);

var path = sankey.link();

// load the data
d3.json("sankey-formatted-names.json", function(error, graph) {

    var nodeMap = {};
    graph.nodes.forEach(function(x) { nodeMap[x.name] = x; });
    graph.links = graph.links.map(function(x) {
      return {
        source: nodeMap[x.source],
        target: nodeMap[x.target],
        value: x.value
      };
    });

  sankey
      .nodes(graph.nodes)
      .links(graph.links)
      .layout(32);

// add in the links
  var link = svg.append("g").selectAll(".link")
      .data(graph.links)
    .enter().append("path")
      .attr("class", "link")
      .attr("d", path)
      .style("stroke-width", function(d) { return Math.max(1, d.dy); })
      .sort(function(a, b) { return b.dy - a.dy; });

// add the link titles
  link.append("title")
        .text(function(d) {
            return d.source.name + " → " + 
                d.target.name + "\n" + format(d.value); });

// add in the nodes
  var node = svg.append("g").selectAll(".node")
      .data(graph.nodes)
    .enter().append("g")
      .attr("class", "node")
      .attr("transform", function(d) { 
          return "translate(" + d.x + "," + d.y + ")"; })
    .call(d3.behavior.drag()
      .origin(function(d) { return d; })
      .on("dragstart", function() { 
          this.parentNode.appendChild(this); })
      .on("drag", dragmove));

// add the rectangles for the nodes
  node.append("rect")
      .attr("height", function(d) { return d.dy; })
      .attr("width", sankey.nodeWidth())
      .style("fill", function(d) { 
          return d.color = color(d.name.replace(/ .*/, "")); })
      .style("stroke", function(d) { 
          return d3.rgb(d.color).darker(2); })
    .append("title")
      .text(function(d) { 
          return d.name + "\n" + format(d.value); });

// add in the title for the nodes
  node.append("text")
      .attr("x", -6)
      .attr("y", function(d) { return d.dy / 2; })
      .attr("dy", ".35em")
      .attr("text-anchor", "end")
      .attr("transform", null)
      .text(function(d) { return d.name; })
    .filter(function(d) { return d.x < width / 2; })
      .attr("x", 6 + sankey.nodeWidth())
      .attr("text-anchor", "start");

// the function for moving the nodes
  function dragmove(d) {
    d3.select(this).attr("transform", 
        "translate(" + d.x + "," + (
                d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))
            ) + ")");
    sankey.relayout();
    link.attr("d", path);
  }
});

</script>

</body>
</html>

它不起作用......不确定原因。非常感谢任何建议。

阿尔法

1 个答案:

答案 0 :(得分:0)

不幸的是,看起来像是一对非常小的错误。

1)你的链接{"source":"Station 3","target":"Full Admission","value":.027}**,**末尾有一个额外的逗号,所以使用更新的sankey-formatted-names.json文件,下面没有额外的逗号。我喜欢使用JSON验证器https://jsonformatter.curiousconcept.com/来确认是否有效的JSON文件。

2)另外,我查看了http://bl.ocks.org/d3noob/5028304处的示例JSON文件,它们的值为双引号。由于您将source和target作为字符串,因此看起来value也必须是一个字符串。如果您有源和目标作为数字,则值可以是数字。

{
"nodes":[
{"name":"All Patients"},
{"name":"Station 1"},
{"name":"Station 2"},
{"name":"Station 3"},
{"name":"Discharge"},
{"name":"Obs Admission"},
{"name":"Full Admission"}
],
"links":[
{"source":"All Patients","target":"Station 1","value":"3.043"},
{"source":"All Patients","target":"Station 2","value":"1.983"},
{"source":"All Patients","target":"Station 3","value":"1.703"},
{"source":"Station 1","target":"Discharge","value":"1.725"},
{"source":"Station 2","target":"Discharge","value":"1.095"},
{"source":"Station 3","target":"Discharge","value":"1.652"},
{"source":"Station 1","target":"Obs Admission","value":"0.610"},
{"source":"Station 2","target":"Obs Admission","value":"0.424"},
{"source":"Station 3","target":"Obs Admission","value":"0.024"},
{"source":"Station 1","target":"Full Admission","value":"0.708"},
{"source":"Station 2","target":"Full Admission","value":"0.464"},
{"source":"Station 3","target":"Full Admission","value":"0.027"}
]}