2017-01-20 22 views
3

我想用我的Angular2应用程序中的d3-cloud生成一个词云。但是,我无法找到正确的类型进行安装。我试过this,但是当我尝试将它导入到我的组件中时,它不起作用。我不断收到错误,“物业布局无法找到类型”。有人可以帮我解决这个问题吗?d3云的类型

+0

你有没有解决这个问题?在分钟有完全相同的问题 –

+0

@SimonMcLoughlin我确实得到它的工作。在下面发布答案。评论你是否需要更多的说明。 –

回答

5

我想出了如何做到这一点。不是正确的Typescript方式,而是使用回退JS方式。这里是你如何去做:

  1. import像往常一样D3库,但给它一个别名:import * as D3 from 'd3';(注:资本d为D3)
  2. declare D3再次所以你可以用它来WordCloud :declare let d3: any;
  3. 使用D3来处理与父d3库有关的所有内容,并且仅针对单词云生成使用d3

d3-cloud的类型似乎不起作用。所以declare似乎是现在唯一的方法。

全码:

import { Component, Input, ElementRef, DoCheck, KeyValueDiffers } from '@angular/core'; 
import { WordCloudConfig } from '../../../models/charts/word-cloud-config'; 
import * as D3 from 'd3'; 

declare let d3: any; 

@Component({ 
    selector : 'word-cloud', 
    templateUrl: './word-cloud.component.html', 
    styleUrls : ['./word-cloud.component.scss'] 
}) 
export class WordCloudComponent implements DoCheck { 

    @Input() config: WordCloudConfig; 

    private _host;    // D3 object referencing host DOM object 
    private _svg;    // SVG in which we will print our chart 
    private _margin: {   // Space between the svg borders and the actual chart graphic 
    top: number, 
    right: number, 
    bottom: number, 
    left: number 
    }; 
    private _width: number;  // Component width 
    private _height: number;  // Component height 
    private _htmlElement: HTMLElement; // Host HTMLElement 
    private _minCount: number; // Minimum word count 
    private _maxCount: number; // Maximum word count 
    private _fontScale;   // D3 scale for font size 
    private _fillScale;   // D3 scale for text color 
    private _objDiffer; 

    constructor(private _element: ElementRef, private _keyValueDiffers: KeyValueDiffers) { 
    this._htmlElement = this._element.nativeElement; 
    this._host = D3.select(this._element.nativeElement); 
    this._objDiffer = this._keyValueDiffers.find([]).create(null); 
    } 

    ngDoCheck() { 
    let changes = this._objDiffer.diff(this.config); 
    if (changes) { 
     if (!this.config) { 
     return; 
     } 
     this._setup(); 
     this._buildSVG(); 
     this._populate(); 
    } 
    } 

    private _setup() { 
    this._margin = { 
     top : 10, 
     right : 10, 
     bottom: 10, 
     left : 10 
    }; 
    this._width = ((this._htmlElement.parentElement.clientWidth == 0) 
     ? 300 
     : this._htmlElement.parentElement.clientWidth) - this._margin.left - this._margin.right; 
    if (this._width < 100) { 
     this._width = 100; 
    } 
    this._height = this._width * 0.75 - this._margin.top - this._margin.bottom; 

    this._minCount = D3.min(this.config.dataset, d => d.count); 
    this._maxCount = D3.max(this.config.dataset, d => d.count); 

    let minFontSize: number = (this.config.settings.minFontSize == null) ? 18 : this.config.settings.minFontSize; 
    let maxFontSize: number = (this.config.settings.maxFontSize == null) ? 96 : this.config.settings.maxFontSize; 
    this._fontScale = D3.scaleLinear() 
         .domain([this._minCount, this._maxCount]) 
         .range([minFontSize, maxFontSize]); 
    this._fillScale = D3.scaleOrdinal(D3.schemeCategory20); 
    } 

    private _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._width/2) + ',' + ~~(this._height/2) + ')'); 
    } 

    private _populate() { 
    let fontFace: string = (this.config.settings.fontFace == null) ? 'Roboto' : this.config.settings.fontFace; 
    let fontWeight: string = (this.config.settings.fontWeight == null) ? 'normal' : this.config.settings.fontWeight; 
    let spiralType: string = (this.config.settings.spiral == null) ? 'rectangular' : this.config.settings.spiral; 

    d3.layout.cloud() 
     .size([this._width, this._height]) 
     .words(this.config.dataset) 
     .rotate(() => 0) 
     .font(fontFace) 
     .fontWeight(fontWeight) 
     .fontSize(d => this._fontScale(d.count)) 
     .spiral(spiralType) 
     .on('end',() => { 
     this._drawWordCloud(this.config.dataset); 
     }) 
     .start(); 
    } 

    private _drawWordCloud(words) { 
    this._svg 
     .selectAll('text') 
     .data(words) 
     .enter() 
     .append('text') 
     .style('font-size', d => d.size + 'px') 
     .style('fill', (d, i) => { 
      return this._fillScale(i); 
     }) 
     .attr('text-anchor', 'middle') 
     .attr('transform', d => 'translate(' + [d.x, d.y] + ')rotate(' + d.rotate + ')') 
     .attr('class', 'word-cloud') 
     .text(d => { 
      return d.word; 
     }); 
    } 

} 
+0

谢谢你,现在为我工作。只需要玩图书馆来获得我想要的外观。 –

+0

您是如何在应用程序中包含d3-cloud的?我正在使用带有webpack的angular-cli,因为d3-cloud NPM模块使用'require',因此会窒息。 – ansorensen

+0

@ansorensen您无需“包含”d3-cloud。我只是将''添加到'index.html'中并且访问它使用答案中提到的方法。 –