D3.js bar chart not selecting or binding “date” data to Y axis label “text” elements on first ajax request

I'm building a dynamic bar chart that binds fetched JSON data requested via ajax, with the data being filtered according to values in Metric and Category select drop down menus. These values are passed as parameters to the controller and help decide what to query the database for. For some reason on the first ajax request that is sent (and only on the first, not the 2nd, not the 3rd, etc.) and no matter which select option is chosen, the "date" values that get sent back from the server with the JSON data do not display on the chart. For all subsequent ajax requests these date values display as expected, but not on the first request.

When looking at the DOM elements in Chrome developer tools, the ".labelContainer" g element is empty after this first ajax request. This means (atleast to me) that the update or enter selection's are not working properly, and that only the exit selection is working on this first request, which is odd because here is an example of the JSON data requested via ajax and there are clearly "date" values to be entered but which do not display on the first request:

[{"date":"23","load_volume":40},{"date":"24","load_volume":10},{"date":"28","load_volume":432},{"date":"30","load_volume":20}]

Furthermore, in the success function of my ajax request, where I assign the value to the label variable/function, if I perform a selectAll("text.label") instead of a selectAll(.labelContainer .label) like I do below:

var label = svg.selectAll(".labelContainer .label").data(data, function(d) { return d.date; });

... the dates do not display on every other request (i.e., on all odd requests they do not display, but they display on all even-numbered request).

EXAMPLE:

Default graph (rendered on page load):

First ajax request (no dates displayed):

Second ajax request (dates displayed):

Is there something I'm missing here? Any help would be appreciated. Below is the code that graphs the chart with some parts omitted for brevity. The "label" moniker corresponds to the Y axis text elements: Here is a gist of the full code: 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 ***//

EDIT

What the DOM looks like for initial graph (.labelContainer g filled with date label text elements):

What DOM looks like on first ajax request (.labelContainer g empty and no text elements):

And on second request (.labelContainer g empty but label text elements appear after it):

It appears that on the initial graph, the label selection is returning elements inside the .labelContainer g element. On update, the first ajax request returns nothing, and the second returns label text elements but not inside the .labelContainer g element.

Answers


Ok, for some reason I made the following edits to the code above and it now works, but I don't really understand it, because now on update it selects the .labelContainer text elements, but I removed the .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 ***//

Need Your Help

What does my error mean?

python debugging google-app-engine internationalization

I'm trying to send a localized email with a new password. It seems it crashes when I try to send the mail:

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.