[英]Compilation errors when drawing a piechart using D3.js, TypeScript and Angular
I am trying to display a pie chart and it's actually working, even though I get TypeScript compilation errors: Argument of type '(d: any) => {}' is not assignable to parameter of type 'datum: Arc<number>, index: number, outerIndex: number) => number | string | boolean'. Type '{}' is not assignable to type 'number | string | boolean'. Type '{}' is not assignable to type 'boolean'.
我正在尝试显示饼图并且它实际上正在工作,即使我收到 TypeScript 编译错误:
Argument of type '(d: any) => {}' is not assignable to parameter of type 'datum: Arc<number>, index: number, outerIndex: number) => number | string | boolean'. Type '{}' is not assignable to type 'number | string | boolean'. Type '{}' is not assignable to type 'boolean'.
Argument of type '(d: any) => {}' is not assignable to parameter of type 'datum: Arc<number>, index: number, outerIndex: number) => number | string | boolean'. Type '{}' is not assignable to type 'number | string | boolean'. Type '{}' is not assignable to type 'boolean'.
I've been using TypeScript for the last 2 years, but the line above makes me dizzy.过去 2 年我一直在使用 TypeScript,但上面的行让我头晕目眩。 I have no idea what is going on, I tried few things but nothing worked so far.
我不知道发生了什么,我尝试了几件事,但到目前为止没有任何效果。
This is the code that actually draws the pie chart:这是实际绘制饼图的代码:
function drawChart(){
var width = 960,
height = 500,
radius = Math.min(width, height) / 2;
var colourValues = d3.scale.ordinal().range(d3.values(that.ColoursService.colours));
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(radius - 70);
var pie = d3.layout.pie()
.sort(null)
.value(function(d: any) {return d.quantity});
var svg = d3.select('.pie-chart').append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + width / 2 + ',' + height/2 + ')');
var g = svg.selectAll('.arc')
.data(pie(data))
.enter().append('g')
.attr('class', 'arc');
g.append('path')
.attr('d', <any>arc)
.attr('fill', function(d: any) {
return colourValues(d.data.category);
});
}
This is where the typescript highlights the error, the squiggly line appears below "function" word.这是打字稿突出显示错误的地方,波浪线出现在“功能”词下方。 I need to make the TypeScript compilator pass, but I don't know how.
我需要让 TypeScript 编译器通过,但我不知道如何通过。
Although using <any>
will get rid of compiler complaints, you are basically sidestepping strong type checking, which is arguably one of the main points of using Typescript in the first place.尽管使用
<any>
会摆脱编译器的抱怨,但您基本上是在回避强类型检查,这可以说是首先使用 Typescript 的要点之一。 I struggled with this problem a long time, and finally, through trial and error and a lot of quality time with the d3.d.ts
definition for d3.svg.arc
, was able to come up with a way to make all of the types line up.我有这个问题很长一段时间挣扎,最后,经过反复试验和大量的质量与时间的
d3.d.ts
定义d3.svg.arc
,能想出一种方法,使所有的类型排列。 Here is a solution that demonstrates how to get a pie chart without using <any>
.这是一个演示如何在不使用
<any>
情况下获取饼图的解决方案。 The key is that you need to specify an interface
that describes the shape of your input, ie your data:关键是您需要指定一个
interface
来描述输入的形状,即您的数据:
interface Datum {
category: string;
quantity: number;
}
function drawChart(data: Array<Datum>) {
let width = 960,
height = 500,
radius = Math.min(width, height) / 2,
colourValues = d3.scale.category10();
// specify Datum as shape of data
let arc = d3.svg.arc<d3.layout.pie.Arc<Datum>>()
.innerRadius(radius - 70)
.outerRadius(radius - 10);
// notice accessor receives d of type Datum
let pie = d3.layout.pie<Datum>().sort(null).value((d: Datum):number => d.quantity);
// note input to all .attr() and .text() functions
// will be of type d3.layout.pie.Arc<Datum>
let fill = (d: d3.layout.pie.Arc<Datum>): string => colourValues(d.data.category);
let tfx = (d: d3.layout.pie.Arc<Datum>): string => `translate(${arc.centroid(d)})`;
let text = (d: d3.layout.pie.Arc<Datum>): string => d.data.category;
let svg = d3.select('.pie-chart').append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
// create a group for the pie chart
let g = svg.selectAll('.arc')
.data(pie(data))
.enter().append('g').attr('class', 'arc');
// add pie sections
g.append('path').attr('d', arc).attr('fill', fill);
// add labels
g.append('text').attr('transform', tfx).text(text);
}
Note that I swapped out your ColourService
for one of the standard d3
color category functions, but it should still work as long as colourValues()
returns a string that specifies the fill color.请注意,我将您的
ColourService
换成了标准d3
颜色类别函数之一,但只要colourValues()
返回一个指定填充颜色的字符串,它就应该仍然有效。
Hopefully this example shows how to get your custom data types to work with d3
and Typescript.希望这个例子展示了如何让你的自定义数据类型与
d3
和 Typescript 一起工作。
Alright I figured out what is happening, although I don't fully understand how D3 works with TypeScript.好吧,我知道发生了什么,虽然我不完全理解 D3 如何与 TypeScript 一起工作。 There are essentially two solutions:
基本上有两种解决方案:
First one, where I set specific interface on datum parameter and return values (either string, number or boolean) and then typecast the return value to string - it is too wordy.第一个,我在 datum 参数和返回值(字符串、数字或布尔值)上设置特定接口,然后将返回值类型转换为字符串 - 这太罗嗦了。
g.append('path')
.attr('d', <any>arc)
.attr('fill', function (datum: d3.layout.pie.Arc<any>): number | string | boolean {
return <string>colourValues(datum.data.category);
});
Second solution is easier on the eye.第二种解决方案对眼睛更容易。 I only added
:any
as a return type from the function.我只添加了
:any
作为函数的返回类型。
g.append('path')
.attr('d', <any>arc)
.attr('fill', function (d: any): any {
return colourValues(d.data.category);
});
I still don't fully understand how to interface my data models I interact with in D3 - every time I try to use the interface that is already implemented in successful promise resolution via angular.IPromise<interfaceNameOfTheReturnData>
in D3 functions wrapped inside angular directive's link function, I encounter TypeScript compilation errors and have to use any
type.我仍然不完全理解如何连接我在 D3 中与我交互的数据模型 - 每次我尝试使用已通过
angular.IPromise<interfaceNameOfTheReturnData>
在 angular 指令链接中包装的 D3 函数中成功实现承诺解析的angular.IPromise<interfaceNameOfTheReturnData>
函数,我遇到了 TypeScript 编译错误,必须使用any
类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.