删除d3.js中的先前路径并转换为新数据

时间:2014-07-25 10:43:20

标签: javascript php jquery d3.js

我目前正在运行一个页面,该页面会在页面加载时生成带有默认值的图表。该页面从PHP脚本生成的TSV中获取数据,由GET参数修改。

然后,用户可以输入选项,并通过AJAX更新图表。

目前该页面几乎正常工作,但它是用新数据覆盖新路径而不删除旧路径。

新数据具有相同的x范围和域,但y坐标值不同,有时会有不同数量的值。

理想情况下,我希望旧路径能够从旧路径中流畅地过渡 - 我怎样才能实现这一目标?

我尝试在下面加入相关代码。对于质量差的道歉,我对d3很新。

...

var line = d3.svg.line()
    .interpolate("basis")
    .defined(function(d) {
        return d.result != 0;
    })
    .x(function(d) {
        return x(d.date);
    })
    .y(function(d) {
        return y(d.result);
    });

var svg = d3.select(".chart")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var txtDays = 7;
var txtStartDate = "01/01/2013";
var txtEndDate = "01/01/2014";
var txtInterval = 1;

requestDataURL = //removed for SO


    d3.tsv("http://localhost" + requestDataURL, function(error, data) {
        var varPolls = d3.keys(data[0]).filter(function(key) {
            return key !== "date";
        });

        data.forEach(function(d) {
            d.date = parseDate(d.date);
        });

        var results = varPolls.map(function(name) {
            return {
                name: name,
                values: data.map(function(d) {
                    return {
                        date: d.date,
                        result: +d[name]
                    };
                })
            };
        });


        x.domain(d3.extent(data, function(d) {
            return d.date;
        }));



        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);

        svg.append("g")
            .attr("class", "y axis")
            .call(yAxis)

        var group = svg.selectAll(".group")
            .data(results)
            .enter().append("g")
            .attr("class", "group")
            .attr("data-name", function(d) {
                return d.name;
            });

        group.append("path")
            .attr("class", "line")
            .attr("d", function(d) {
                return line(d.values);
            })
            .style("stroke", function(d) {
                return colors[d.name];
            });

        group.append("text")
            .datum(function(d) {
                return {
                    name: d.name,
                    value: d.values[d.values.length - 1]
                };
            })
            .attr("transform", function(d) {
                return "translate(" + x(d.value.date) + "," + y(d.value.result) + ")";
            })
            .attr("x", 3)
            .attr("dy", ".35em")
            .text(function(d) {
                return Math.round(d.value.result);;
            });

        d3.select(".submit")
            .attr('disabled', null);


    });

$(".submit").click(function(event) {
    var data = [];
    //SORT OUT VALIDATION


    var req = $.ajax({
        url: requestDataURL,
        dataType: 'text',
        success: function(response) {
            data = response;
        }
    });

    requestDataURL = //new data removed for SO

        $.when(req).done(function() {
            d3.tsv("http://localhost" + requestDataURL, function(error, data) {

                var varPolls = d3.keys(data[0]).filter(function(key) {
                    return key !== "date";
                });

                data.forEach(function(d) {
                    d.date = parseDate(d.date);
                });

                var results = varPolls.map(function(name) {
                    return {
                        name: name,
                        values: data.map(function(d) {
                            return {
                                date: d.date,
                                result: +d[name]
                            };
                        })
                    };
                });


                x.domain(d3.extent(data, function(d) {
                    return d.date;
                }));


                var group = svg.selectAll(".chart")
                    .data(results);

                group.exit().remove();

                group.enter().append("g");
                group.attr("class", "group")
                    .attr("data-name", function(d) {
                        return d.name;
                    });

                group.append("path")
                    .attr("class", "line")
                    .attr("d", function(d) {
                        return line(d.values);
                    })
                    .style("stroke", function(d) {
                        return colors[d.name];
                    });




                group.transition()
                    .duration(500)
                    .ease("linear")
                    .attr("d", group);

            });

        });
});

1 个答案:

答案 0 :(得分:1)

问题是您没有正确处理输入和更新选择。通常,追加操作应仅在输入选择时进行,而不是更新。获取新数据后,您将获得以下代码:

group.enter().append("g");
// ...
group.append("path");

这会将新的path元素添加到更新选择中,这是您在图表中看到的内容。处理新数据的正确方法如下:

var enterSel = group.enter().append("g");
// set attributes on the g elements
enterSel.append("path"); // append path elements to the new g elements

group.select("path") // select the path elements that are present, this includes the newly appended ones
     .attr("d", function(d) { // update the d attribute
       return line(d.values);
     });

此代码将为没有相应元素的数据项追加新元素,并为现有元素更新path