2014-03-24 51 views
-1

我想繪製一個簡單的面積圖,使用來自服務器,d3和backbone.js的數據。我發現了一個錯誤d3&backbone - 錯誤解析d =「」

問題解析d =「」

每當被拉出時的實際面積路徑。該錯誤出現兩次。在控制檯中的錯誤如下:

Error: Problem parsing d="" d3.v3.js:585 
attrFunction d3.v3.js:585 
(anonymous function) d3.v3.js:868 
d3_selection_each d3.v3.js:874 
d3_selectionPrototype.each d3.v3.js:867 
d3_selectionPrototype.attr d3.v3.js:567 
GraphBase.extend.renderData backboney.html:242 
Backbone.View.extend.render backboney.html:153 
(anonymous function) backboney.html:128 
fire jquery-2.0.2.js:2939 
self.fireWith jquery-2.0.2.js:3051 
done jquery-2.0.2.js:7428 
(anonymous function) 

這裏是我的工作代碼:

<!DOCTYPE html> 
<html> 
<head> 
    <title>BONEZY</title> 
    <style> 

      body { 
       font: .7em sans-serif; 
      } 

      #graph { 
       height: 600px; 
       width: 800px; 
      } 

      /* Styles axes of graph */ 
      .axis path { 
       fill: none; 
       stroke: #c9c9c9; 
       shape-rendering: crispEdges; 
      } 

      .axis line { 
       fill: none; 
       stroke: none; 
       shape-rendering: crispEdges; 
      } 

      /* Fill of graph */ 
      .area { 
       fill: #49decf; 
      } 

    </style> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 
</head> 
<body> 
<div id="graph"></div> 

<script src="jquery-2.0.2.js"></script> 
<script type="text/javascript" src="d3.v3.js"></script> 
<script type="text/javascript" src="underscore.js"></script> 
<script type="text/javascript" src="backbone.js"></script> 
<script> 
(function ($) { 

    var Entry = Backbone.Model.extend({}); 

    var Entries = Backbone.Collection.extend({ 
     url: 'http://sensors.metabolic.nl/api/v1/entry/?format=json', 
     model: Entry, 
     parse: function(response, xhr) { 
      // Get objects array from JSON response (actual entries) 
      //return response.objects; 
      //console.log('Response object value',response.objects[0].value); 
      _.each(response.objects, function (object) { 
       // Convert each value attribute to an actual array 
       object.value = toArray(object.value); 
       // Actually fuck it, just extract numerical value and set as value 
       // FIX WHEN NEW DATA STRUC EXISTS 
       object.value = object.value[1]; 
      }); 
      console.log('finished parsing', response.objects); 
      return response.objects; 
     } 
    }); 

     // Used to convert the shitty sensor value strings to arrays 
     function toArray(str) { 

      var trimRegEx = /[\'\[\]\s\*C\%]/g; 
      var newStr = str.replace(trimRegEx, ""); 

      var commaIndex = newStr.indexOf(",");  // Index of the comma (divider between values) 

      var sensorName = newStr.slice(0, commaIndex); 
      var sensorValue = newStr.slice(commaIndex + 1); 

      return new Array(sensorName, parseFloat(sensorValue)); 
     } 


    // Base of the graph that we will draw with d3 
    // MAD HELPS found at http://jtuulos.github.io/bayd3-may2013/ 
    var GraphBase = Backbone.View.extend({ 

     defaults: { 
      xAttr: "x", 
      yAttr: "y", 
      margin: { top: 20, right: 20, bottom: 20, left: 50 } 
     }, 

     initialize: function(options) { 

      var self = this; 
      // Constructor options no longer automatically copied 
      self.options = options; 
      self.collection = new Entries(); 
      _.bindAll(self, 'render'); 
      //self.collection.on('add', self.render(self.options)); 

      // Populate collection 
      self.collection.fetch({ 
       data: { /*offset: 20, limit: 20 */}, 
       add: true, 
       reset: true, 
       success: function(collection, response) { 
        console.log('Collection fetch success', response); 
        console.log('Collection models: ', collection.models); 
       }, 
       error: function() { 
        console.log('alas, failure'); 
       } 
      }).complete(function() { 
       console.log('complete!'); 
       self.render(self.options); 
      }); 
     }, 

     render: function(options) { 
      console.log('render graph base'); 

      this.options = options; 
      var margin = this.options.margin; 
      this.width = this.$el.width() - margin.left - margin.right; 
      this.height = this.$el.height() - margin.top - margin.bottom; 
      console.log("height", this.height); 

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

      this.scales = { 
       x: this.getXScale(), 
       y: this.getYScale() 
      }; 

      this.renderAxes(); 
      this.renderData(); 

      return this; 
     } 
    }); 

    // Extension of GraphBase View, contains everything related to data 
    var AreaGraph = GraphBase.extend({ 

     defaults: _.defaults({ 
      /*ex barPadding: 0.1 */ 
     }, GraphBase.prototype.defaults), 

     // Calculate and return scale and domain of X axis 
     getXScale: function() { 
      //console.log('x scale', this.collection.models[1].get('at')/*this.collection.pluck(this.options.at)*/); 
      console.log('Get X scale'); 
      var xAttr = this.options.xAttr; 
      return d3.time.scale() 
        .range([0, this.width]) 
        //.domain(this.collection.models.pluck(this.options.xAttr)); 
        .domain(this.collection.map(function(model) { 
         return model.get(xAttr); 
        })); 
     }, 
     // Calculate and return scale and domain of Y axis 
     getYScale: function() { 
      console.log('Get Y scale'); 
      var yAttr = this.options.yAttr; 
      return d3.scale.linear() 
        .range([this.height, 0]) 
        //.domain([0, 1.2 * d3.max(this.collection.pluck(this.options.yAttr))]); 
        .domain([0, 1.2 * d3.max(this.collection.map(function(model) { 
          return model.get(yAttr); 
         } 
        ))]); 
     }, 

     // Render the X and Y axis 
     renderAxes: function() { 
      console.log('render axes'); 

      var xAxis = d3.svg.axis() 
         .scale(this.scales.x) 
         .orient('bottom'); 

      var yAxis = d3.svg.axis() 
         .scale(this.scales.y) 
         .orient('left'); 
         /*.tickFormat(d3.format("") Option to modify ticks on axis*/ 

      //console.log('svg', this.svg); 

      // Adds X axis to graph 
      this.svg.append("g") 
       .attr("class", "x axis") 
       .attr("transform", "translate(0," + this.height + ")") 
       .call(xAxis); 

      // Adds Y axis to graph (ignore label for now) 
      this.svg.append("g") 
       .attr("class", "y axis") 
       .call(yAxis); 

     }, 

     // Render the actual data for the graph 
     renderData: function() { 
      console.log('render data'); 

      var chart = this, 
       x = this.scales.x, 
       y = this.scales.y; 

      // Calculate area under path 
      var area = d3.svg.area() 
         .x(function(d) { return x(d.at); }) 
         .y0(chart.height) 
         .y1(function(d) { return y(d.value); }); 

      console.log(this.collection.models); 
      this.svg.selectAll("path") 
       .data(this.collection.models) 
       .attr("class", "area") 
       //.attr("d", area); 
       .attr("d", function(d) { 
        // Generate area 
        var dArray = new Array(); 
        dArray[x] = d.get('at'); 
        dArray[y] = d.get('value'); 
        //return area(d.attributes); 
        return area(dArray); 
       }); 
     } 
    }); 

    // Graph object (AreaGraph inherits GraphBase) 
    var graph = new AreaGraph({ 

     // Backbone view options 
     el: '#graph', 
     // These are the data attributes to be read to determine values 
     xAttr: "at", 
     yAttr: "value", 
     margin: { top: 20, right: 20, bottom: 20, left: 50 } 

    }); 

})(jQuery); 

</script> 
</body> 
</html> 

任何瞭解非常感謝!如果你把你的代碼的jsfiddle

回答

0

會更容易調試,但這是錯誤的一個顯而易見的事情:

.attr("d", function(d) { 
    // Generate area 
    var dArray = new Array(); 
    dArray[x] = d.get('at'); 
    dArray[y] = d.get('value'); 
    //return area(d.attributes); 
    return area(dArray); 
}); 

此代碼不能真正使任何意義我。你的x,y是尺度,而不是數組索引。這意味着路徑的「d」屬性將變成垃圾(即,d =「」)。您應該使用註釋掉的代碼:

.attr("d", area); 

提請區域,並確保您的數據數組中的每個元素具有「.AT」和「.value的」屬性。