D3.js&#34; <path>属性的值无效...&#34;但图表仍然更新

时间:2015-08-09 21:43:41

标签: javascript d3.js charts

我正在浏览Mike Bostock令人难以置信的一系列示例,我目前正在努力让我自己的Pie Update II版本正常工作(http://bl.ocks.org/mbostock/1346410)。我已经与此处显示的代码(http://jonsadka.com/blog/how-to-create-adaptive-pie-charts-with-transitions-in-d3/)混合在一起,以帮助我更好地了解实际发生的事情。通过这个,我的意思是我已经通过单独添加其他示例中的代码来调整mbostock示例,以查看哪些有效,哪些无效。

无论如何,我设置了一个简单的HTML页面,其中的单选按钮声明如下:

<form>
  <label><input type="radio" name="dataset" value="photoCounts2" checked> Photos</label>
  <label><input type="radio" name="dataset" value="videoCounts2"> Videos</label>
</form> 

我有一个大小相等的整数数组(10),名为videoCounts2photoCounts2。我试图能够点击单选按钮并将饼图调整到相应的数据集。我还不需要平稳过渡,我首先想让初始过渡工作。这是JavaScript:

/* ----------------------------------------------------------------------- */
// Global vars
/* ----------------------------------------------------------------------- */   
var width = 960,
    height = 500,
    radius = Math.min(width, height) / 2;

/* ----------------------------------------------------------------------- */
// Data Agnostic - Setup page elements
/* ----------------------------------------------------------------------- */       
var color = d3.scale.category20();

var pie = d3.layout.pie()
  .value(function(d) { return d; })
  .sort(null);

var arc = d3.svg.arc()
  .innerRadius(radius - 100)
  .outerRadius(radius - 20);

var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height);

var g = svg.append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

/* ----------------------------------------------------------------------- */
// Data Dependent
/* ----------------------------------------------------------------------- */       
var path = g.datum(photoCounts2).selectAll("path")
    .data(pie)
    .enter().append("path")
    .attr("fill", function(d, i) { return color(i); })
    .attr("d", arc)
    .each(function(d) { this._current = d; }); // store the initial angles

d3.selectAll("input")
    .on("change", change);

function change() {
    console.log("made it to change");
    data = ((this.value === "photoCounts2") ? photoCounts2 : videoCounts2); // This needs to be changed if the dataset is different than video count.
    console.log(this.value);
    // Transition the pie chart
    g.datum(data).selectAll("path")
        .data(pie)
        .transition()
        .attr("d", arc);

    // Add any new data
    g.datum(data).selectAll("path")
        .data(pie)
        .enter()
        .append("path")
        .attr("fill", function(d, i) { return color(i); })
        .attr("d", arc)
        .each(function(d) { this._current = d; }); // store the initial angles

    // Remove any unused data
    g.datum(data).selectAll("path")
        .data(pie)
        .exit()
        .remove();
}

我实际上获得了所需的功能,并且没有直观中断,但是当我在数据集之间切换时(通过选择不同的无线电输入),我不断将以下错误打印到控制台:

Error: Invalid value for <path> attribute d="M1.4083438190194563e-14,-230A230,230 0 0.000006912,1 217.6110300447649,-74.45790482200897L141.92023698571626,-48.559503144788465A150,150 0 0.000006912,0 9.184850993605149e-15,-150Z"
(anonymous function) @ d3.js:8717
tick @ d3.js:8914
(anonymous function) @ d3.js:8906
d3_timer_mark @ d3.js:2159
d3_timer_step @ d3.js:2139

我真的相信我已经在其他地方寻找解决方案的尽职调查,但我很难过。非常感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

您正在查看错误,因为转换生成的d的某些中间path值无效。由于每个都只能在几毫秒内看到,因此您实际上看不到错误。

问题的根本原因是D3的默认转换无法正确插入饼图段。要使其正常工作,您需要使用自定义属性补间,例如如this example

path.transition().duration(750).attrTween("d", arcTween);
function arcTween(a) {
  var i = d3.interpolate(this._current, a);
  this._current = i(0);
  return function(t) {
    return arc(i(t));
  };
}

这告诉D3如何生成所有中间值;在这种情况下,通过插入线段的角度并使用弧生成器生成更改角度的路径(而不是在不知道首先如何生成路径的情况下插入路径本身)。