过渡弧时出错: 属性d:预期的弧标志('0'或'1')

问题描述 投票:2回答:1

我到处都在寻找解决方案,我已经尝试了所有方法,但无济于事!

当我单击以更新数据和饼图时,过渡无法正常工作,并且打印错误(错误:属性d:预期的弧形标志(“ 0”或“ 1”))超过100次。有人可以帮我吗?

这是代码的开头:

// set the dimensions and margins of the graph
var width = 320
    height = 450
    margin = 40

// The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin.
var radius = Math.min(width, height) / 2 - margin

// append the svg object to the div called 'my_dataviz'
var svg = d3.select("#recipe-graph")
  .append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

// create 2 data_set
//Aromatic Profile
//a: woody, b: floral, c: resinous, d: herbaceus, e: citrus, f: minty, 
var data1 = {a:56.2, b: 25, c:18.8} //woody, floral, resinous
var data2 = {b: 31.2, d: 50, e:18.8} //floral, herbaceus, citus
var data3 = {d: 33.3, e:11.1, f: 55.6} //herbaceous, citrus, minty
var data4 = {b: 56.2, c: 43.8} //floral, resinous
var data5 = {b: 82.6, e: 17.4} //floral, citrus

// set the color scale
var color = d3.scaleOrdinal()
  .domain(["a", "b", "c", "d", "e", "f"])
  .range(d3.schemeDark2);

我相信问题出在下面。 (我正在使用最新的d3.js库)

 // A function that create / update the plot for a given variable:
function update(data) {

  // Compute the position of each group on the pie:
  var pie = d3.pie()
    .value(function(d) {return d.value; })
    .sort(function(a, b) { console.log(a) ; return d3.ascending(a.key, b.key);} ) // This make sure that group order remains the same in the pie chart
  var data_ready = pie(d3.entries(data))

  // map to data
  var u = svg.selectAll("path")
    .data(data_ready)

  // Build the pie chart: Basically, each part of the pie is a path that we build using the arc function.
  u
    .enter()
    .append('path')
    .merge(u)
    .transition()
    .duration(1000)
    .attr('d', d3.arc()
      .innerRadius(0)
      .outerRadius(radius)
    )
    .attr('fill', function(d){ return(color(d.data.key)) })
    .attr("stroke", "white")
    .style("stroke-width", "2px")
    .style("opacity", 1)

  // remove the group that is not present anymore
  u
    .exit()
    .remove()

}

// Initialize the plot with the first dataset
update(data1)


//Change Recipe according to button selected
function selectCategory(category, results) {
    var postResults = document.getElementById(results);
    postResults.innerHTML = category;
  }
javascript d3.js svg transition
1个回答
0
投票

这在D3 API中没有很好的记录,但是您会找到几个在线上如何过渡弧的示例。您面临的最大问题(以及所导致错误的原因)是SVG d属性是一个长而复杂的字符串,并且由transition.attr提供的默认插值器为d3.interpolateString,不知道如何插值。

解决方案是将attrTween与自定义插值器一起使用。为此,您必须保存每个元素的先前基准。为此,我喜欢使用局部变量:

var local = d3.local();

selection.each(function(d) {
    local.set(this, d)
})

然后,在attrTween中:

transition.attrTween('d', function(d) {
  var i = d3.interpolate(local.get(this), d);
  local.set(this, i(0));
  return function(t) {
    return arc(i(t));
  };
})

这是您的代码,从data1转换为data2

// set the dimensions and margins of the graph
var width = 320
height = 450
margin = 40

// The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin.
var radius = Math.min(width, height) / 2 - margin

var local = d3.local();

// append the svg object to the div called 'my_dataviz'
var svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

// create 2 data_set
//Aromatic Profile
//a: woody, b: floral, c: resinous, d: herbaceus, e: citrus, f: minty, 
var data1 = {
  a: 56.2,
  b: 25,
  c: 18.8
} //woody, floral, resinous
var data2 = {
  b: 31.2,
  d: 50,
  e: 18.8
} //floral, herbaceus, citus
var data3 = {
  d: 33.3,
  e: 11.1,
  f: 55.6
} //herbaceous, citrus, minty
var data4 = {
  b: 56.2,
  c: 43.8
} //floral, resinous
var data5 = {
  b: 82.6,
  e: 17.4
} //floral, citrus

// set the color scale
var color = d3.scaleOrdinal()
  .domain(["a", "b", "c", "d", "e", "f"])
  .range(d3.schemeDark2);

var arc = d3.arc()
  .innerRadius(0)
  .outerRadius(radius)

// A function that create / update the plot for a given variable:
function update(data) {

  // Compute the position of each group on the pie:
  var pie = d3.pie()
    .value(function(d) {
      return d.value;
    })
    .sort(function(a, b) {
      return d3.ascending(a.key, b.key);
    }) // This make sure that group order remains the same in the pie chart
  var data_ready = pie(d3.entries(data))

  // map to data
  var u = svg.selectAll("path")
    .data(data_ready)

  // Build the pie chart: Basically, each part of the pie is a path that we build using the arc function.
  u
    .enter()
    .append('path')
    .each(function(d) {
      local.set(this, d)
    })
    .merge(u)
    .transition()
    .duration(1000)
    .attrTween('d', function(d) {
      var i = d3.interpolate(local.get(this), d);
      local.set(this, i(0));
      return function(t) {
        return arc(i(t));
      };
    })
    .attr('fill', function(d) {
      return (color(d.data.key))
    })
    .attr("stroke", "white")
    .style("stroke-width", "2px")
    .style("opacity", 1)

  // remove the group that is not present anymore
  u
    .exit()
    .remove()

}

// Initialize the plot with the first dataset
update(data1)


d3.timeout(function() {
  update(data2)
}, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
© www.soinside.com 2019 - 2024. All rights reserved.