首页 > 解决方案 > d3 TypeError: a is undefined

问题描述

I've spent hours trying to figure this out. I'm trying to load some mailchimp data into d3 and do stuff with it. Just simple reporting information.

On firefox, I get this error: TypeError: a is undefined On Chrome, I get this error: Uncaught TypeError: Cannot read property 'length' of undefined

I'm at a loss. Any help?

I got this code:

var data; 
    d3.csv("data/campaigns.csv", function(d) {
        return {
            title: d.Title,
            Subject: d.Subject,
            List: d.List,
            SendDate: new Date(d.SendDate),
            TotalRecipients: +d.TotalRecipients,
            SuccessfulDeliveries: +d.SuccessfulDeliveries,
            SoftBounces: +d.SoftBounces,
            HardBounces: +d.HardBounces,
            TotalBounces: +d.TotalBounces,
            TimesForwarded: +d.TimesForwarded,
            ForwardedOpens: +d.ForwardedOpens,
            UniqueOpens: +d.UniqueOpens,
            OpenRate: parseFloat(d.OpenRate),
            TotalOpens: +d.TotalOpens,
            UniqueClicks: +d.UniqueClicks,
            ClickRate: parseFloat(d.ClickRate),
            TotalClicks: +d.TotalClicks,
            Unsubscribes: +d.Unsubscribes,
            AbuseComplaints: +d.AbuseComplaints
        }
    }).then(function(d) {
        data = d;
        console.log(d);
    });
  var datemin = new Date("September 12, 2013");
    var datemax = new Date();

    // X Scale
    var xScale = d3.scaleTime()
        .domain([datemax, datemin])
        .range([width, 0]);
    // Y Scale
    var yScale = d3.scaleLinear()
        .domain([0, 7000])
        .range([height, 0]);

    // Tooltip div
    d3.select('#content').append('div')
        .attr('class', 'tooltip')
        .style('opacity', 0);
    // SVG
    var svg = d3.select('#content') 
        .append('svg')
            .attr('class', 'mainsvg')
            .attr('width', width + margin.left + margin.right)
            .attr('height', height + margin.top + margin.bottom)
        .append('g')
            .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

    // Append x and y axis
    svg.append('g')
        .attr('class', 'x axis')
        .attr('transform', 'translate(0,' + height + ')')
        .call(d3.axisBottom(xScale))
    svg.append('g')
        .attr('class', 'y axis')
        .call(d3.axisLeft(yScale))

    // Line
    var line = d3.line()
        .x(function(d) { return xScale( new Date(d.SendDate) ); })
        .y(function(d) { return yScale( +d.UniqueOpens ); });

    svg.append('path')
        .datum(data)
        .attr('class', 'line')
        .attr('d', line);

}

标签: javascriptd3.js

解决方案


因为d3.csv是异步的,看起来 d3 可能会在调用完成并提供所述数据之前尝试使用它提供的数据。

我怀疑如果您将代码放在另一个then块中,您的代码会起作用,因此它仅在数据绑定到data.

例如,而不是:

    }).then(function(d) {
        data = d;
        console.log(d);
    });
    // The rest of your code here

你会这样做:

    }).then(function(d) {
        data = d;
        console.log(d);
    })
    .then(function() {
      // The rest of your code here.
    })

推荐阅读