2017-08-04 68 views
0

我正在为d3直方图构建一个非常简单的角度控件。d3 v4和角度v4直方图语法

我已经在许多教程在网上看了,他们都似乎在暗示对直方图的区间的施工中特定的语法:

let datagenerator = d3.histogram<number>() 
    .domain(d => x.domain()) 
    .thresholds(x.ticks(20)); 

    let bins = datagenerator(this.data); 

当我试试这个,我得到以下错误:

ERROR in src/app/d3/histogram/histogram.component.ts (45,25): 
Supplied parameters do not match any signature of call target. 

UPDATE:

ERROR in src/app/d3/histogram/histogram.component.ts (48,15): Argument of type '(d: number[]) => number[]' is not assignable to parameter of type '(values: number[]) => [number, number]'. 
    Type 'number[]' is not assignable to type '[number, number]'. 
Property '0' is missing in type 'number[]'. 

ERROR in src/app/d3/histogram/histogram.component.ts (54,15): Argument of type '(string | number)[]' is not assignable to parameter of type '(number | { valueOf(): number; })[]'. 
    Type 'string | number' is not assignable to type 'number | { valueOf(): number; }'. 
Type 'string' is not assignable to type 'number | { valueOf(): number; }'. 

ERROR in src/app/d3/histogram/histogram.component.ts (54,48): Property 'length' does not exist on type '{}'. 
012:尝试下面的建议,我正在取得进展,但现在收到此错误后

下面是完整的源代码:

import { Component, OnInit, OnChanges, ViewChild, ElementRef, Input, 
ViewEncapsulation } from '@angular/core'; 
import * as d3 from 'd3'; 

@Component({ 
    selector: 'histogram', 
    templateUrl: './histogram.component.html', 
    styleUrls: ['./histogram.component.css'], 
    encapsulation: ViewEncapsulation.None 
}) 
export class HistogramComponent implements OnInit { 

    @ViewChild('chart') private chartContainer:ElementRef; 
    @Input() private histogramdata:Array<number>; 

    private margin:any = {top: 20, bottom: 20, left: 20, right: 20}; 
    private chart:any; 
    private svg:any; 
    private width; 
    private height; 
    private data; 

    constructor() { } 

    createChart() { 
    let element = this.chartContainer.nativeElement; 
    this.width = element.offsetWidth - this.margin.left - this.margin.right; 
    this.height = element.offsetHeight - this.margin.top - this.margin.bottom; 
    this.svg = d3.select(element).append('svg') 
     .attr('width', element.offsetWidth) 
     .attr('height', element.offsetHeight); 

    // chart plot area 
    this.chart = this.svg.append('g') 
     .attr('transform', `translate(${this.margin.left}, ${this.margin.top})`); 
    } 

    updateChart() { 

    let formatCount = d3.format(",.0f"); 
    //this.data = this.histogramdata; 
    this.data = [0.1,0.2,0.3,0.4]; 


    let x = d3.scaleLinear<number>() 
     .rangeRound([0, this.width]); 

    let datagenerator = d3.histogram<number, number>() 
     .domain(d => x.domain()) 
     .thresholds(x.ticks(20)); 

    let bins = datagenerator(this.data); 

    let y = d3.scaleLinear<number>() 
     .domain([0, d3.max(bins, d => { return d.length; })]) 
     .range([this.height, 0]); 

    let bar = this.chart.selectAll(".bar") 
     .data(bins) 
     .enter().append("g") 
     .attr("class", "bar") 
     .attr("transform", d => { 
     return "translate(" + x(d.x0) + "," + y(d.length) + ")"; 
     }); 

    let barWidth = x(bins[0].x1) - x(bins[0].x0) - 1; 

    bar.append("rect") 
     .attr("x", 1) 
     .attr("width", barWidth) 
     .attr("height", d => { return this.height - y(d.length); }); 

    let textLoc = (x(bins[0].x1) - x(bins[0].x0))/2; 

    bar.append("text") 
     .attr("dy", ".75em") 
     .attr("y", 6) 
     .attr("x", textLoc) 
     .attr("text-anchor", "middle") 
     .text(d => { return formatCount(d.length); }); 

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

    } 

    ngOnInit() { 
    } 

} 

我明白,我们有一些类型的装饰添加到呼叫的打字稿兼容性,但我不明白的是为什么错误提示,直方图功能应该采取一个参数。我见过的所有例子都没有参数。

感谢您的关注。任何建议感激。

回答

1

按照sourcetests,签名是:

d3.histogram<number, number>() 

为数字阵列。

或:

d3.histogram<MixedObject, number | Date>() 

其中“混合对象”是一个自定义类型匹配你的数据,你是用数字或日期装箱。

为了进一步帮助,与您的数据样本更新您的问题...

编辑

再次,看看源。这很容易理解。第一个参数是数组中要用来调用直方图函数的类型。它用于,例如在所述value功能,如:

.value((d: number, i: number) => { 
    return d; 
}) 

第二种类型是在设置两个部分的domain和指定为阈值阵列中的类型中使用的类型。它也用于返回对象中,作为x0x1属性的类型。

所有这一切说,我只是做了一个简单的测试中Angular2 /打字稿有:

let dataGenerator = d3.histogram<number, number>() 
     .thresholds([0.2,0.4,0.6,0.8,1]); 

    let data = d3.range(100).map(() => { 
     return Math.random(); 
    }); 

    console.log(dataGenerator(data)); 

而且这两者建立和运行。

为了进一步提供帮助,请提供一组完整的代码来重新生成您的问题。

EDITS 2

错误实际上是在这里:

let datagenerator = d3.histogram<number, number>() 
    .domain(d => x.domain()) //<-- ERROR 
    .thresholds(x.ticks(20)); 

x.domain()回报number[],而histogram<number, number().domain(期待[number, number]

我整理出来这样的:

let dom : number[] = x.domain(); 
let datagenerator = d3.histogram<number, number>() 
    .domain([ dom[0], dom[1] ]) 
    .thresholds(x.ticks(20)); 
+0

嗯 - 还是有点困惑。我将一组数字传递给直方图 - 其他参数来自哪里。当我在代码中进行此更改时,出现以下错误: 'src/app/d3/histogram/histogram.component.ts中的错误(46,15): '(d:number [])类型的参数=> number []'不可分配给 类型为'(values:number [])=> [number,number]'的参数。 类型'number []'不可分配给'[number,number]'类型。 类型'number []'中缺少属性'0'。' – jb44

+0

@ jb44,请参阅上面的编辑以回应您的评论。从你的错误,它看起来像你没有传递一个数组数组,而是一个数组数组。 – Mark

+0

感谢您的评论 - 我仍然无法理解如何传递数组数组。我包括上面的源代码,对值进行了硬编码,并且仍然出现相同的错误。很有可能我正在做一个傻瓜式的监督,所以我很感激你对我的支持。 – jb44