2017-07-21 164 views
0

我想用somethingA,somethingB,somethingC,somethingD将条形图添加到条形图的条形图中。d3.js条形图的标签栏

试图让它看起来像这样,

enter image description here

的数据形式,

data = [ 
      {name : 'somethingA', yVal : 1}, 
      {name : 'somethingB', yVal : 4}, 
      {name : 'somethingC', yVal : 2}, 
      {name : 'somethingD', yVal : 3} 
     ]; 

我尝试使用,

.attr('text', function(d){ 
        return xScale(d.name); 
       }) 

这是在angular4组件中运行。

在app.component.ts文件中的代码,

ngOnInit() { 
      let self = this; 
      let d3 = this.d3; 
      let d3ParentElement: any; 
      let svg: any; 
      let name: string; 
      let xVal: number 
      let yVal: number; 
      let data: {name: string, yVal: number}[] = []; 
      let padding: number = 25; 
      let width: number = 500; 
      let height: number = 150; 
      let xScale: any; 
      let yScale: any; 
      let xAxis: any; 
      let yAxis: any; 

    if (this.parentNativeElement !== null) { 
     svg = d3.select(this.parentNativeElement) 
      .append('svg')  // create an <svg> element 
      .attr('width', width) // set its dimensions 
      .attr('height', height); 

     data = [ 
      {name : 'A', yVal : 1}, 
      {name : 'B', yVal : 4}, 
      {name : 'C', yVal : 2}, 
      {name : 'D', yVal : 3} 
     ]; 

     xScale = d3.scaleLinear() 
      .domain([0,d3.max(data, function(d,i) {return i+1})]) 
      .range([0, 200]); 

     yScale = d3.scaleLinear() 
      .domain([0,d3.max(data, function(d) {return d.yVal})]) 
      .range([100, 0]); 

     xAxis = d3.axisBottom(xScale) // d3.js v.4 
      .ticks(5) 
      .scale(xScale); 

     yAxis = d3.axisLeft(xScale) // d3.js v.4 
      .scale(yScale) 
      .ticks(7); 

     svg.append("g") 
     .attr("class", "axis") 
     .attr("transform", "translate(" + (padding) + "," + padding + ")") 
     .call(yAxis); 

      svg.append('g')   // create a <g> element 
     .attr('class', 'axis') // specify classes 
      .attr("transform", "translate(" + padding + "," + (height - padding) + ")") 
     .call(xAxis);   // let the axis do its thing 

     var rects = svg.selectAll('rect') 
      .data(data); 
      rects.size(); 

     var newRects = rects.enter(); 

     newRects.append('rect') 
      // .attr('x', function(d, i) { 
      //  return xScale(i+1); 
      // }) 
      .attr("x", function(d,i) { 
      return xScale(i+1); 
      }) 
      .attr('y', function(d) { 
       return yScale(d.yVal); 
      }) 
      .attr('text', function(d){ 
       return xScale(d.name); 
      }) 
      .attr("transform","translate(" + (padding -5) + "," + (padding - 5) + ")") 
      .attr('height', function(d) { 
       return height - yScale(d.yVal) - (2*padding) + 5}) 
      .attr('width', 10); 
    } 
    } 

编辑:作为建议我使用scaleBand由杰拉德·费塔朵()。这是代码和输出。

ngOnInit() { 
      let self = this; 
      let d3 = this.d3; 
      let d3ParentElement: any; 
      let svg: any; 
      let name: string; 
      let xVal: number 
      let yVal: number; 
      let data: {name: string, yVal: number}[] = []; 
      let padding: number = 25; 
      let width: number = 500; 
      let height: number = 150; 
      let xScale: any; 
      let yScale: any; 
      let xAxis: any; 
      let yAxis: any; 

    if (this.parentNativeElement !== null) { 
     svg = d3.select(this.parentNativeElement) 
      .append('svg')  // create an <svg> element 
      .attr('width', width) // set its dimensions 
      .attr('height', height); 

     data = [ 
      {name : 'A', yVal : 1}, 
      {name : 'B', yVal : 4}, 
      {name : 'C', yVal : 2}, 
      {name : 'D', yVal : 3} 
     ]; 

     xScale = d3.scaleBand() 
      .domain(data.map(function(d){ return d.name; })) 
      .range([0, 200]); 

     yScale = d3.scaleLinear() 
      .domain([0,d3.max(data, function(d) {return d.yVal})]) 
      .range([100, 0]); 

     xAxis = d3.axisBottom(xScale) // d3.js v.4 
      .ticks(5) 
      .scale(xScale); 

     yAxis = d3.axisLeft(xScale) // d3.js v.4 
      .scale(yScale) 
      .ticks(7); 

     svg.append("g") 
     .attr("class", "axis") 
     .attr("transform", "translate(" + (padding) + "," + padding + ")") 
     .call(yAxis); 

      svg.append('g')   // create a <g> element 
     .attr('class', 'axis') // specify classes 
      .attr("transform", "translate(" + padding + "," + (height - padding) + ")") 
     .call(xAxis);   // let the axis do its thing 

     var rects = svg.selectAll('rect') 
      .data(data); 
      rects.size(); 

     var newRects = rects.enter(); 

     newRects.append('rect') 
      // .attr('x', function(d, i) { 
      //  return xScale(i+1); 
      // }) 
      .attr("x", function(d,i) { 
      return xScale(d.name); 
      }) 
      .attr('y', function(d) { 
       return yScale(d.yVal); 
      }) 
      .attr("transform","translate(" + (padding -5) + "," + (padding - 5) + ")") 
      .attr('height', function(d) { 
       return height - yScale(d.yVal) - (2*padding) + 5}) 
      .attr('width', 10); 
    } 
    } 

不幸的是,杆不定心在A,B,C和D. enter image description here

这导致在未对A,B,C,D。我用翻译居中杆( )移位它的权利有点像这样,

.attr("transform","translate(" + (padding -5 + 25) + "," + (padding - 5) + ")") 

enter image description here

+1

我觉得你的代码是不是“angularish” ... – Vega

+0

好吧,以及它在角4 –

+0

运行图形在angular4组件中运行。 –

回答

0

这里是组件类,

Full project codeDemo

export class D3graphComponent implements OnInit { 
    private d3: D3; 
    private parentNativeElement: any; 
    private d3Svg: Selection<SVGSVGElement, any, null, undefined>; 

    constructor(element: ElementRef, private ngZone: NgZone, d3Service: D3Service) { 
    this.d3 = d3Service.getD3(); 
    this.parentNativeElement = element.nativeElement; 
    } 

    ngOnInit() { 
      let self = this; 
      let d3 = this.d3; 
      let d3ParentElement: any; 
      let svg: any; 
      let name: string; 
      let yVal: number; 
      let colors: any = []; 
      let data: {name: string, yVal: number}[] = []; 
      let padding: number = 25; 
      let width: number = 500; 
      let height: number = 150; 
      let xScale: any; 
      let yScale: any; 
      let xColor: any; 
      let xAxis: any; 
      let yAxis: any; 

    if (this.parentNativeElement !== null) { 
     svg = d3.select(this.parentNativeElement) 
      .append('svg')  // create an <svg> element 
      .attr('width', width) // set its dimensions 
      .attr('height', height); 

     colors = ['red', 'yellow', 'green', 'blue']; 

     data = [ 
      {name : 'A', yVal : 1}, 
      {name : 'B', yVal : 4}, 
      {name : 'C', yVal : 2}, 
      {name : 'D', yVal : 3} 
     ]; 

     xScale = d3.scaleBand() 
      .domain(data.map(function(d){ return d.name; })) 
      .range([0, 200]); 

     yScale = d3.scaleLinear() 
      .domain([0,d3.max(data, function(d) {return d.yVal})]) 
      .range([100, 0]); 

     xAxis = d3.axisBottom(xScale) // d3.js v.4 
      .ticks(5) 
      .scale(xScale); 

     yAxis = d3.axisLeft(xScale) // d3.js v.4 
      .scale(yScale) 
      .ticks(7); 

     svg.append("g") 
     .attr("class", "axis") 
     .attr("transform", "translate(" + (padding) + "," + padding + ")") 
     .call(yAxis); 

      svg.append('g')   // create a <g> element 
     .attr('class', 'axis') // specify classes 
      .attr("transform", "translate(" + padding + "," + (height - padding) + ")") 
     .call(xAxis);   // let the axis do its thing 

     var rects = svg.selectAll('rect') 
      .data(data); 
      rects.size(); 

     var newRects = rects.enter(); 

     newRects.append('rect') 
      .attr('x', function(d,i) { 
      return xScale(d.name); 
      }) 
      .attr('y', function(d) { 
       return yScale(d.yVal); 
      }) 
      .attr("transform","translate(" + (padding -5 + 25) + "," + (padding - 5) + ")") 
      .attr('height', function(d) { 
       return height - yScale(d.yVal) - (2*padding) + 5}) 
      .attr('width', 10) 
      .attr('fill', function(d, i) { 
      return colors[i]; 
      }); 
    } 
    } 
}