Angular d3-ng2-服务错误“;不存在force()类型的属性链接;
我刚刚开始使用AngularJS2和d3-ng2-service,我正在尝试让网络图正常工作 我举个例子 并将其转换为d3-ng2-service 我得到以下错误 “force()类型的属性链接不存在” 使用以下代码Angular d3-ng2-服务错误“;不存在force()类型的属性链接;,angular,d3.js,Angular,D3.js,我刚刚开始使用AngularJS2和d3-ng2-service,我正在尝试让网络图正常工作 我举个例子 并将其转换为d3-ng2-service 我得到以下错误 “force()类型的属性链接不存在” 使用以下代码 simulation.force("link") .links(links); 下面列出了完整的代码 import { Component, ElementRef, NgZone, OnDestroy, OnInit } from '@angular/core'
simulation.force("link")
.links(links);
下面列出了完整的代码
import { Component, ElementRef, NgZone, OnDestroy, OnInit } from '@angular/core';
import { links, nodes} from './networkData.component';
import {
D3Service,
D3,
Axis,
ScaleLinear,
ScaleOrdinal,
Selection,
Simulation,
Transition
} from 'd3-ng2-service';
@Component({
selector: 'network1',
template: '<svg width="100%" height="100%"></svg>',
styleUrls: ['./network.component.css']
})
export class Network1Component implements OnInit, OnDestroy {
private d3: D3;
private parentNativeElement: any;
private d3Svg: Selection<SVGSVGElement, any, null, undefined>;
constructor(element: ElementRef, private ngZone: NgZone, d3Service: D3Service) {
this.d3 = d3Service.getD3();
this.parentNativeElement = element.nativeElement;
}
ngOnDestroy() {
if (this.d3Svg.empty && !this.d3Svg.empty()) {
this.d3Svg.selectAll('*').remove();
}
}
ngOnInit() {
let self = this;
let d3 = this.d3;
let width: number;
let height: number;
let d3ParentElement: Selection<HTMLElement, any, null, undefined>;
let d3Svg: Selection<SVGSVGElement, any, null, undefined>;
if (this.parentNativeElement !== null) {
d3ParentElement = d3.select(this.parentNativeElement);
d3Svg = this.d3Svg = d3ParentElement.select<SVGSVGElement>('svg');
width = +d3Svg.attr('width');
height = +d3Svg.attr('height');
var color = d3.scaleOrdinal(d3.schemeCategory20);
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) { return d[0].id; }))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2));
var link = d3Svg.append<SVGGElement>('g')
.attr("class", "links")
.selectAll("line")
.data(links)
.enter().append("line")
.attr("stroke-width", function(d) { return Math.sqrt(d.value); });
var node = d3Svg.append<SVGGElement>('g')
.attr("class", "nodes")
.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("r", 5)
.attr("fill", function(d) { return color(d.id); });
node.append("title")
.text(function(d) { return d.id; });
simulation
.nodes(nodes)
.on("tick", ticked);
simulation.force("link")
.links(links);
}
function ticked() {
link
.attr("x1", function(d) { return d.source; })
.attr("y1", function(d) { return d.source; })
.attr("x2", function(d) { return d.target; })
.attr("y2", function(d) { return d.target; });
node
.attr("cx", function(d) { return d.id; })
.attr("cy", function(d) { return d.id; });
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
}
}
从'@angular/core'导入{Component,ElementRef,NgZone,OnDestroy,OnInit};
从“./networkData.component”导入{links,nodes};
进口{
D3服务,
D3,
轴
标线,
尺度正交,
选择,
模拟
过渡
}来自“d3-ng2-service”;
@组成部分({
选择器:“网络1”,
模板:“”,
样式URL:['./network.component.css']
})
导出类Network1组件在OnIt、OnDestroy上实现{
私人d3:d3;
private parentNativeElement:任何;
私有化:选择;
构造函数(元素:ElementRef,私有ngZone:ngZone,d3Service:d3Service){
this.d3=d3Service.getD3();
this.parentNativeElement=element.nativeElement;
}
恩贡德斯特罗(){
if(this.d3Svg.empty&&!this.d3Svg.empty()){
this.d3Svg.selectAll('*').remove();
}
}
恩戈尼尼特(){
让自我=这个;
设d3=this.d3;
让宽度:数字;
让高度:数字;
让我们选择一个元素:选择;
设d3Svg:选择;
if(this.parentNativeElement!==null){
d3ParentElement=d3.select(this.parentNativeElement);
d3Svg=this.d3Svg=d3ParentElement.select('svg');
宽度=+d3Svg.attr('width');
高度=+d3Svg.attr('height');
var color=d3.scaleOrdinal(d3.schemeCategory 20);
var simulation=d3.forceSimulation()
.force(“link”,d3.forceLink().id(函数(d){返回d[0].id;}))
.force(“电荷”,d3.forceManyBody())
.力(“中心”,d3.力中心(宽度/2,高度/2));
var link=d3Svg.append('g')
.attr(“类”、“链接”)
.selectAll(“行”)
.数据(链接)
.enter().append(“行”)
.attr(“笔划宽度”,函数(d){return Math.sqrt(d.value);});
var node=d3Svg.append('g')
.attr(“类”、“节点”)
.selectAll(“圆圈”)
.数据(节点)
.enter().append(“圆”)
.attr(“r”,5)
.attr(“fill”,函数(d){返回颜色(d.id);});
node.append(“标题”)
.text(函数(d){返回d.id;});
模拟
.节点(节点)
。在(勾选)上;
模拟力(“链接”)
.链接(links);
}
函数勾选(){
链接
.attr(“x1”,函数(d){返回d.source;})
.attr(“y1”,函数(d){返回d.source;})
.attr(“x2”,函数(d){返回d.target;})
.attr(“y2”,函数(d){返回d.target;});
节点
.attr(“cx”,函数(d){返回d.id;})
.attr(“cy”,函数(d){返回d.id;});
}
函数dragstarted(d){
如果(!d3.event.active)simulation.alphaTarget(0.3.restart();
d、 fx=d.x;
d、 fy=d.y;
}
函数(d){
d、 fx=d3.event.x;
d、 fy=d3.event.y;
}
函数d(d){
如果(!d3.event.active)simulation.alphaTarget(0);
d、 fx=null;
d、 fy=null;
}
}
}
在将bl.ock移植到TypeScript时,需要进行一些调整,以确保正确处理节点和链接的数据类型以及各种力类型
forceSimulation
在调用时接受两个泛型。让我们假设,您的节点类型为YourNodeType
,它扩展了SimulationNodeDatum
,链接类型为YourLinkType
,它扩展了SimulationLinkDatum
,SimulationNodeDatum
和SimulationLinkDatum
是d3 force定义中定义的接口
(见附件)
话虽如此,您应该通过这种方式定义let simulation=d3.forceSimulation()
,节点和重要的链接类型在整个模拟过程中都是强制的
现在讨论您遇到的错误的核心,为了检索具有最小force
接口以外属性的力,有必要将力强制转换为事先已知的类型。在您的情况下,链接力在定义中具有预定义的接口
因此,simulation.force('link')
,将返回一个定义了links()
方法的链接力
由于您使用的是d3-ng2-service,因此可以将接口SimulationNodeDatum
、SimulationLinkDatum
和ForceLink
直接从d3-ng2-service
导入包含角度分量的文件中
如果使用的是stricnullchecks
,则可能需要simulation.force('link')!。链接()
,其中代码>解决返回力通常可能未定义的情况。显然,你不是这样
希望这能有所帮助。汤姆的回答为我指明了正确的方向,我成功地实现了这一目标——谢谢汤姆。对于其他正在处理此问题的人,在我的例子中,我还必须将.links(links)
添加到simulation.force()
以便:
simulation.force("link").links(links);
变成:
simulation.force<ForceLink<any, any>>('link').links(links);
simulation.force('link')。links(links);
我想加上这个作为评论,但我的代表不够高