2016-04-14 4 views
2

Я приглашаю новичка в D3.js, и для проекта мне нужно сделать дончурт с данными, которые меняются каждые 2 секунды. Но каждый раз, когда я пытаюсь изменить данные я получаю сообщение об ошибке:D3 Uncaught TypeError: path.data не является функцией

Uncaught TypeError: path.data is not a function

я использовал this code в качестве примера для функции изменения

Код:

<!DOCTYPE html> 
 
<html lang="en"> 
 
<head> 
 
\t <meta charset="UTF-8"> 
 
\t <title>D3 donuttest</title> 
 
\t <script src="//d3js.org/d3.v3.min.jss"></script> \t 
 
\t <style> 
 

 
\t \t body { 
 
\t \t font: 10px sans-serif; 
 
\t \t } 
 
\t </style> 
 
</head> 
 
<body> 
 
</body> 
 
\t <div id="chartwrapper"> 
 
\t \t 
 
\t </div> 
 
</body> 
 
<script> 
 
\t var wrapper="#chartwrapper"; 
 
\t var dummydata=70; 
 
\t var data=[dummydata,100-dummydata]; 
 
\t var width = 460, 
 
\t  height = 300, 
 
\t  radius = Math.min(width, height)/2; 
 

 
\t var color = d3.scale.category20(); 
 

 
\t var pie = d3.layout.pie() 
 
\t  .sort(null); 
 

 
\t var arc = d3.svg.arc() 
 
\t  .innerRadius(radius - 100) 
 
\t  .outerRadius(radius - 50); 
 

 
\t var svg = d3.select(wrapper).append("svg") 
 
\t  .attr("width", width) 
 
\t  .attr("height", height) 
 
\t  .append("g") 
 
\t  .attr("transform", "translate(" + width/2 + "," + height/2 + ")"); 
 

 
\t var path = svg.selectAll("path") 
 
\t  .data(pie(data)) 
 
\t \t .enter().append("path") 
 
\t  .attr("fill", function(d, i) { return color(i); }) 
 
\t  .attr("d", arc) 
 
\t  .transition() 
 
\t  .ease("bounce") 
 
    \t .duration(1000) 
 
    \t .attrTween("d", initTween); 
 
    var label=svg.append("g") 
 
    .attr("class", "display") 
 
    .attr("transform", "translate(-30,10)"); 
 
var labeltext=label.append("text") 
 
    .attr("font-size","2rem") 
 
    .text(dummydata + "%"); 
 
    \t function change(data){ 
 
    \t \t labeltext.text(data[0] + "%"); 
 
    \t \t path.data(pie(data)); 
 
    \t \t path.transition().duration(750).attrTween("d",arcTween); 
 
    \t }; 
 
    //animation tween for when graph is drawn 
 
\t function initTween(b) { 
 
\t \t b.innerRadius = 0; 
 
\t \t var i = d3.interpolate({startAngle: 0, endAngle: 0}, b); 
 
\t \t return function(t) { return arc(i(t)); }; 
 
\t } 
 
\t //animation for when data is changed 
 
\t function arcTween(a) { 
 
\t \t var i = d3.interpolate(this._current, a); 
 
\t \t this._current = i(0); 
 
\t \t return function(t) { 
 
\t \t \t return arc(i(t)); 
 
\t \t }; 
 
\t }; 
 
\t //simulating data changes 
 
\t setInterval(function() { 
 
\t dummydata = parseInt(Math.random() * 100); 
 
\t data=[dummydata,100-dummydata]; 
 
\t console.log(data) 
 
\t \t change(data); 
 
\t },2000); 
 

 

 
</script>

ответ

1

Вот небольшая модификация вашего кода, которая может вам помочь. В качестве руководства я использовал this answer.

Модификации включают:

  • только сохранить результат append() в переменной path;
  • при первом рисовании диаграммы сохраните начальные углы в _current вместо использования функции initTween.

var wrapper = "#chartwrapper"; 
 
var dummydata = 70; 
 
var data = [dummydata, 100 - dummydata]; 
 

 
var width = 460, 
 
    height = 300, 
 
    radius = Math.min(width, height)/2; 
 

 
var color = d3.scale.category20(); 
 

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

 
var pie = d3.layout.pie() 
 
    .sort(null); 
 

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

 
var path = svg.selectAll("path") 
 
    .data(pie(data)) 
 
    .enter() 
 
    .append("path"); 
 

 
path.attr("fill", function(d, i) { 
 
    return color(i); 
 
    }) 
 
    .attr("d", arc) 
 
    .transition() 
 
    .ease("bounce") 
 
    .duration(1000) 
 
    .each(function(d) { 
 
    this._current = d; 
 
    }); // store the initial angles 
 

 
var label = svg.append("g") 
 
    .attr("class", "display") 
 
    .attr("transform", "translate(-30,10)"); 
 

 
var labeltext = label.append("text") 
 
    .attr("font-size", "2rem") 
 
    .text(dummydata + "%"); 
 

 
function change(data) { 
 
    labeltext.text(data[0] + "%"); 
 
    path.data(pie(data)); 
 
    path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs 
 

 
} 
 

 
function arcTween(a) { 
 
    var i = d3.interpolate(this._current, a); 
 
    this._current = i(0); 
 
    return function(t) { 
 
    return arc(i(t)); 
 
    }; 
 
} 
 

 
setInterval(function() { 
 
    dummydata = parseInt(Math.random() * 100); 
 
    data = [dummydata, 100 - dummydata]; 
 
    console.log(data) 
 
    change(data); 
 
}, 2000);
body { 
 
    font: 10px sans-serif; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
<div id="chartwrapper"></div>

Смежные вопросы