当前位置:  开发笔记 > 编程语言 > 正文

d3.js或rxjs错误?this.svg.selectAll(...).data(...).enter不是函数

如何解决《d3.js或rxjs错误?this.svg.selectAll().data().enter不是函数》经验,为你挑选了0个好方法。

这很奇怪.它也有点长,所以提前道歉. 更新 - 它最终成为2个问题,请参阅下面的答案.

这是我的错误: EXCEPTION: this.svg.selectAll(...).data(...).enter is not a function

我有一个angular-cli客户端和一个节点api服务器.我可以使用observable从服务中检索states.json文件(下面的代码).d3喜欢该文件并显示预期的美国地图.

当我将api服务器中的服务目标从文件更改为bluemix-cloudant服务器时,我在客户端收到上述错误.

当我使用ngOnInit在一个变体中使用console.log输出时,最初mapData打印为一个空数组,并抛出错误.这是错误的明显来源,因为没有数据,但Chrome调试器显示待处理的请求.请求完成后,数据将按预期在控制台中打印.

angular-cli版本1.0.0-beta.26

角度版本^ 2.3.1

d3版本^ 4.4.4

rxjs版本^ 5.0.1

map.component.ts:

import { Component, ElementRef, Input } from '@angular/core';
import * as D3 from 'd3';
import '../rxjs-operators';

import { MapService } from '../map.service';

@Component({
  selector: 'map-component',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.css']
})
export class MapComponent {

  errorMessage: string;
  height;
  host;
  htmlElement: HTMLElement;
  mapData;
  margin;
  projection;
  path;
  svg;
  width;

  constructor (private _element: ElementRef, private _mapService: MapService) {
    this.host = D3.select(this._element.nativeElement);
    this.getMapData();
    this.setup();
    this.buildSVG();
  }

  getMapData() {
    this._mapService.getMapData()
      .subscribe(
        mapData => this.setMap(mapData),
        error =>  this.errorMessage = error
      )
  }

  setup() {
    this.margin = {
      top: 15,
      right: 50,
      bottom: 40,
      left: 50
    };
    this.width = document.querySelector('#map').clientWidth - this.margin.left - this.margin.right;
    this.height = this.width * 0.6 - this.margin.bottom - this.margin.top;
  }

  buildSVG() {
    this.host.html('');
    this.svg = this.host.append('svg')
      .attr('width', this.width + this.margin.left + this.margin.right)
      .attr('height', this.height + this.margin.top + this.margin.bottom)
      .append('g')
      .attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')');
  }

  setMap(mapData) {
    this.mapData = mapData;
    this.projection = D3.geoAlbersUsa()
      .translate([this.width /2 , this.height /2 ])
      .scale(650);
    this.path = D3.geoPath()
      .projection(this.projection);

    this.svg.selectAll('path')
      .data(this.mapData.features)
      .enter().append('path')
        .attr('d', this.path)
        .style('stroke', '#fff')
        .style('stroke-width', '1')
        .style('fill', 'lightgrey');
  }
}

map.service.ts:

import { Http, Response } from '@angular/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class MapService {
  private url = 'http://localhost:3000/api/mapData';
  private socket;

  constructor (private _http: Http) { }

  getMapData(): Observable {
    return this._http.get(this.url)
      .map(this.extractData)
      .catch(this.handleError);
  }

  private extractData(res: Response) {
    let body = res.json();
    return body.data || {};
  }

  private handleError(error: any) {
    let errMsg = (error.message) ? error.message :
      error.status ? `${error.status} - ${error.statusText}` : 'Server error';
    console.error(errMsg);
    return Promise.reject(errMsg);
  }
}

这是异步的功能,对数据的调用对于d3来说需要太长时间吗?

我曾希望这个问题 Uncaught TypeError:canvas.selectAll(...).data(...).enter不是d3中的一个函数会提供一些见解,但我没有看到任何.

非常感谢任何帮助或见解!

编辑: 以下是Chrome per Marks请求下方标题部分的屏幕截图.响应选项卡显示正确作为GeoJSON对象发送的数据.我还将该响应复制到本地文件中,并将其用作具有正面结果的地图源.

到目前为止的数据测试:GeoJSON文件(2.1mb)

本地文件,本地服务器:成功(响应时间54ms)

相同文件,远程服务器:数据返回浏览器前D3错误(750ms)

来自远程服务器的API调用:数据返回浏览器之前的D3错误(2.1 s)

Chrome标头按钮

推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有