Angular 如何在d3中使用SimulationLinkDatum和SimulationNodeDatum
我在使用SimulationLinkDatum类型时遇到问题。我创建了两个类Node和Link,它们实现了SimulationNodeDatum和SimulationLinkDatum。当我尝试使用SimulationLinkDatum类型脚本时,d.source.x、d.target.x等类型脚本说“属性“x”在类型“string | number | Node”上不存在。” 我理解SimulationLinkDatum接受源节点和目标节点属性的Angular 如何在d3中使用SimulationLinkDatum和SimulationNodeDatum,angular,typescript,d3.js,Angular,Typescript,D3.js,我在使用SimulationLinkDatum类型时遇到问题。我创建了两个类Node和Link,它们实现了SimulationNodeDatum和SimulationLinkDatum。当我尝试使用SimulationLinkDatum类型脚本时,d.source.x、d.target.x等类型脚本说“属性“x”在类型“string | number | Node”上不存在。” 我理解SimulationLinkDatum接受源节点和目标节点属性的number | string |,如果使用nu
number | string |
,如果使用number或string,它将变异为SimulationNodeDatum。这只是我们必须接受的东西,还是有更好的方法使用这些接口
谢谢
class D3Component {
private createPathString(d: SimulationLinkDatum<Node>) {
return 'M' + d.source.x + ',' + d.source.y + 'L' + d.target.x + ',' + d.target.y;
}
}
class Node implements SimulationNodeDatum {
public x: number;
public y: number;
constructor (public id: number) {}
}
class Link implements SimulationLinkDatum<Node> {
constructor (public source: Node, public target: Node) {}
}
D3类组件{
私有createPathString(d:SimulationLinkDatum){
返回'M'+d.source.x+'、'd.source.y+'L'+d.target.x+'、'+d.target.y;
}
}
类节点实现SimulationNodeDataum{
公共x:数字;
公众y:数字;
构造函数(公共id:number){}
}
类Link实现SimulationLinkDatum{
构造函数(公共源:节点,公共目标:节点){}
}
正如您正确指出的那样,d3 force的TypeScript定义反映了实际JS实现中固有的改变节点和链接数据结构的方法
具体而言,对于SimulationLinkDatum
接口,建议的做法是使用自定义类型的防护装置,例如:
function isNodeObject<T>(node: number | string| T): node is T {
return typeof node !== 'number' && typeof node !== 'string';
}
函数是nodeObject(节点:number | string | T):节点是T{
返回节点的类型!='number'&&typeof节点!='string';
}
然后,可以像往常一样使用TypeScript的类型缩小功能,例如,在上述情况下:
private createPathString(d: SimulationLinkDatum<Node>) {
if (isNodeObject(d.source) && isNodeObject(d.target)) {
return 'M' + d.source.x + ',' + d.source.y + 'L' + d.target.x + ',' + d.target.y;
} else {
return '';
}
}
private createPathString(d:SimulationLinkDatum){
if(isNodeObject(d.source)和&isNodeObject(d.target)){
返回'M'+d.source.x+'、'd.source.y+'L'+d.target.x+'、'+d.target.y;
}否则{
返回“”;
}
}
虽然这是最可重用的方法,但在某些情况下,以下两种方法可能更适合:
(1) 如果已知给定的代码段将仅在已初始化的链接上调用,则可以简单地强制转换(d.source).x
。对强制转换节点对象使用局部变量可以提高下游可读性
(2) 在if
-子句中直接使用类型缩小,而不创建可重用的自定义类型保护
鉴于当前定义接口的方式,这些是访问变异属性中对象的关键方法