2017-09-12 73 views
0

我試圖實現與角4的d3圖表,每件事情都很好,現在我試圖將svg元素放入引導選項卡,但我得到這個錯誤。D3圖表indside bootstrap選項卡

錯誤錯誤:未捕獲(在承諾):類型錯誤:無法讀取的未定義

HTML代碼屬性 'nativeElement'

<ul class="nav nav-tabs profile-tab" role="tablist"> 
    <li class="nav-item"> <a class="nav-link active" data-toggle="tab" href="#profile" role="tab">Profile</a> </li>        
</ul> 

<div class="tab-content"> 
    <div class="tab-pane active" id="profile" role="tabpanel"> 
     <div class="card-block"> 
      <svg width="560" height="400"></svg> 
     </div> 
    </div> 
</div> 

導致問題

myComponent的代碼的角代碼行

import { Component, OnInit, OnDestroy,AfterViewInit, ViewChild , ElementRef} from '@angular/core'; 

import * as d3 from 'd3'; 

@Component({ 
selector: 'jhi-pathway-detail', 
templateUrl: './pathway-detail.component.html' 
}) 
export class PathwayDetailComponent implements OnInit, OnDestroy, 
    AfterViewInit { 


@ViewChild('svg') svgElement: ElementRef; 

svg= this.svgElement.nativeElement; 
color; 
simulation; 
link; 
node; 

constructor( 
) { 
} 

ngOnInit() { 

    } 

ngAfterViewInit(){ 
    this.svg = d3.select("svg"); 

    let width = this.svg.attr("width"); 
    let height =this.svg.attr("height"); 


    this.color = d3.scaleOrdinal(d3.schemeCategory20); 

    this.simulation = d3.forceSimulation() 
    .force("link", d3.forceLink().id(function(d) { return d.id; })) 
    .force("charge", d3.forceManyBody()) 
    .force("center", d3.forceCenter(width/2, height/2)); 

    this.render(this.grapgData); 
    } 


ticked() { 
    this.link 
    .attr("x1", function(d) { return d.source.x; }) 
    .attr("y1", function(d) { return d.source.y; }) 
    .attr("x2", function(d) { return d.target.x; }) 
    .attr("y2", function(d) { return d.target.y; }); 

this.node 
    .attr("cx", function(d) { return d.x; }) 
    .attr("cy", function(d) { return d.y; }); 
} 

render(graph){ 
this.link = this.svg.append("g") 
    .attr("class", "links") 
    .selectAll("line") 
    .data(graph.links) 
    .enter().append("line") 
    .attr("stroke-width", function(d) { return Math.sqrt(d.value); }); 

this.node = this.svg.append("g") 
    .attr("class", "nodes") 
    .selectAll("circle") 
    .data(graph.nodes) 
    .enter().append("circle") 
    .attr("r", 5) 
    .attr("fill", (d)=> { return this.color(d.group); }) 
    .call(d3.drag() 
     .on("start", (d)=>{return this.dragstarted(d)}) 
     .on("drag", (d)=>{return this.dragged(d)}) 
     .on("end", (d)=>{return this.dragended(d)})); 

this.node.append("title") 
    .text(function(d) { return d.id; }); 

this.simulation 
    .nodes(graph.nodes) 
    .on("tick",()=>{return this.ticked()}); 

this.simulation.force("link") 
    .links(graph.links); 
} 

dragged(d) { 
    d.fx = d3.event.x; 
    d.fy = d3.event.y; 
} 

dragended(d) { 
    if (!d3.event.active) this.simulation.alphaTarget(0); 
    d.fx = null; 
    d.fy = null; 
} 

dragstarted(d) { 
    if (!d3.event.active) this.simulation.alphaTarget(0.3).restart(); 
    d.fx = d.x; 
    d.fy = d.y; 
    } 

    } 

回答

0

您將需要使用ElementRef到d直接引用DOM元素。在您的模板,做這樣的事情:

<svg width="560" height="400" #svg></svg> 

在你的類,創建一個實例變量:

import { ..., ViewChild, ElementRef } from '@angular/core';  

... 

@ViewChild('svg') svgElement: ElementRef; 

... 

drawSvg() { 
    let svg = this.svgElement.nativeElement; 
    let width = svg.attr("width"); 
    let height = svg.attr("height"); 
    ... 
} 
+0

感謝重播,我都試過,但得到錯誤錯誤:未捕獲的(在承諾):類型錯誤:無法讀取未定義的屬性'nativeElement' –

+0

您的svg元素如何定義(在您的模板中)? – Brian

+0

我已更新帖子並添加組件代碼 –