D3.js进入转换路径不工作

时间:2013-07-25 17:54:49

标签: javascript animation charts d3.js visualization

我正在使用d3为一堆数据创建线图可视化。该行的数据来自一个对象数组,我使用此函数将该数据转换为可显示的svg路径:

this.line = d3.svg.line()
    .interpolate('linear')
    // .x(function(d,i) {return x(d['date']);})
    .x(function (d,i) {return x(i);})
    .y(function (d,i) {return y(d[this.key]) - this.yOffset;});

但是,如果我将所有数据保留为单个对象数组(并将其设置为路径的唯一数据点),那么我将无法使用进入和退出转换来添加/删除某些段如果我的数据集改变了大小,则构成该行。因此,为了解决这个问题,我使用这个函数将我的点数组分成一个2D数组:一个长度为2的数组,每个数组包含我的一行特定段的起点和终点,然后我用它array作为我路径的数据,屏幕上的每个段都分别绑定到它自己的2元素数组。

当我调用setData并输入时,路径完全按照预期绘制。但是,当我使用更新功能更新数据时(在这种情况下我转换为更长的数据集),路径将经历相应的更新和退出转换,这表明我在绑定数据时提供的关键功能是按预期工作。但是当我再次调用enter时,它不只是绘制需要添加的一个段 - 相反,它会删除现有路径,并重新绘制整个行,这次包括新行段。

这里有什么我想念的吗?如何使其仅为新段的绘制设置动画,而不是擦除现有的线段?

所有相关代码如下 - 如果我需要澄清更多信息,请随时发表评论:

提前致谢!

this.line = d3.svg.line()
    .interpolate('linear')
    .x(function (d,i) {return x(d['date']);})
    .y(function (d,i) {return y(d[this.key]) - this.yOffset;});

this.pathEnterData = function(selection) {
    this.path = selection.enter().append('path')
        .attr('class','segment')
        .attr('d',function(d, i) {return mThis.line(d);})
        .style('stroke', mThis.pathColor)
        .style('stroke-width',2)
        .style('fill','none');
};

this.pathEnterTransition = function(selection) {   
    return selection
        .attr("stroke-dasharray", function(d) { var totLength = d3.select(this).node().getTotalLength();
                                                    return totLength + " " + totLength; })
        .attr("stroke-dashoffset", function(d) { var totLength = d3.select(this).node().getTotalLength();
                                                    return totLength; })
        .transition()
            .delay(function(d,i) { return segmentDuration*i; })
            .duration(segmentDuration)
            .ease("linear")
            .attr('stroke-dashoffset',0);
};

this.enterData = function() {
    this.path.call(this.pathEnterData);
};

this.enterTransition = function() {
    this.path.call(this.pathEnterTransition);
};

this.enter = function() { 
    this.enterData();
    this.enterTransition();                  
};

this.exitTransition = function() {
    this.path.exit().transition()
        .duration(exitTransitionDuration)
        .style("stroke-opacity", 0.0)
        .style("fill-opacity", 0.0)
        .remove();
};

this.update = function(newData) {
    this.setData(newData);
    this.exitTransition();
    this.updateTransition();
    setTimeout(function() {mThis.enter();},updateTransitionDuration);
};

this.updateTransition = function() {
    this.bubbleCircles.transition()
        .duration(updateTransitionDuration)
        .attr("cx", function (d, i) { return x(d['date']); })
        .call(mThis.setCircleY);
    this.bubbleText.transition()
        .duration(updateTransitionDuration)
        .attr("x", function (d, i) { return x(d['date']) - (13.0/16)*bubbleNumberSize; })
        .call(mThis.setTextY);
};

this.setData = function(points) {
    var splitPoints = new Array(points.length-1);
    for(var i=0; i<points.length-1; i++) {
        splitPoints[i] = [points[i],points[i+1]];//{'start':points[i],'end':points[i+1]};
    }
    this.path = this.path.data(splitPoints,function(d,i){return d[1]['date']});
};

0 个答案:

没有答案