我刚刚开始使用Angularjs 2和d3-ng2-service,我正在尝试使用网络图表.
我用例子
https://bl.ocks.org/mbostock/2675ff61ea5e063ede2b5d63c08020c7
并将其转换为d3-ng2-service.
我收到以下错误
"属性链接不存在类型force()"
使用以下代码
simulation.force("link")
.links(links);
Run Code Online (Sandbox Code Playgroud)
完整代码如下
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在将bl.ock移植到TypeScript时,需要进行一些调整以确保节点和链接的数据类型以及正确处理不同的强制类型.
forceSimulation
在调用它时接受两个泛型.让我们假设,您的节点是YourNodeType
扩展的类型,SimulationNodeDatum
链接是YourLinkType
扩展的类型SimulationLinkDatum<YourNodeType>
.SimulationNodeDatum
并且SimulationLinkDatum
是d3-force定义中定义的接口.
(见d3-force定义).
话虽如此,您应该定义let simulation = d3.forceSimulation<YourNodeType, YourLinkType>()
这种方式,节点,对于您的情况,重要的是在整个模拟过程中强制实施链接类型.
现在,对于您遇到的错误的核心,为了检索具有除最小Force
接口之外的属性的力,必须将力转换为事前已知类型.在您的情况下,链接强制在定义中具有预定义的接口.
因此simulation.force<ForceLink<YourNodeType, YourLinkType>>('link')
,将使用已定义的links()
方法返回链接力.
一些内务注释,因为您正在使用d3-ng2-service,接口SimulationNodeDatum
,SimulationLinkDatum
并且ForceLink
可以直接从d3-ng2-service
包含角度组件的文件导入.
如果你正在使用strictNullChecks
,你可能想要simulation.force<ForceLink<YourNodeType, YourLinkType>>('link')!.links()
,在哪里!
解决返回的力量undefined
一般的情况.事实并非如此.
希望这可以帮助.
汤姆的回答为我指明了正确的方向,我成功地完成了这项工作 - 谢谢汤姆。对于其他正在解决此问题的人,就我而言,我还必须添加.links(links)
以下simulation.force()
内容:
simulation.force("link").links(links);
Run Code Online (Sandbox Code Playgroud)
变成:
simulation.force<ForceLink<any, any>>('link').links(links);
Run Code Online (Sandbox Code Playgroud)
我想将此添加为评论,但我的代表不够高。
归档时间: |
|
查看次数: |
1202 次 |
最近记录: |