0

我正在构建一个动态条形图,它绑定通过 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请求之后。 不显示日期

第二个 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 元素内。

4

1 回答 1

0

好的,由于某种原因,我对上面的代码进行了以下编辑,现在它可以工作了,但我不太明白,因为现在更新时它选择了 .labelContainer 文本元素,但我删除了 .labelContainer ...

$(document).ready(function () {

 //*** Initial data request and graph configuration omitted for brevity, except for Y axis label configuration below, which is relevant ***//

  // Draw the Y axis labels. ****CHANGED HERE****
  svg.append("g").selectAll("text").data(data).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; });

            // 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 ***//
// ****CHANGED HERE****
                                var label = svg.selectAll(".labelContainer text").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 ***//
于 2013-05-01T21:19:30.750 回答