d3.js未捕获的TypeError:无法读取未定义的属性“长度”

时间:2014-02-08 18:34:30

标签: d3.js

我正在尝试编写一个可重复使用的折线图,但是我在加载时遇到以下错误:

Uncaught TypeError: Cannot read property 'length' of undefined

JS在这里:http://jsfiddle.net/2qs95/

我首先将它“直接”写入并且不可重复使用,这样可行,但是当我尝试将其转换为函数时,它因某种原因而破坏了。我确信这是一个范围问题。似乎无法弄明白。

在这里工作JSfiddle:http://jsfiddle.net/ht9rG/

function LineChart (data, chart) {
    this.data = data;

    this.margin = chart.margin || { top: 0, bottom: 0, left: 0, right: 0 };
    this.height = chart.height || 100;
    this.width = chart.width || 400;
    this.target = chart.target || 'body';
    this.yLabelClass = chart.classes.yLabelClass || 'y-label';
    this.yTicksClass = chart.classes.yTicksClass || 'y-ticks';
    this.specialTextClass = chart.classes.specialTextClass || 'special-text';
}
LineChart.prototype = {
    draw: function () {
        this.g.selectAll("." + this.yLabelClass)
            .data(this.y.ticks(2))
            .enter().append("svg:text")
            .attr("class", this.yLabelClass)
            .text(String)
            .attr("x", d3.select(this.target).attr('width') - 50)
            .attr("y", function(d) { return -1 * this.y(d) })
            .attr("text-anchor", "left")
            .attr("dy", 5);

        this.g.selectAll("." + this.yTicksClass)
            .data(y.ticks(2))
            .enter().append("svg:line")
            .attr("class", this.yTicksClass)
            .attr("y1", function(d) { return -1 * this.y(d); })
            .attr("x1", this.x(-0.3))
            .attr("y2", function(d) { return -1 * this.y(d); })
            .attr("x2", d3.select('svg').attr('width') - 70);

        this.g.append('text')
            .attr({
                class: this.specialTextClass,
                y: -50,
                x: 0
            })
            .text(this.data[this.data.length - 1] + 'ms');

        this.g.append("svg:path").attr("d", line(this.data));
    },

    y: d3.scale.linear()
        .domain([0, d3.max(this.data)])
        .range([this.margin.bottom, this.height - this.margin.bottom]),

    x: d3.scale.linear()
        .domain([0, this.data.length])
        .range([this.margin.left, this.width - this.margin.left]),

    svg: d3.select(this.target)
        .append("svg:svg")
        .attr("width", this.width)
        .attr("height", this.height),

    g: svg.append("svg:g")
        .attr("transform", "translate(0, " + h + ")"),

    line: d3.svg.line()
        .interpolate('linear')
        .x(function (d, i) { return x(i); })
        .y(function (d) { return -1 * y(d); })
}

var data = [432, 123, 432,123,765,234,234,656,800,123,431,543,652, 100, 200];
var options = {
        width: 800,
        height: 100,
        margin: {
            top: 10,
            bottom: 10,
            left: 10,
            right: 10
        },
        target: 'body'
    };

var x = new LineChart(data, options);
x.draw();

1 个答案:

答案 0 :(得分:3)

你在这里和那里都缺少一些东西,主要是

  • 您没有以this.为前缀的变量,
  • 您给出了不同名称的变量,
  • 在D3回调中使用this,此时它引用了SVG元素而不是图表对象,
  • 以及其他一些事情。

我不会在此列出所有内容,但一个有效的示例是here,您可以与您的版本进行比较。