d3js:未捕获的TypeError:无法读取属性' length'未定义的

时间:2015-09-03 02:11:43

标签: javascript json d3.js

我是d3的新手。我很确定我的数据没有问题。正确方向的任何一点都将受到赞赏。

(function() {

  d3.json("data.json", function(error, json){
    if(error) return console.warn(error);
    data = json;

    var format = d3.time.format("%a %b %d %Y")
    var amountFn = function(d){return d.amount}
    var dateFn = function(d){
      console.log(d.bonus);
      return format.parse(d.date)

    }


    var x = d3.time.scale()
      .range([10, 280])
      .domain(d3.extent(data, dateFn));

    var y = d3.scale.linear()
      .range([180, 10])
      .domain(d3.extent(data, amountFn));

    var svg = d3.select('#demo').append("svg:svg")
      .attr("width", 300)
      .attr("height", 200)

    svg.selectAll("circle").data(data).enter()
      .append("svg:circle")
      .attr("r", 4)
      .attr("cx", function(d){return x(dateFn(d.draw_date))})
      .attr("cy", function(d){return y(amountFn(d))})
  });


 })();

我检索的数据采用以下格式。

[
    {
        "date": "2015-08-26T00:00:00",
        "amount": "30"
    },
    ...more data
]

2 个答案:

答案 0 :(得分:2)

其实你在这里做了很多愚蠢的小错误。使用D3.js,您必须了解数据结构。

在你的代码中我发现了很多错误。

1。您将json存储在一个变量中,该变量将您未初始化的数据命名为数据,但javascript会忽略它。

2。您传入 console.log(d.bonus); 此密钥在您的json中不存在,因此其值显示为“undefned” 即可。当你看着你控制台时。

3。您需要将d.date转换为日期对象的json数据。

4。你已经把你的钥匙包裹在x和y中,所以你只需要传递

.attr("cx", function(d){ return x(d.date); })
.attr("cy", function(d){return y(d.amount); })

而不是

.attr("cx", function(d){return x(dateFn(d.draw_date))})
.attr("cy", function(d){return y(amountFn(d))})

因此我修复了代码中的一些错误,您可以通过在系统上运行来测试此代码:

我的HTML:

<!DOCTYPE html>
<html>
<head>  
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <link rel="stylesheet" href="css/bootstrap-theme.css">
</head>    

<body>
<div class = "container">
    <div class="row">
        <div class="col-md-12">
            <div class = "panel panel-primary">
                <div class="panel-heading">
                    <h3 class="panel-title">D3 Test Example</h3>
                </div>
                <div class="panel-body">
                    <div id="demo"></div>
                <div>
            </div>
        </div>
    </div>
</div>
<script src="js/jquery-2.1.1.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/d3.v3.min.js"></script>
<script src="js/script.js"></script>
</body>
</html>

我的脚本代码在这里..

    (function() {

      d3.json("data.json", function(error, json){
        if(error) return console.warn(error);
        var data = json;  // you store your json in data variable here..

        var format = d3.time.format("%a %b %d %Y").parse; // you don't need to this...
        var amountFn = function(d){return d.amount; };

        data.forEach(function(d){
            d.date = new Date(d.date); // you convert your d.date value in date string Object 
            d.amount = d.amount;
        });

        var dateFn = function(d){
          return d.date;
        }


        var x = d3.time.scale()
          .range([10, 280])
          .domain(d3.extent(data, dateFn));

        var y = d3.scale.linear()
          .range([180, 10])
          .domain([0, d3.max(data, amountFn)]);

        var svg = d3.select('#demo').append("svg:svg")
          .attr("width", 300)
          .attr("height", 200)

        svg.selectAll("circle").data(data).enter()

          .append("svg:circle")
          .attr("r", 4)
          .attr("cx", function(d){ return x(d.date); })
          .attr("cy", function(d){return y(d.amount); })
      });

 })();

我用过这个数据..

[     {         “日期”:“2015-08-24T00:00:00”,         “金额”:“30”     },{         “日期”:“2015-08-25T00:00:00”,         “金额”:“40”     },{         “日期”:“2015-08-26T00:00:00”,         “金额”:“50”     },{         “date”:“2015-08-27T00:00:00”,         “金额”:“60”     },{         “日期”:“2015-08-28T00:00:00”,         “金额”:“70”     },{         “日期”:“2015-08-29T00:00:00”,         “金额”:“80”     },{         “日期”:“2015-08-30T00:00:00”,         “金额”:“90”     },{         “日期”:“2015-08-31T00:00:00”,         “金额”:“100”     }
]

我希望这是你的问题的答案。 所以我的输出就在这里......

enter image description here

答案 1 :(得分:0)

您的代码中有两个错误。

  1. 在格式字符串中,您必须添加要提供给格式字符串的所有字段。因此,您应该使用d3.time.format("%Y-%m-%dT%H:%M:%S");代替d3.time.format("%a %b %d %Y")

  2. dateFn函数需要一个对象作为参数而不是日期字符串。因此,请将x(dateFn(d.draw_date))替换为x(dateFn(d))

  3. 以下是工作代码段。

    &#13;
    &#13;
    var data = [{
        "date": "2015-08-26T00:00:00",
        "amount": "30"
    }, {
        "date": "2015-07-26T00:00:00",
        "amount": "40"
    }];
    
    var format = d3.time.format("%Y-%m-%dT%H:%M:%S");
    var amountFn = function(d) {
        return d.amount
    };
    var dateFn = function(d) {
        console.log(d.bonus);
        return format.parse(d.date)
    }
    
    
    var x = d3.time.scale()
        .range([10, 280])
        .domain(d3.extent(data, dateFn));
    
    var y = d3.scale.linear()
        .range([180, 10])
        .domain(d3.extent(data, amountFn));
    
    var svg = d3.select('#demo').append("svg:svg")
        .attr("width", 300)
        .attr("height", 200)
    
    svg.selectAll("circle").data(data).enter()
        .append("svg:circle")
        .attr("r", 4)
        .attr("cx", function(d) {
            return x(dateFn(d))
        })
        .attr("cy", function(d) {
            return y(amountFn(d))
        })
    &#13;
    div{
       height: 800px;
      width: 1200px;
    }
    &#13;
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
    <div id="demo"></div>
    &#13;
    &#13;
    &#13;