使用d3,js在圆环图中更改arctween和数据集

时间:2014-01-13 05:10:04

标签: javascript jquery d3.js

点击一个按钮,我想在我的圆环图中添加一个新的数据集并让它转换新的数据集。我编写的代码就是这样做但当数据集中的单个数据的数量与前一个数据不同时(即从[1,2]到[1,2,3,4]),它会遇到问题。

我认为问题在于,只要新数据集有更多数据,我就需要创建一个新路径,并且只要有较少的数据就删除路径。但是,当我尝试在我的点击功能中附加数据时,它会在不删除旧路径的情况下附加数据并在图表上重叠。

这是一个没有附加的版本,其中arctween将起作用,但是会有空的圆弧,因为我没有追加路径(arctween工作的时间是一半): http://jsfiddle.net/njrPF/1/

var pieW = 500;
var pieH = 500;
var innerRadius = 100;
var outerRadius = 200;

var results_pie = d3.layout.pie()
    .sort(null);
var pie_arc = d3.svg.arc()
    .innerRadius(innerRadius)
    .outerRadius(outerRadius);

var svg_pie = d3.select("#pieTotal")
    .attr("width", pieW)
    .attr("height", pieH)
    .append("g")
    .attr("transform", "translate(" + pieW / 2 + "," + pieH / 2 + ")")
    .attr("class", "piechart");

var pie_path = svg_pie.selectAll("path").data(results_pie([1, 2]))
    .enter().append("path")
    .attr("d", pie_arc)
    .each(function (d) {
    this._current = d;
}) // store the initial values
.attr("class", "vote_arc")
    .attr("value", function (d, i) {
    return (i - 1);
});


var pie_votes = [1, 2];
var pie_colors = ["#0f0", "#f00"];
$(svg_pie).bind("monitor", worker);
$(svg_pie).trigger("monitor");

function worker(event) {
    pie_path = pie_path.data(results_pie(pie_votes))
        .attr("fill", function (d, i) {
        return pie_colors[i];
    });

    pie_path.transition().duration(500).attrTween("d", arcTween).each('end', function (d) {
        if (d.value <= 0) {
            this.remove();
        }
    });
    setTimeout(function () {
        $(svg_pie).trigger("monitor");
    }, 500);
}

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

$('button').click(function () {
    pie_votes = [];
    pie_colors = [];
    for (var i = 0; i < Math.floor(Math.random() * 6); i++) {
        //sets new values on pie arcs
        pie_votes.push(Math.floor(Math.random() * 10));
        pie_colors.push("#" + (Math.floor(Math.random() * 16777215)).toString(16));
    }
    pie_path = pie_path.data(results_pie(pie_votes))
        .attr("fill", function (d, i) {
        return pie_colors[i]
    });

    pie_path.transition().duration(500).attrTween("d", arcTween).each('end', function (d) {
        if (d.value <= 0) {
            this.remove();
        }
    });
});

这是一个版本,我尝试追加新路径,但它们重叠: http://jsfiddle.net/njrPF/3/

var pieW = 500;
var pieH = 500;
var innerRadius = 100;
var outerRadius = 200;

var results_pie = d3.layout.pie()
    .sort(null);
var pie_arc = d3.svg.arc()
    .innerRadius(innerRadius)
    .outerRadius(outerRadius);

var svg_pie = d3.select("#pieTotal")
    .attr("width", pieW)
    .attr("height", pieH)
    .append("g")
    .attr("transform", "translate(" + pieW / 2 + "," + pieH / 2 + ")")
    .attr("class", "piechart");

var pie_path = svg_pie.selectAll("path").data(results_pie([1, 2]))
    .enter().append("path")
    .attr("d", pie_arc)
    .each(function (d) {
    this._current = d;
}) // store the initial values
.attr("class", "vote_arc")
    .attr("value", function (d, i) {
    return (i - 1);
});

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

$('button').click(function () {
    pie_votes = [];
    pie_colors = [];
    for (var i = 0; i < Math.floor(Math.random() * 10); i++) {
        //sets new values on pie arcs
        pie_votes.push(Math.floor(Math.random() * 10));
        pie_colors.push("#" + (Math.floor(Math.random() * 16777215)).toString(16));
    }
    pie_path = pie_path.data(results_pie(pie_votes))
        .enter().append("path")
        .attr("d", pie_arc)
        .each(function (d) {
        this._current = d; }) // store the initial values
    .attr("class", "vote_arc")
        .attr("value", function (d, i) {
        return (i - 1);
    });
    pie_path.attr("fill", function (d, i) {
        return pie_colors[i]
    });

    pie_path.transition().duration(500).attrTween("d", arcTween).each('end', function (d) {
        if (d.value <= 0) {
            this.remove();
        }
    });
});

提前致谢。

1 个答案:

答案 0 :(得分:1)

您需要处理输入和退出选择以及更新选择。请参阅示例this tutorial。您案例中的相关代码将是

pie_path = pie_path.data(results_pie(pie_votes));

pie_path.enter().append("path")
    .attr("d", pie_arc)
    .each(function (d) {
        this._current = d;
    }) // store the initial values
    .attr("class", "vote_arc")
        .attr("value", function (d, i) {
        return (i - 1);
    });

pie_path.exit().remove();

完整示例here