D3、TS 和 Angular 2
Posted
技术标签:
【中文标题】D3、TS 和 Angular 2【英文标题】:D3, TS and Angular 2 【发布时间】:2017-04-16 14:34:31 【问题描述】:我正在尝试将 D3 v4 与 Angular 2 (Typescript) 一起使用。我目前正在研究 D3 v4。我能够在***中遵循一些答案,但没有成功。我已经导入了大部分 D3 库及其类型(我使用的是 TS 2.0),并且在我的组件文件中我需要 import * as d3 from 'd3';
。对我来说,这个问题可能是 Angular 2、Typescript 和 3rd 方库......到目前为止一团糟。
在我的组件文件中,我有一些这样的代码:
let arc = d3.arc()
.outerRadius(chartHeight / 2)
.innerRadius(chartHeight / 4)
.padAngle(0.03)
.cornerRadius(8);
let pieG = chartLayer.selectAll("g")
.data([data])
.enter()
.append("g")
.attr("transform", "translate(" + [chartWidth / 2, chartHeight / 2] + ")");
let block = pieG.selectAll(".arc")
.data(arcs);
let newBlock = block.enter().append("g").classed("arc", true);
newBlock.append("path")
.attr("d", arc)
.attr("id", function (d, i)
return "arc-" + i
)
.attr("stroke", "gray")
.attr("fill", function (d, i)
return d3.interpolateCool(Math.random())
);
如您所见,我在第一行定义了 arc 并在第 19 行使用它,但出现错误:
[at-loader] src\piechart\piechart.component.ts:19:28
Argument of type 'Arc<any, DefaultArcObject>' is not assignable to parameter of type '(this: BaseType, datum: PieArcDatum<number | valueOf(): number; >, index: num
ber, groups: Base...'.
Types of parameters 'd' and 'datum' are incompatible.
Type 'PieArcDatum<number | valueOf(): number; >' is not assignable to type 'DefaultArcObject'.
Property 'innerRadius' is missing in type 'PieArcDatum<number | valueOf(): number; >'.
Arch 和 arc 似乎是在 d3-shape 类型和 d3-path 类型中定义的。
任何可以帮助我的人...我花了几天时间尝试使用 angular 2、TS 和 D3 v4 进行 POC,但到目前为止没有运气...我已经在网上看到了所有关于它的文章,其中大多数都有旧版本或不工作。我也觉得这是一个打字问题。 Angular 2 和第三方库是一场噩梦。
【问题讨论】:
将.attr("d", arc)
更改为.attr("d", function(d) console.log(d); arc(d);
使用console.log
的输出更新您的问题...
newBlock.append("path") .attr("d", (d) => console.log(d); arc(d); ) .attr("id", (d, i) => return "arc-" + i )
我收到两个 ts 错误...和 4 个日志如下:Log: "data":"name":"hoge","value":100,"index":0,"value":100,"startAngle":0,"endAngle":0.7075659129706742,"padAngle":0
试图复制您的问题here,但没有成功。不过,我不确定 plunker 如何编译打字稿:(
谢谢马克。这令人沮丧。我切换到 d3 v3.5.5,这个版本的最新类型是 3.5.36。使用此代码时:` let pie = d3.layout.pie() .sort(null) .value((d) => return d.population; ); ` 我收到一个错误:[at-loader] src/piechart/piechart.component.ts:39:26 类型“数字”上不存在属性“人口”。但是,如果我只是将类型添加到任何它的“d”(内部值)中。我认为问题出在打字上,或者我做错了什么但无法弄清楚。
在显示圆弧/饼图等之前,您是否尝试过在 SVG 中显示最基本的 D3 图像或形状。我正在经历与您相同的繁琐工作,试图获得正确的 d3 版本、类型、Angular2、typeScript 设置。这并不容易!当基础知识不起作用时,我能够将其范围缩小到类型。
【参考方案1】:
只需要将arc
转换为any
。所以应该是.attr("d", <any>arc)
【讨论】:
这可能是一个临时解决方法,但我想这应该以适当的方式解决,也许是打字稿定义的错误?【参考方案2】:我在我的 Angular 2 项目中添加了 import 语句,并且在开发过程中不断出现错误。我正在使用 angular-cli 和 d3 v4。
除了 import * as d3 from "d3";
之外,将以下代码添加到您的 typings.d.ts 文件中:
declare module 'd3'
export * from 'd3-array';
export * from 'd3-axis';
export * from 'd3-brush';
export * from 'd3-chord';
export * from 'd3-collection';
export * from 'd3-color';
export * from 'd3-dispatch';
export * from 'd3-drag';
export * from 'd3-dsv';
export * from 'd3-ease';
export * from 'd3-force';
export * from 'd3-format';
export * from 'd3-geo';
export * from 'd3-hierarchy';
export * from 'd3-interpolate';
export * from 'd3-path';
export * from 'd3-polygon';
export * from 'd3-quadtree';
export * from 'd3-queue';
export * from 'd3-random';
export * from 'd3-request';
export * from 'd3-scale';
export * from 'd3-selection';
export * from 'd3-shape';
export * from 'd3-time';
export * from 'd3-time-format';
export * from 'd3-timer';
export * from 'd3-transition';
export * from 'd3-voronoi';
export * from 'd3-zoom';
当我包含此代码时,我遇到的任何错误(并且仅在开发中看到)都消失了。希望这可以帮助您排除打字错误并让您更接近解决方案!
【讨论】:
谢谢布鲁斯。在发布问题之前我已经尝试过,但我仍然遇到错误。我切换到 d3 3.5.5,不幸的是打字版本是 3.3.6。例如,我仍然收到错误:let _data: any = d3.layout.pie().sort(null).value(function (d: any) return d.value; )(data);
如果我没有将 d 声明为任何,则打字稿转译器会抛出一个错误,指出“类型'数字'上不存在属性'值'。”。为了解决这个问题,我需要在 d 中添加任何类型。输入应该是可选的,但实际情况并非如此。【参考方案3】:
您只需要在创建弧时添加一个类型。试试这样的:
interface Datum
key: string;
value: number;
const pieData = d3.pie<Datum>()
.value(d => d.value)(data);
const arc = d3.arc<d3.PieArcDatum<Datum>>();
d3.select('#pie')
.data(pieData)
.enter()
.append('path')
.attr('d', arc);
【讨论】:
【参考方案4】:添加路径时试试这个:
newBlock.append("path")
.attr("d", arc())
.attr("id", function (d, i)
return "arc-" + i
)
.attr("stroke", "gray")
.attr("fill", function (d, i)
return d3.interpolateCool(Math.random())
);
根据d3 API,使用let arc = d3.arc()
构造弧生成器后,必须调用arc()
才能生成实际弧。
【讨论】:
我试过你告诉我的,但现在我得到这个错误:[at-loader] src\piechart\piechart.component.ts:19:28 提供的参数与调用目标的任何签名都不匹配。我认为打字不好。 如果在构造弧生成器时还包含 startAngle 和 endAngle(例如.startAngle(0).endAngle(Math.PI / 2)
),调用arc()
时仍然会出现该错误,但至少它会返回一个字符串你可以通过路径。【参考方案5】:
以下代码绘制一条弧线。您可以向arcData
提供更多物品:
import * as d3 from "d3";
export function run()
const chartLayer = d3.select('svg');
let chartHeight = 500;
let chartWidth = 500;
let data = null;
let arcData = [
innerRadius: 0,
outerRadius: 100,
startAngle: 0,
endAngle: Math.PI / 2,
padAngle: 1
];
let arc = d3.arc();
let pieG = chartLayer
.selectAll("g").data([data]).enter()
.append("g")
.attr("transform", "translate(" + [chartWidth / 2, chartHeight / 2] + ")");
let block = pieG.selectAll(".arc")
.data(arcData);
let newBlock = block.enter().append("g").classed("arc", true);
newBlock.append("path")
.attr("d", function (d) return arc(d) )
.attr("id", function (d, i)
return "arc-" + i
)
.attr("stroke", "gray")
.attr("fill", function (d, i)
return d3.interpolateCool(Math.random())
);
顺便说一句,我猜你不需要这条线
.selectAll("g").data([data]).enter()
【讨论】:
以上是关于D3、TS 和 Angular 2的主要内容,如果未能解决你的问题,请参考以下文章
带有 Ionic 2 Angular 2 和 TypeScript 的 OpenPGP