D3.js and Ionic 2: Elements not in DOM on second page view -


i have created simple ionic app testing integration of d3.js. can found here: https://github.com/wberger/ionic2-d3js-test

i did integration follows:

  1. create app side navigation , single page (home.html)
  2. add home.html menu.
  3. load d3.js in index.html: <script src="https://d3js.org/d3.v4.min.js"></script>
  4. add <div id="chart"></div> home.html
  5. create chart in ngafterviewinit() in home.ts

the home template defined follows (source):

<ion-header>   <ion-navbar>     <button menutoggle>       <ion-icon name="menu"></ion-icon>     </button>     <ion-title>       ionic blank     </ion-title>   </ion-navbar> </ion-header>  <ion-content padding>   world oyster.   <p>     if lost, <a href="http://ionicframework.com/docs/v2">docs</a> guide.   </p>   <div id="chart"></div>   <p>after</p> </ion-content> 

the chart creation implemented follows (source):

  ngafterviewinit() {     this.createchart();   }    createchart() {     var chart = d3.select("#chart").append("svg")       .attr("width", 100)       .attr("height", 100)       .append("g");      var rows = [       {x: 1, y: 1},       {x: 2, y: 2},       {x: 3, y: 3},     ];      var xscale = d3.scalelinear()             .range([0, 100])             .domain([1, 3]);     var yscale = d3.scalelinear()             .range([100, 0])             .domain([1, 3]);      chart.selectall(".dot")       .data(rows)       .enter().append("circle")       .attr("class", "dot")       .attr("cx", (row) => { return xscale(row.x) })       .attr("cy", (row) => { return yscale(row.y) })       .attr("r", 3.5);   } 

when starting app, chart displayed intended. when (re-)opening page side menu, chart not there. when inspecting ts/dom in google chrome, can observe following behaviour when re-opening:

  • ngafterviewinit() gets called , in turn calls 'createchart()'
  • the created svg elements still there
  • a second svg element created , filled createchart()

after ngafterviewinit() created svg gone. seems dom replaced empty (or cached??) template.

so questions are:

  • what goes wrong here? should know?
  • how can fix that?

i solved issue building chart component:

@component({   selector: 'my-chart',   inputs: ['options', 'data'],   template: `` }) export class mychart implements onchanges {    el: any;   options: mychartoptions;   data: mychartdata;    chart: any;   arcmap: any;    /**    * initializes component root element.    */   constructor(@inject(elementref) elementref: elementref) {     this.el = elementref.nativeelement;   }    /**    * handler binding changes.    * @param changes changed bound values.    */   ngonchanges(changes) {     if (changes.options) {       this.updatewithoptions(this.options);     }      if (changes.data) {       this.updatewithdata(this.data);     }   }    // handlers, drawing etc. ... } 

it can integrated follows:

<my-chart [data]="chartdata" [options]="chartoptions"></my-chart> 

don't forget register component in app.module.ts, e.g.:

import { mychart } '../components/charts/my-chart';  // ...  @ngmodule({   declarations: [     // ...     mychart   ],   imports: [     // ...   ],   bootstrap: [myapp],   entrycomponents: [     // ...   ],   providers: [     // ...   ] }) 

Comments

Popular posts from this blog

Spring Boot + JPA + Hibernate: Unable to locate persister -

go - Golang: panic: runtime error: invalid memory address or nil pointer dereference using bufio.Scanner -

c - double free or corruption (fasttop) -