javascript - D3 chart indside bootstrap tab -


i'm tryng implement d3 chart angular 4 ,every thing works fine ,now i'm tryng put svg element inside bootstrap tab error.

error error: uncaught (in promise): typeerror: cannot read property 'nativeelement' of undefined

html code

<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> 

the angular code lines caused problem

mycomponent code

import { component, oninit, ondestroy,afterviewinit, viewchild , elementref} '@angular/core';  import * d3 '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;   }    } 

you need use elementref directly reference dom elements. in template, this:

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

in class, create instance variable:

import { ..., viewchild, elementref } '@angular/core';      ...  @viewchild('svg') svgelement: elementref;  ...  drawsvg() {   let svg = this.svgelement.nativeelement;   let width = svg.attr("width");   let height = svg.attr("height");   ... } 

Comments

Popular posts from this blog

neo4j - finding mutual friends in a cypher statement starting with three or more persons -

php - How to remove letter in front of the word laravel -

minify - Minimizing css files -