且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

无法读取属性"0"未定义

更新时间:2022-05-08 21:28:19

您的问题出在这里:

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.