2016-08-08 51 views
1

Ich habe eine einfache Ionic App zum Testen der Integration von d3.js erstellt. Es ist hier zu finden: https://github.com/wberger/ionic2-d3js-testD3.js und Ionic 2: Elemente nicht in DOM auf der zweiten Seitenansicht

ich die Integration tat wie folgt:

  1. Eine App mit Seiten Navigation und einer einzigen Seite (home.html)
  2. hinzufügen home.html zum Menü.
  3. laden d3.js in index.html: <script src="https://d3js.org/d3.v4.min.js"></script>
  4. hinzufügen <div id="chart"></div> zu home.html
  5. das Diagramm in ngAfterViewInit() in home.ts erstellen

Die home Vorlage ist wie folgt definiert (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> 
    The world is your oyster. 
    <p> 
    If you get lost, the <a href="http://ionicframework.com/docs/v2">docs</a> will be your guide. 
    </p> 
    <div id="chart"></div> 
    <p>After</p> 
</ion-content> 

Das Diagramm creat Ionen wird wie folgt implementiert (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); 
    } 

, wenn die Anwendung gestartet wird, wird das Diagramm, wie beabsichtigt angezeigt. Wenn Sie die Seite jedoch über das Seitenmenü öffnen (neu), ist das Diagramm nicht vorhanden. Wenn die TS/DOM in Google Chrome Inspektion, kann ich folgendes Verhalten beobachten, wenn der Wiedereröffnung:

  • ngAfterViewInit() aufgerufen wird und wiederum Anrufe ‚Create()‘
  • Die zuvor erstellte SVG-Elemente sind immer noch da
  • Ein zweites SVG Element durch createChart()

nach ngAfterViewInit() die erstellen SVG gegangen wird erstellt und gefüllt werden. Es scheint, dass das DOM durch die leere (oder eine zwischengespeicherte ??) Vorlage ersetzt wird.

Also meine Fragen sind:

  • Was hier schief geht? Was soll ich wissen?
  • Wie kann ich das beheben?
+0

Hallo Thewolf, hatten Sie eine Chance, dieses Problem zu lösen und d3js in Ionic 2 arbeiten zu lassen? Danke für Ihre Rückmeldung! Antoine. –

Antwort

0

Ich löste das Problem, indem das Diagramm als Bestandteil Aufbau:

@Component({ 
    selector: 'my-chart', 
    inputs: ['options', 'data'], 
    template: `` 
}) 
export class MyChart implements OnChanges { 

    el: any; 
    options: MyChartOptions; 
    data: MyChartData; 

    chart: any; 
    arcMap: any; 

    /** 
    * Initializes the component with the root element. 
    */ 
    constructor(@Inject(ElementRef) elementRef: ElementRef) { 
    this.el = elementRef.nativeElement; 
    } 

    /** 
    * Handler for binding changes. 
    * @param changes The changed bound values. 
    */ 
    ngOnChanges(changes) { 
    if (changes.options) { 
     this.updateWithOptions(this.options); 
    } 

    if (changes.data) { 
     this.updateWithData(this.data); 
    } 
    } 

    // handlers, drawing etc. ... 
} 

Es kann dann integriert werden, wie folgt:

<my-chart [data]="chartData" [options]="chartOptions"></my-chart> 

Vergessen Sie nicht, die Komponente in app.module.ts registrieren , zB:

import { MyChart } from '../components/charts/my-chart'; 

// ... 

@NgModule({ 
    declarations: [ 
    // ... 
    MyChart 
    ], 
    imports: [ 
    // ... 
    ], 
    bootstrap: [MyApp], 
    entryComponents: [ 
    // ... 
    ], 
    providers: [ 
    // ... 
    ] 
})