无法读取属性"0"未定义 [英] Cannot read property "0" of undefined

查看:115
本文介绍了无法读取属性"0"未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个div标签,如下所示.

I have a div tag like in the following.

<div id="line_chart" ></div>

,然后在脚本标签内添加d3代码以绘制图形.

and then d3 code inside script tags to draw a graph.

      var data = [{ "date": "2016.07.28", "close": 186889.45 }, { "date": 
      "2016.07.29", "close": 187156.54 }, { "date": "2016.08.01", "close": 
       187218.54 }, { "date": "2016.08.02", "close": 187624.73 }, { "date": 
       "2016.08.03", "close": 187198.72 }, { "date": "2016.08.05", "close": 
       185673.17 }, { "date": "2016.08.11", "close": 188383.55 }, { "date": 
       "2016.08.12", "close": 188033.59 }, { "date": "2016.08.13", "close": 
       187877.45 }, { "date": "2016.08.14", "close": 187877.45 }, { "date": 
       "2016.08.15", "close": 187935.9 }, { "date": "2016.08.16", "close": 
       180575.62 }, { "date": "2016.08.17", "close": 181022.03 }, { "date": 
       "2016.08.18", "close": 180294.82 }, { "date": "2016.08.19", "close": 
       194423.11 }];

            margin = {
                top: 20,
                right: 20,
                bottom: 20,
                left: 100
            };
            var width = 960,
                        height = 500;

            var vis = d3.select("#line_chart").append("svg")
                                .attr("width", width + margin.left + 
                                  margin.right)
                                .attr("height", height + margin.top + 
                                  margin.bottom);


            var parseTime = d3.time.format("%Y.%m.%d").parse;

            max_y = 0;
            min_y = data[0].close;
            var extent = d3.extent(data.map(function (d) { return d.date }))

            max_x = extent[1];
            min = extent[0];

            for (i = 0; i < data.length; i++) {
                max_y = Math.max(max_y, data[i].close);
                min_y = Math.min(min_y, data[i].close);
            }

            var x = d3.time.scale()
             .rangeRound([margin.left, width]);


            xScale = x.domain(d3.extent(data, function (d) {
                return parseTime(d.date);
            }));


            yScale = d3.scale.linear().range([height - margin.top, margin.bottom]).domain([min_y, max_y]),

            xAxis = d3.svg.axis()
            .scale(xScale),

            yAxis = d3.svg.axis()
            .scale(yScale)
            .orient("left");


            vis.append("svg:g")                
                .attr("class", "x axis")
                .style({ 'stroke': 'Black', 'fill': 'none', 'stroke-width': '1px' })
                .attr("transform", "translate(0," + (height - margin.bottom) + ")")                   
                .call(xAxis);


            vis.append("svg:g")                  
                .attr("class", "y axis")
                .style({ 'stroke': 'Black', 'fill': 'none', 'stroke-width': '1px' })
                .attr("transform", "translate(" + (margin.left) + ",0)")                    
                .call(yAxis);

            var line = d3.svg.line()
                 .x(function (d) {
                     return xScale(parseTime(d.date));
                 })
                 .y(function (d) {
                     return yScale(d.close);
                 })
                 .interpolate("basis");              

            vis.append('svg:path')
              .datum(data)
              .attr("fill", "none")
              .attr("stroke", "steelblue")
              .attr("stroke-linejoin", "round")
              .attr("stroke-linecap", "round")
              .attr("stroke-width", 1.5)
              .attr("d", line);


            var hoverLineGroup = vis.append("g")
                                .attr("class", "hover-line");

            var hoverLine = hoverLineGroup
                .append("line")
                    .attr("stroke", "#000")
                    .attr("x1", 10).attr("x2", 10)
                    .attr("y1", 0).attr("y2", height);

            var hoverTT = hoverLineGroup.append('text')
               .attr("class", "hover-tex capo")
               .attr('dy', "0.35em");

            var cle = hoverLineGroup.append("circle")
                .attr("r", 4.5);

            var hoverTT2 = hoverLineGroup.append('text')

               .attr("class", "hover-text capo")
               .attr('dy', "0.55em");

            hoverLineGroup.style("opacity", 1e-6);

            var rectHover = vis.append("rect")
              .data(data)
              .attr("fill", "none")
              .attr("class", "overlay")
              .attr("width", width)
              .attr("height", height);

            vis
                .on("mouseout", hoverMouseOff)
                .on("mousemove", hoverMouseOn);


            var bisectDate = d3.bisector(function (d) { return 
              parseTime(d.date); }).left;

            function hoverMouseOn() {

                var mouse_x = d3.mouse(this)[0];
                var mouse_y = d3.mouse(this)[1];
                var graph_y = yScale.invert(mouse_y);
                var graph_x = xScale.invert(mouse_x);

                var mouseDate = xScale.invert(mouse_x);
                var i = bisectDate(data, mouseDate);

                var d0 = data[i - 1]
                var d1 = data[i];

                var d = mouseDate - d0[0] > d1[0] - mouseDate ? d1 : d0;

                hoverTT.text("Date: " + d.date);                 
                hoverTT.attr('x', mouse_x);
                hoverTT.attr('y', yScale(d.close));


                hoverTT2.text("Portfolio Value: " + Math.round(d.close * 
             100) / 100)
                   .attr('x', mouse_x)
                   .attr('y', yScale(d.close) + 10);

                cle
                  .attr('x', mouse_x)
                  .attr('y', mouse_y);


                hoverLine.attr("x1", mouse_x).attr("x2", mouse_x)
                hoverLineGroup.style({ 'font-weight': 'bold', 'opacity': 1 
             });


            }

            function hoverMouseOff() {
                hoverLineGroup.style("opacity", 1e-6);
            }

该图是根据我想要的方式绘制的.没关系. 但是,当我打开javascript控制台(ctrl + shift + J)时,出现了几个错误.

The graph is drawn according to the way I've want. That's fine. But when I open the javascript console ( ctrl + shift + J) there are several errors.

 Uncaught ReferenceError: radOnResponseEnd is not defined
 Uncaught TypeError: Cannot read property '0' of undefined
 .
 .
 .

我认为这些错误是由于hoverMouseOn方法引起的. 以下行可疑

I think these errors are due to hoverMouseOn method. The following line is suspicious

var bisectDate = d3.bisector(function (d) { return parseTime(d.date); 
 }).left;

因为在函数hoverMouseOn()中使用了bisectDate,该函数将数组数据"与bisectDate一起使用.似乎数据"为空,这就是为什么它说无法读取未定义的属性"0""的原因.

Because bisectDate is used inside function hoverMouseOn() which uses array "data" together with bisectDate. It seems like "data" is empty and that is why it says "cannot read property "0" of undefined".

推荐答案

您的问题出在这里:

var bisectDate = d3.bisector(function(d) {
    return
    parseTime(d.date);
}).left;

在JavaScript中,当您在return ...

In JavaScript, when you put a new line after the return...

return
foo;

...您将返回foo.这与以下内容相同:

... you will not return foo. This is the same of:

return;
foo;

因此,您什么也不返回(或undefined).

So, you are returning nothing (or undefined).

解决方案:

必须为:

var bisectDate = d3.bisector(function(d) {
    return parseTime(d.date);
}).left;

这是您所做的更改的代码:

Here is your code with that change:

  var data = [{
    "date": "2016.07.28",
    "close": 186889.45
  }, {
    "date": "2016.07.29",
    "close": 187156.54
  }, {
    "date": "2016.08.01",
    "close": 187218.54
  }, {
    "date": "2016.08.02",
    "close": 187624.73
  }, {
    "date": "2016.08.03",
    "close": 187198.72
  }, {
    "date": "2016.08.05",
    "close": 185673.17
  }, {
    "date": "2016.08.11",
    "close": 188383.55
  }, {
    "date": "2016.08.12",
    "close": 188033.59
  }, {
    "date": "2016.08.13",
    "close": 187877.45
  }, {
    "date": "2016.08.14",
    "close": 187877.45
  }, {
    "date": "2016.08.15",
    "close": 187935.9
  }, {
    "date": "2016.08.16",
    "close": 180575.62
  }, {
    "date": "2016.08.17",
    "close": 181022.03
  }, {
    "date": "2016.08.18",
    "close": 180294.82
  }, {
    "date": "2016.08.19",
    "close": 194423.11
  }];

  margin = {
    top: 20,
    right: 20,
    bottom: 20,
    left: 100
  };
  var width = 960,
    height = 500;

  var vis = d3.select("body").append("svg")
    .attr("width", width + margin.left +
      margin.right)
    .attr("height", height + margin.top +
      margin.bottom);


  var parseTime = d3.time.format("%Y.%m.%d").parse;

  max_y = 0;
  min_y = data[0].close;
  var extent = d3.extent(data.map(function(d) {
    return d.date
  }))

  max_x = extent[1];
  min = extent[0];

  for (i = 0; i < data.length; i++) {
    max_y = Math.max(max_y, data[i].close);
    min_y = Math.min(min_y, data[i].close);
  }

  var x = d3.time.scale()
    .rangeRound([margin.left, width]);


  xScale = x.domain(d3.extent(data, function(d) {
    return parseTime(d.date);
  }));


  yScale = d3.scale.linear().range([height - margin.top, margin.bottom]).domain([min_y, max_y]),

    xAxis = d3.svg.axis()
    .scale(xScale),

    yAxis = d3.svg.axis()
    .scale(yScale)
    .orient("left");


  vis.append("svg:g")
    .attr("class", "x axis")
    .style({
      'stroke': 'Black',
      'fill': 'none',
      'stroke-width': '1px'
    })
    .attr("transform", "translate(0," + (height - margin.bottom) + ")")
    .call(xAxis);


  vis.append("svg:g")
    .attr("class", "y axis")
    .style({
      'stroke': 'Black',
      'fill': 'none',
      'stroke-width': '1px'
    })
    .attr("transform", "translate(" + (margin.left) + ",0)")
    .call(yAxis);

  var line = d3.svg.line()
    .x(function(d) {
      return xScale(parseTime(d.date));
    })
    .y(function(d) {
      return yScale(d.close);
    })
    .interpolate("basis");

  vis.append('svg:path')
    .datum(data)
    .attr("fill", "none")
    .attr("stroke", "steelblue")
    .attr("stroke-linejoin", "round")
    .attr("stroke-linecap", "round")
    .attr("stroke-width", 1.5)
    .attr("d", line);


  var hoverLineGroup = vis.append("g")
    .attr("class", "hover-line");

  var hoverLine = hoverLineGroup
    .append("line")
    .attr("stroke", "#000")
    .attr("x1", 10).attr("x2", 10)
    .attr("y1", 0).attr("y2", height);

  var hoverTT = hoverLineGroup.append('text')
    .attr("class", "hover-tex capo")
    .attr('dy', "0.35em");

  var cle = hoverLineGroup.append("circle")
    .attr("r", 4.5);

  var hoverTT2 = hoverLineGroup.append('text')

  .attr("class", "hover-text capo")
    .attr('dy', "0.55em");

  hoverLineGroup.style("opacity", 1e-6);

  var rectHover = vis.append("rect")
    .data(data)
    .attr("fill", "none")
    .attr("class", "overlay")
    .attr("width", width)
    .attr("height", height);

  vis
    .on("mouseout", hoverMouseOff)
    .on("mousemove", hoverMouseOn);


  var bisectDate = d3.bisector(function(d) {
    return parseTime(d.date);
  }).left;

  function hoverMouseOn() {

    var mouse_x = d3.mouse(this)[0];
    var mouse_y = d3.mouse(this)[1];
    var graph_y = yScale.invert(mouse_y);
    var graph_x = xScale.invert(mouse_x);

    var mouseDate = xScale.invert(mouse_x);
    var i = bisectDate(data, mouseDate);

    var d0 = data[i - 1] ? data[i - 1] : 0;
    var d1 = data[i] ? data[i] : 0;

    var d = mouseDate - d0[0] > d1[0] - mouseDate ? d1 : d0;

    hoverTT.text("Date: " + d.date);
    hoverTT.attr('x', mouse_x);
    hoverTT.attr('y', yScale(d.close));


    hoverTT2.text("Portfolio Value: " + Math.round(d.close *
        100) / 100)
      .attr('x', mouse_x)
      .attr('y', yScale(d.close) + 10);

    cle
      .attr('cx', mouse_x)
      .attr('cy', mouse_y);


    hoverLine.attr("x1", mouse_x).attr("x2", mouse_x)
    hoverLineGroup.style({
      'font-weight': 'bold',
      'opacity': 1
    });


  }

  function hoverMouseOff() {
    hoverLineGroup.style("opacity", 1e-6);
  }

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

PS :记住var d0 = data[i - 1];var d1 = data[i];.它们将在图表的边缘处为undefined.

PS: Mind that var d0 = data[i - 1]; and var d1 = data[i];. They will be undefined at the margins of the chart.

这篇关于无法读取属性"0"未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆