TypeError:无法读取未定义的属性"year" [英] TypeError: Cannot read property 'year' of undefined

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

问题描述

我正在尝试创建具有鼠标悬停功能的交互式折线图.将鼠标悬停在该行上时,可以看到该特定点的GDP值和年份.但是由于某种原因,我遇到了以下错误,但是我不确定为什么会发生这种情况,因为我正在将正确的格式数据集传递给该函数.

I am trying to create an interactive line chart with mouseover function. When you place your mouse over the line you can see the value of the GDP and the year at that certain point. But for some reason,I am getting the below error but I am not sure why it is happening as i am passing the right format data-set into the function.

Uncaught TypeError: Cannot read property 'year' of undefined

我的代码如下:

HTML

<!DOCTYPE html>
<htmL>
  <meta charset="utf-8">
  <head>
    <style>
      .line-chart2{
        margin-top:200px;
        margin-left:100px;
        border:1px solid lightgray;
      }
      circle {
        fill: steelblue;
      }
      body { 
        font: 12px Arial;}
      path { 
        stroke: steelblue;
        stroke-width: 2;
        fill: none;
      }
      .axis path,
      .axis line {
        fill: none;
        stroke: grey;
        stroke-width: 1;
        shape-rendering: crispEdges;
      }

      div.tooltip { 
          position: absolute;           
          text-align: center;           
          width: 80px;                  
          height: 64px;                 
          padding: 2px;             
          font: 14px sans-serif;
          color: black;     
          background: lightsteelblue;   
          border: 0px;      
          border-radius: 8px;           
          pointer-events: none;         
      }
      .overlay {
          fill: none;
          pointer-events: all;
        }
      .focus circle {
        fill: #F1F3F3;
        stroke: #6F257F;
        stroke-width: 5px;
      }
      .hover-line {
        stroke: #6F257F;
        stroke-width: 2px;
        stroke-dasharray: 3,3;
      }

  </style>

  </head>
  <body>
      <svg class='line-chart2'></svg>
      <script src="https://d3js.org/d3.v4.min.js"></script> 
      <script src="math.js" type="text/javascript"></script>
      <script src="./regression.js"></script>
  </body>
</htmL>

JavaScript

Javascript

var gdp=[ 387.65,   410.32,  415.73,  452.69,  462.14,
  478.96,  508.06,  599.59,  699.68,  808.90,
  920.31, 1201.11, 1186.95, 1323.94, 1656.61,
 1823.04, 1827.63, 1856.72, 2039.12,  2102.39,
 2274.22, 2600.81]; //y or GDP of India
var years=['1996','1997','1998','1999','2000','2001','2002','2003','2004','2005','2006','2007','2008','2009','2010','2011','2012','2013','2014','2015','2016','2017'];

var data_gdp=[]
  for(i=0;i<forexp.length;i++){
    data_gdp.push({year:years[i],value:gdp[i]})
    }

function drawChart_gdp(data,class_name) {
  var svgWidth = 1200, svgHeight = 400;
  var margin = { top: 60, right: 60, bottom: 60, left: 60 };
  var width = svgWidth - margin.left - margin.right;
  var height = svgHeight - margin.top - margin.bottom;
  var svg = d3.select(class_name)
    .attr("width", svgWidth)
    .attr("height", svgHeight);
  var bisectDate= d3.bisector(function(d) { return d.year; }).left;
  var g = svg.append("g")
    .attr("transform", 
       "translate(" + margin.left + "," + margin.top + ")"
    );
  var x = d3.scaleTime().range([0,width]);
  var y = d3.scaleLinear().rangeRound([height, 0]);

  var line = d3.line()
   .x(function(d) { return x(new Date(parseInt(d.year),0))})
   .y(function(d) { return y(d.value)})
   x.domain(d3.extent(data, function (d) { return new Date(parseInt(d.year),0); }));
   y.domain(d3.extent(data, function(d) { return d.value }));

   g.append("g")
   .attr("transform", "translate(0," + height + ")")
   .call(d3.axisBottom(x))
   .append("text")
    .attr("fill", "#000")
    .text("Year")
    .attr("dy", "1.90em")
    .attr("y", 5)
    .attr("x",500)
    .attr("font-size", "20px")
    .select(".domain")
    .remove();

   g.append("g")
   .call(d3.axisLeft(y))
   .append("text")
   .attr("fill", "#000")
   .attr("transform", "rotate(-90)")
   .attr("y", -80)
   .attr("x",-55)
   .attr("dy", "1.90em")
   .attr("text-anchor", "center")
   .attr("font-size", "20px")
   .text("GDP ($)")

  g.append("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 focus = g.append("g")
   .attr("class", "focus")
   .style("display", "none");

  focus.append("line")
    .attr("class", "x-hover-line hover-line")
    .attr("y1", 0)
    .attr("y2", height);

  focus.append("line")
    .attr("class", "y-hover-line hover-line")
    .attr("x1", width)
    .attr("x2", width);

  focus.append("circle")
    .attr("r", 7.5);

  focus.append("text")
    .attr("x", 15)
    .attr("dy", ".31em");

  svg.append("rect")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    .attr("class", "overlay")
    .attr("width", width)
    .attr("height", height)
    .on("mouseover", function() { focus.style("display", null); })
    .on("mouseout", function() { focus.style("display", "none"); })
    .on("mousemove",  function() { //problem in this function
      var x0 = x.invert(d3.mouse(this)[0]),
          i = bisectDate(data, x0, 1),
          d0 = data[i - 1],
          d1 = data[i],
          d = x0 - d0.year > d1.year - x0 ? d1 : d0;
      focus.attr("transform", "translate(" + x(d.year) + "," + y(d.value) + ")");
      focus.select("text").text(function() { return d.value; });
      focus.select(".x-hover-line").attr("y2", height - y(d.value));
      focus.select(".y-hover-line").attr("x2", width + width);
     });

  }
drawChart_gdp(data_gdp,'.line-chart2');

推荐答案

由于x是时间标度,因此返回的值...

Since x is a time scale, the returned value of...

var x0 = x.invert(d3.mouse(this)[0])

...是日期对象,如下所示:

... is a date object, like this:

Fri Nov 29 1996 19:56:00

但是,在您的数据中,您有字符串:

However, in your data, you have strings:

[{year: "1996", value: 387.65}, {year: "1997", value: 410.32} etc...];

解决方案非常简单,只需格式化日期即可:

The solution is quite straightforward, just format the dates:

var x0 = d3.timeFormat("%Y")(x.invert(d3.mouse(this)[0]))

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

Here is your code with that change:

var gdp = [387.65, 410.32, 415.73, 452.69, 462.14,
  478.96, 508.06, 599.59, 699.68, 808.90,
  920.31, 1201.11, 1186.95, 1323.94, 1656.61,
  1823.04, 1827.63, 1856.72, 2039.12, 2102.39,
  2274.22, 2600.81
]; //y or GDP of India
var years = ['1996', '1997', '1998', '1999', '2000', '2001', '2002', '2003', '2004', '2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017'];

var data_gdp = []
for (i = 0; i < years.length; i++) {
  data_gdp.push({
    year: years[i],
    value: gdp[i]
  })
}

function drawChart_gdp(data, class_name) {
  var svgWidth = 1200,
    svgHeight = 400;
  var margin = {
    top: 60,
    right: 60,
    bottom: 60,
    left: 60
  };
  var width = svgWidth - margin.left - margin.right;
  var height = svgHeight - margin.top - margin.bottom;
  var svg = d3.select(class_name)
    .attr("width", svgWidth)
    .attr("height", svgHeight);
  var bisectDate = d3.bisector(function(d) {
    return d.year;
  }).left;
  var g = svg.append("g")
    .attr("transform",
      "translate(" + margin.left + "," + margin.top + ")"
    );
  var x = d3.scaleTime().range([0, width]);
  var y = d3.scaleLinear().rangeRound([height, 0]);

  var line = d3.line()
    .x(function(d) {
      return x(new Date(parseInt(d.year), 0))
    })
    .y(function(d) {
      return y(d.value)
    })
  x.domain(d3.extent(data, function(d) {
    return new Date(parseInt(d.year), 0);
  }));
  y.domain(d3.extent(data, function(d) {
    return d.value
  }));

  g.append("g")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(x))
    .append("text")
    .attr("fill", "#000")
    .text("Year")
    .attr("dy", "1.90em")
    .attr("y", 5)
    .attr("x", 500)
    .attr("font-size", "20px")
    .select(".domain")
    .remove();

  g.append("g")
    .call(d3.axisLeft(y))
    .append("text")
    .attr("fill", "#000")
    .attr("transform", "rotate(-90)")
    .attr("y", -80)
    .attr("x", -55)
    .attr("dy", "1.90em")
    .attr("text-anchor", "center")
    .attr("font-size", "20px")
    .text("GDP ($)")

  g.append("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 focus = g.append("g")
    .attr("class", "focus")
    .style("display", "none");

  focus.append("line")
    .attr("class", "x-hover-line hover-line")
    .attr("y1", 0)
    .attr("y2", height);

  focus.append("line")
    .attr("class", "y-hover-line hover-line")
    .attr("x1", width)
    .attr("x2", width);

  focus.append("circle")
    .attr("r", 7.5);

  focus.append("text")
    .attr("x", 15)
    .attr("dy", ".31em");

  svg.append("rect")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    .attr("class", "overlay")
    .attr("width", width)
    .attr("height", height)
    .on("mouseover", function() {
      focus.style("display", null);
    })
    .on("mouseout", function() {
      focus.style("display", "none");
    })
    .on("mousemove", function() { //problem in this function
      var x0 = d3.timeFormat("%Y")(x.invert(d3.mouse(this)[0])),
        i = bisectDate(data, x0, 1);
      d0 = data[i - 1],
        d1 = data[i],
        d = x0 - d0.year > d1.year - x0 ? d1 : d0;
      focus.attr("transform", "translate(" + x(d.year) + "," + y(d.value) + ")");
      focus.select("text").text(function() {
        return d.value;
      });
      focus.select(".x-hover-line").attr("y2", height - y(d.value));
      focus.select(".y-hover-line").attr("x2", width + width);
    });

}
drawChart_gdp(data_gdp, '.line-chart2');

<head>
  <style>
    circle {
      fill: steelblue;
    }
    
    body {
      font: 12px Arial;
    }
    
    path {
      stroke: steelblue;
      stroke-width: 2;
      fill: none;
    }
    
    .axis path,
    .axis line {
      fill: none;
      stroke: grey;
      stroke-width: 1;
      shape-rendering: crispEdges;
    }
    
    div.tooltip {
      position: absolute;
      text-align: center;
      width: 80px;
      height: 64px;
      padding: 2px;
      font: 14px sans-serif;
      color: black;
      background: lightsteelblue;
      border: 0px;
      border-radius: 8px;
      pointer-events: none;
    }
    
    .overlay {
      fill: none;
      pointer-events: all;
    }
    
    .focus circle {
      fill: #F1F3F3;
      stroke: #6F257F;
      stroke-width: 5px;
    }
    
    .hover-line {
      stroke: #6F257F;
      stroke-width: 2px;
      stroke-dasharray: 3, 3;
    }
  </style>

</head>

<body>
  <svg class='line-chart2'></svg>
  <script src="https://d3js.org/d3.v4.min.js"></script>
</body>

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

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