javascript - D3.js sankey 的解析和无效值

标签 javascript json d3.js sankey-diagram

我目前正在尝试使用 D3.js 创建一个简单的 Sankey 图。我已经完成了大部分工作,但事实证明设置高度和 y 轴是一个挑战。具体返回的错误如下:

Error: Problem parsing d="M15, NaNC479, NaN 479, NaN 943, NaN" Error: Invalid value for attribute height = "NaN"

我已尝试遵循示例(有效):http://bost.ocks.org/mike/sankey/ 我的例子在这里:http://zenbot.ca/elections.html

请注意,下面的文本(“Brockville”、“Central Toronto”等)只是一个测试,以确保我正确连接到 JSON 文件,因此您可以忽略它。页面顶部的 blob 应该看起来像 Sankey 图,但目前不是。

我的 JSON 示例(可在 http://zenbot.ca/js/electionJSON.json 获得)似乎以与 Bostock 先生的示例 (http://bost.ocks.org/mike/sankey/energy.json) 相同的方式形成,如下所示:

{
  "nodes": [
    {"name": "Brockville"},
    {"name": "Central Toronto"},
    ...
  ],
  "links": [
    {"source": 0, "type": "Individual", "target": 26, "amount": 500},
    {"source": 5, "type": "Individual", "target": 16, "amount": 200},
    ...
  ]
}

我尝试自己解决问题的方法是尝试使用“d.dy”值(尝试将其替换为“d.amount”)。将其硬编码为“100”而不是大约第 79 行的函数使一个节点出现,但其余部分仍然是一团乱麻。

所以...这似乎取决于节点的高度和位置。它看起来很像 Bostock 的例子,但显然不是。有什么想法吗?

让 sankey 工作的代码如下:

d3.json("js/electionJSON.json", function(election) {

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

  var link = svg.append("g").selectAll(".link")
      .data(election.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; });

  link.append("title")
      .text(function(d) { return d.source.name + " → " + d.target.name + "\n" + format(d.amount); });

  var node = svg.append("g").selectAll(".node")
      .data(election.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));

  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.amount); });

  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");

  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);
  }
});

最佳答案

您可能会因为这个而自责,但对我来说,使用 sankey 实现很有趣。您现在最大的问题是 electionJSON.json 中的数据使用 amount 作为值。然而 sankey 期望该值被称为 value:

function value (link) {
  return link.value;
}

这将始终在您的数据集中返回 undefined。 sankey 似乎在多个地方做出了这个假设,所以我最终使用 sed 将“数量”一词替换为“值(value)”。这似乎可以解决问题。

关于javascript - D3.js sankey 的解析和无效值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20763975/

相关文章:

java - 使用 Webdriver 突出显示元素后等待几秒钟

javascript - 为什么@angular 表单中没有 FormArrayDirective?

json - Firebase: Exporting JSON Unable to export 单个位置导出的数据大小不能超过256MB

json - 如何将json对象作为参数传递给另一个powershell脚本

javascript - 组合多个字段中的文本字段集

javascript - 尝试直接从 javascript 控制 Paper.js 时出现奇怪的行为

iOS。是否可以覆盖远程 json 文件的内容或将其替换为新文件?

javascript - 按组查找最近的日期和输出值

javascript - D3 转换不适用于多个 <g> 元素

javascript - D3 - 将事件添加到酒吧