我目前正在运行一个页面,该页面会在页面加载时生成带有默认值的图表。该页面从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);
});
});
});
答案 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
。