.data()不是函数

时间:2018-01-18 04:58:05

标签: javascript d3.js real-time updates pie-chart

我正在构建一个实时更新的动态图表。

我设法用每个新的输入数据动态更新弧。但是我怎么想更新文本呢?

以下是我的代码,它一直在说.data() is not a function

function initDoughnutChart() {

console.log(JSON.stringify(dataset));
var width = 300,
height = 300,
radius = Math.min(width, height) / 2;

var outerRadius = width / 2;
var innerRadius = 100;

var colorValues = d3.scaleOrdinal().range(["#605A4C", "#ff9900", "#ff1a1a"]);


var pie = d3.pie()
        .value(function (d, i) {
            return d.percent;
        })
    .sort(null)
    .padAngle(.03);

var arc = d3.arc()
       .outerRadius(outerRadius)
       .innerRadius(innerRadius);

var svg = d3.select("#chart")
       .append("svg")
       .attrs({
           width: width,
           height: height,
           class: 'shadow'
       }).append('g')
       .attrs({
           transform: 'translate(' + width / 2 + ',' + height / 2 + ')'
       });

var path = svg.selectAll('path')
       .data(pie(dataset))
       .enter()
       .append('path')
       .attrs({
           d: arc
       }).each(function (d, i) {
           this._current = d;
       }).attrs({
           id: function (d, i) {
               return d.data.id;
           },
           class: function (d, i) {
               return d.data.class;
           },
           fill: function (d, i) {
               return colorValues(i);
           }
       });

var centroidLabels = svg.selectAll('text')
    .data(pie(dataset))
    .enter()
    .append("text")
    .transition()
    .duration(200)
    .attr("transform", function (d) {
        return "translate(" + arc.centroid(d) + ")";
    })
    .attr("dy", ".4em")
    .attr("text-anchor", "middle")
    .text(function (d) {
        return d.data.percent + "%";
    })
    .styles({
        fill: '#000000',
        'font-size': '15px'
    });

    path.transition()
        .duration(1000)
        .attrTween('d', function (d) {
            var interpolate = d3.interpolate({ startAngle: 0, endAngle: 0 }, d);
            return function (t) {
                return arc(interpolate(t));
            };
        });


var legendRectSize = 20;
var legendSpacing = 7;
var legendHeight = legendRectSize + legendSpacing;


var legend = svg.selectAll('.legend')
    .data(pie(dataset))
    .enter()
    .append('svg:g')
    .attrs({
        class: 'legend',
        transform: function (d, i) {
            return 'translate(-45,' + ((i * legendHeight) - 40) + ')';

        }
    });
legend.append('rect')
    .attrs({
        width: legendRectSize,
        height: legendRectSize,
        rx: 20,
        ry: 40
    })
    .styles({
        fill: function (d, i) {
            return colorValues(i);
        },
        stroke: function (d, i) {
            return colorValues(i);
        }
    });

legend.append('text')
    .attrs({
        x: 30,
        y: 15
    })
    .text(function (d, i) {
        return d.data.name;
    }).styles({
        fill: ' #C0C0C0',
        'font-size': '16px'
    });

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

function redrawDoughnutChart() {
    pie.value(function (d) {
        return d.percent;
    });
    console.log("new data" + JSON.stringify(dataset));
    path.data(pie(dataset))
        .transition().duration(750).attrTween("d", arcTween);

    //issue occur at this line of code
    centroidLabels.data(pie(dataset))
        .text(function(d, i){
            return d.data.percent + "%";
        });
}

//over here i return the respective object to an update function
//henceforth, each time the function is called, it will called the redrawDoughnutChart function
return {
    redrawDoughnut: redrawDoughnutChart
     }
}

1 个答案:

答案 0 :(得分:1)

你的变量centroidLabels是什么?我们来看看:

var centroidLabels = svg.selectAll('text') // returns a empty selection
    .data(pie(dataset))                    
    .enter()                               // returns a selection of items to enter
    .append("text")                        // returns a selection of entered text
    .transition()                          // returns a transition
    .duration(200)                         // everything else below returns the transition
    .attr("transform", function (d) {
        return "translate(" + arc.centroid(d) + ")";
    })
    .attr("dy", ".4em")
    .attr("text-anchor", "middle")
    .text(function (d) {
        return d.data.percent + "%";
    })
    .styles({
        fill: '#000000',
        'font-size': '15px'
    });

由于链接,您的变量不是选择,而是一个过渡。转换没有.data()方法,这就是您遇到该错误的原因。要解决这个问题,请尝试分解链:

    var centroidLabels = svg.selectAll('text')
        .data(pie(dataset))                    
        .enter()                               
        .append("text");                        

   centroidLabels.transition()                          
        .duration(200)
        .attr("transform", function (d) {
            return "translate(" + arc.centroid(d) + ")";
        })
        .attr("dy", ".4em")
        .attr("text-anchor", "middle")
        .text(function (d) {
            return d.data.percent + "%";
        })
        .styles({
            fill: '#000000',
            'font-size': '15px'
        });

虽然要使这些转换按预期工作,但您应该为每个属性提供初始值。