我正在构建一个动态条形图,它绑定通过 ajax 请求的获取的 JSON 数据,并根据 Metric 和 Category 选择下拉菜单中的值过滤数据。这些值作为参数传递给控制器,并帮助决定查询数据库的内容。出于某种原因,在发送的第一个 ajax 请求上(并且仅在第一个,不是第二个,不是第三个等)并且无论选择哪个选择选项,从服务器发回的“日期”值JSON 数据不显示在图表上。对于所有后续的 ajax 请求,这些日期值按预期显示,但不是在第一次请求时显示。
在 Chrome 开发者工具中查看 DOM 元素时,“.labelContainer”g 元素在第一个 ajax 请求之后是空的。这意味着(至少对我而言)更新或输入选择无法正常工作,并且只有退出选择正在处理第一个请求,这很奇怪,因为这是通过 ajax 请求的 JSON 数据的示例,并且显然有要输入但未在第一个请求中显示的“日期”值:
[{"date":"23","load_volume":40},{"date":"24","load_volume":10},{"date":"28","load_volume":432},{"date":"30","load_volume":20}]
此外,在我的 ajax 请求的成功函数中,我将值分配给标签变量/函数,如果我执行 selectAll("text.label") 而不是 selectAll(.labelContainer .label) 如下所示:
var label = svg.selectAll(".labelContainer .label").data(data, function(d) { return d.date; });
...日期不会显示在所有其他请求上(即,在所有奇数请求上它们不显示,但它们显示在所有偶数请求上)。
例子:
默认图表(在页面加载时呈现):
第一个 ajax 请求(不显示日期):
第二个 ajax 请求(显示日期):
我在这里缺少什么吗?任何帮助,将不胜感激。下面是绘制图表的代码,为简洁起见省略了一些部分。“标签”名称对应于 Y 轴文本元素: 这是完整代码的要点: https ://gist.github.com/kwyoung11/b9f1fe72e19bc70526db
$(document).ready(function () {
//*** Initial data request and graph configuration omitted for brevity, except for Y axis label configuration below, which is relevant ***//
// Place Y axis labels in g element for easy maneuvering
var label_group = svg.append("g").attr("class", "labelContainer").attr("transform", "translate(0,15)");
// Draw the Y axis labels.
label_group.selectAll("text").data(data).enter().append("text")
.attr("x", function(d, i) { return x(i) + (barWidth / 2) - 15; })
.attr("y", graphHeight)
.attr("class", "label")
.text(function(d) { return d.date; });
// Ajax request for updating the graph when user clicks option in select menu
$("#metric_select, #category_select").on('change', function () {
$.ajax({
//*** Ajax settings ommitted **** //
success: function(data) {
// Set the new Y scale.
var y = d3.scale.linear()
.domain([0, d3.max(data, function(d) { return d.load_volume; })])
.range([0, graphHeight]);
// Re-select chart elements and bind them to new data
//*** rect(bar/column) and text element re-selection omitted for brevity ***//
var label = svg.selectAll(".labelContainer .label").data(data, function(d) { return d.date; });
var delay = function(d, i) { return i * 50; };
// Updating rects and text.
// *** Omitted for brevity ***//
// Update the Y axis labels.
label.transition().duration(750)
.delay(delay)
.attr("x", function(d, i) { return x(i) + (barWidth / 2) - 15; })
.attr("y", graphHeight)
.attr("transform", "translate(0,15)")
.attr("class", "label")
.text(function(d) { return d.date; });
// Draw new rects and texts
// *** Omitted for brevity **//
// Draw new labels.
label.enter().append("text")
.attr("x", function(d, i) { return x(i) + (barWidth / 2) - 15; })
.attr("y", graphHeight)
.attr("transform", "translate(0,15)")
.attr("class", "label")
.text(function(d) { return d.date; });
// Exit selections
rect.exit().remove();
text.exit().remove();
label.exit().remove();
//*** closing brackets omitted for brevity ***//
编辑
初始图形的 DOM 是什么样的(.labelContainer g 填充了日期标签文本元素):
第一个 ajax 请求时 DOM 的样子(.labelContainer g 为空且没有文本元素):
在第二次请求时(.labelContainer g 为空,但标签文本元素出现在其后):
似乎在初始图表上,标签选择正在返回 .labelContainer g 元素内的元素。更新时,第一个 ajax 请求不返回任何内容,第二个返回标签文本元素,但不在 .labelContainer g 元素内。