Angular(4)d3.js未定义的长度

时间:2017-05-23 19:56:22

标签: angular typescript d3.js

我目前正在尝试将javascript中的Mike Bostocks多条形图的代码重写为angular(4)中的打字稿 这是原始块:

http://bl.ocks.org/mbostock/3943967

我从控制台收到以下错误: https://i.imgur.com/G4dWu6q.png

EXCEPTION: Error in :0:0 caused by: Cannot read property 'length' of undefined

ORIGINAL EXCEPTION: Cannot read property 'length' of undefined

Unhandled Promise rejection: Error in :0:0 caused by: Cannot read property 'length' of undefined ; Zone: <root> ; Task: Promise.then ; Value:

我刚刚完成了一个角度cli项目的全新安装,然后使用以下命令安装了d3:

ng new d3test
npm install --save d3
npm install --save-dev @types/d3

这是我的代码:

app.component.html:

<form>
  <label><input type="radio" name="mode" value="grouped"> Grouped</label>
  <label><input type="radio" name="mode" value="stacked" checked> Stacked</label>
</form>
<svg width="960" height="500"></svg>

app.component.ts:

import { Component, OnInit } from '@angular/core';
import * as d3 from 'd3/index';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  private n; // The number of series.
  private m; // The number of values per series.

  // The xz array has m elements, representing the x-values shared by all series.
  // The yz array has n elements, representing the y-values of each of the n series.
  // Each yz[i] is an array of m non-negative numbers representing a y-value for xz[i].
  // The y01z array has the same structure as yz, but with stacked [y0, y1] instead of y.
  private xz;
  private yz;
  private y01z;
  private yMax;
  private y1Max;

  private svg;
  private margin;
  private width;
  private height;
  private g;

  private x;

  private y;

  private color;

  private series;

  private rect;

  ngOnInit() {
    this.n = 4; // The number of series.
    this.m = 58; // The number of values per series.

    // The xz array has m elements, representing the x-values shared by all series.
    // The yz array has n elements, representing the y-values of each of the n series.
    // Each yz[i] is an array of m non-negative numbers representing a y-value for xz[i].
    // The y01z array has the same structure as yz, but with stacked [y0, y1] instead of y.
    this.xz = d3.range(this.m);
    this.yz = d3.range(this.n).map(() => {
      return this.bumps(this.m);
    });
    this.y01z = d3.stack().keys(<any>d3.range(this.n))(<any>d3.transpose(this.yz));
    this.yMax = d3.max(this.yz, (y) => {
      return d3.max(this.y);
    });
    this.y1Max = d3.max(this.y01z, (y) => {
      return d3.max(this.y, (d) => {
        return d[1];
      });
    });

    this.svg = d3.select("svg");
    this.margin = {
      top: 40,
      right: 10,
      bottom: 20,
      left: 10
    };
    this.width = +this.svg.attr("width") - this.margin.left - this.margin.right;
    this.height = +this.svg.attr("height") - this.margin.top - this.margin.bottom;
    this.g = this.svg.append("g").attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")");

    this.init();
  }

  init() {
    this.x = d3.scaleBand()
      .domain(this.xz)
      .rangeRound([0, this.width])
      .padding(0.08);

    this.y = d3.scaleLinear()
      .domain([0, this.y1Max])
      .range([this.height, 0]);

    this.color = d3.scaleOrdinal()
      .domain(<any>d3.range(this.n))
      .range(d3.schemeCategory20c);

    this.series = this.g.selectAll(".series")
      .data(this.y01z)
      .enter().append("g")
      .attr("fill", (d, i) => {
        return this.color(i);
      });

    this.rect = this.series.selectAll("rect")
      .data((d) => {
        return d;
      })
      .enter().append("rect")
      .attr("x", (d, i) => {
        return this.x(i);
      })
      .attr("y", this.height)
      .attr("width", this.x.bandwidth())
      .attr("height", 0);

    this.rect.transition()
      .delay((d, i) => {
        return i * 10;
      })
      .attr("y", (d) => {
        return this.y(d[1]);
      })
      .attr("height", (d) => {
        return this.y(d[0]) - this.y(d[1]);
      });

    this.g.append("g")
      .attr("class", "axis axis--x")
      .attr("transform", "translate(0," + this.height + ")")
      .call(d3.axisBottom(this.x)
        .tickSize(0)
        .tickPadding(6));

    d3.selectAll("input")
      .on("change", this.changed);
  }

  private timeout = d3.timeout(() => {
    d3.select("input[value=\"grouped\"]")
      .property("checked", true)
      .dispatch("change");
  }, 2000);

  changed() {
    this.timeout.stop();
    //used to be this.value
    if (d3.event.currentTarget.value === "grouped") {
      this.transitionGrouped();
    } else {
      this.transitionStacked();
    }
  }

  transitionGrouped() {
    this.y.domain([0, this.yMax]);

    this.rect.transition()
      .duration(500)
      .delay((d, i) => {
        return i * 10;
      })
      .attr("x", (d, i) => {
        return this.x(i) + this.x.bandwidth() / this.n * d3.event.currentTarget.parentNode.__data__.key;
      })
      .attr("width", this.x.bandwidth() / this.n)
      .transition()
      .attr("y", (d) => {
        return this.y(d[1] - d[0]);
      })
      .attr("height", (d) => {
        return this.y(0) - this.y(d[1] - d[0]);
      });
  }

  transitionStacked() {
    this.y.domain([0, this.y1Max]);

    this.rect.transition()
      .duration(500)
      .delay((d, i) => {
        return i * 10;
      })
      .attr("y", (d) => {
        return this.y(d[1]);
      })
      .attr("height", (d) => {
        return this.y(d[0]) - this.y(d[1]);
      })
      .transition()
      .attr("x", (d, i) => {
        return this.x(i);
      })
      .attr("width", this.x.bandwidth());
  }

  // Returns an array of m psuedorandom, smoothly-varying non-negative numbers.
  // Inspired by Lee Byron’s test data generator.
  // http://leebyron.com/streamgraph/
  bumps(m) {
    var values = [],
      i, j, w, x, y, z;

    // Initialize with uniform random values in [0.1, 0.2).
    for (i = 0; i < m; ++i) {
      values[i] = 0.1 + 0.1 * Math.random();
    }

    // Add five random bumps.
    for (j = 0; j < 5; ++j) {
      x = 1 / (0.1 + Math.random());
      y = 2 * Math.random() - 0.5;
      z = 10 / (0.1 + Math.random());
      for (i = 0; i < m; i++) {
        w = (i / m - y) * z;
        values[i] += x * Math.exp(-w * w);
      }
    }

    // Ensure all values are positive.
    for (i = 0; i < m; ++i) {
      values[i] = Math.max(0, values[i]);
    }

    return values;
  }

}

我知道这是很多代码,但我真的不明白问题出在哪里。如果我必须要求它可能是使用函数d3.max的地方,但我不确定。

0 个答案:

没有答案