2017-11-17 2 views
2

Ich versuche, eine einfache Liniendiagramm plotten mit d3 in Angular2 Typoskript, Hier ist mein Code,Kreis Größe Null in d3 svg Winkel 2 Typoskript

import { Component, ViewChild, ElementRef, Input, OnInit } from '@angular/core'; 
import * as d3 from 'd3'; 

@Component({ 
selector: 'my-app', 
template: `<h1>Hello {{name}}</h1><div class="chart" #chart></div>`, 
}) 
export class AppComponent implements OnInit { 
@ViewChild('chart') private chartContainer: ElementRef; 
@Input() private data: Array<any>; 
private margin: any = { top: 20, bottom: 20, left: 20, right: 20}; 
private chart: any; 
private width: number; 
private height: number; 
private xScale: any; 
private yScale: any; 
private colors: any; 
private xAxis: any; 
private yAxis: any; 
name = 'Angular'; 

ngOnInit() { 
this.generateData(); 
this.createChart(); 
if (this.data) { 
    this.updateChart(); 
} 
} 

Hier erzeugt I Zufallsdaten

generateData() { 
    this.data = []; 
    for (let i = 0; i < (8 + Math.floor(Math.random() * 10)); i++) { 
     this.data.push([ 
      `Index ${i}`, 
      Math.floor(Math.random() * 100) 
     ]); 
    } 
} 

Hier erstelle ich X- und Y-Achse für die Linie,

createChart() { 

    let element = this.chartContainer.nativeElement; 
    let svg = d3.select(element).append('svg'); 

    svg.attr('width', element.offsetWidth) 
    .attr('height', element.offsetHeight); 

    this.width = this.chartContainer.nativeElement.offsetWidth - 
    this.margin.left - this.margin.right; 
    this.height = this.chartContainer.nativeElement.offsetHeight - 
    this.margin.top - this.margin.bottom; 

    // chart plot area 
    this.chart = svg; 

    // define X & Y domains 
    let xDomain = this.data.map(d => d[0]); 
    let yDomain = [0, d3.max(this.data, (d: any) => {return d[1]})]; 

// create scales 
this.xScale = d3.scaleBand().padding(0.1).domain(xDomain).rangeRound([0, this.width]); 
this.yScale = d3.scaleLinear().domain(yDomain).range([this.height, 0]); 

// bar colors 
this.colors = d3.scaleLinear().domain([0, this.data.length]).range(<any[]>['red', 'blue']); 

// x & y axis 
this.xAxis = svg.append('g') 
    .attr('class', 'axis axis-x') 
    .attr('transform', `translate(${this.margin.left}, ${this.margin.top + this.height})`) 
    .call(d3.axisBottom(this.xScale)); 
this.yAxis = svg.append('g') 
    .attr('class', 'axis axis-y') 
    .attr('transform', `translate(${this.margin.left}, ${this.margin.top})`) 
    .call(d3.axisLeft(this.yScale)); 
} 

Hier Plots ich versuchte (als Kreis) hinzuzufügen, zu den Orten, wo es h wie alles aufgetragen werden (plot Position, count) ist in Ordnung, aber die Breite und Höhe ist immer Null, also nicht in der Benutzeroberfläche

zeigt sich
updateChart() { 

     this.chart = this.chart.append('g') 
     .attr('class', 'dots') 
     .attr('transform', `translate(${this.margin.left}, ${this.margin.top})`); 

     // update scales & axis 
     this.xScale.domain(this.data.map(d => d[0])); 
     this.yScale.domain([0, d3.max(this.data, (d:any) => {return d[1]})]); 
     this.colors.domain([0, this.data.length]); 
     this.xAxis.transition().call(d3.axisBottom(this.xScale)); 
     this.yAxis.transition().call(d3.axisLeft(this.yScale)); 

     let update = this.chart.selectAll('.dot') 
      .data(this.data); 

     update.exit().remove(); 

     update 
      .enter() 
      .append('circle') 
      .attr('class', 'dot') 
      .attr('cx', (d : any) => {return this.xScale(d[0])}) 
      .attr('cy', (d:any) =>{return this.yScale(d[1])}) 
      .style('fill', (d:any, i:any) => { console.log(d); return this.colors(i)}); 
    } 

}

Wie im Bild unten, alle Plots sind dort, aber da g von Null Höhe und Breite ist, sind sie immer Null,

während wenn ich sie durch 'rect' anstelle von 'circle' mit Höhe und Breite ersetze, wird es angezeigt. Ich bin sicher, dass einige Styling für diese Elemente fehlen, aber nicht sicher, was sie sind, bitte geben Sie Anregungen oder beheben

enter image description here

+0

Haben Sie versucht, das Attribut 'radius' zum' Kreis' hinzuzufügen? – sol

+0

Aufnahme von Radius funktioniert, sorry, so ein dummer Fehler! – keerthee

+0

FWIW, du sagst das * "da g null Höhe und Breite hat, sind sie immer Null" * ... g Elemente haben keine Höhe oder Breite. Sie passen sich automatisch ihrem Inhalt an. –

Antwort

3

Sie haben die Radien der Kreise zu setzen, sonst wird standardmäßig auf Null (eigentlich null):

update.enter() 
    .append('circle') 
    .attr('class', 'dot') 
    .attr("r", someValue)//set the radius here 
    .attr('cx', (d : any) => {return this.xScale(d[0])}) 
    .attr('cy', (d:any) =>{return this.yScale(d[1])}) 
    .style('fill', (d:any, i:any) => { console.log(d); return this.colors(i)});