declare const d3; export class BarChart { svg: any; svgWidth=400; svgHeight=400; padding={top:30,bottom:30,left:30,right:30} rectWidth=30 axisWidth=300 axisHeight=300 constructor(target: HTMLElement) { this.svg=d3.select(target) .attr('width',this.svgWidth) .attr('height',this.svgHeight) } drawBar(data) { let names=['小明','小紅','小圓','小賈','小豬'] //座標軸 let xscale=d3.scalePoint() .domain(names) .rangeRound([0,this.axisWidth]) .padding(0.8) let xaxis=d3.axisBottom(xscale) this.svg.append('g').attr('transform',`translate(${this.padding.left},${this.svgHeight-this.padding.bottom})`).call(xaxis) let yscale=d3.scaleLinear([100,0],[0,this.axisHeight]) let yaxis=d3.axisLeft(yscale) this.svg.append('g') .call(yaxis) .attr('transform',`translate(${this.padding.left},${this.svgHeight-this.axisHeight-this.padding.bottom})`) //數據縮放 data=data.map(d=>yscale(d)) //console.log(data); //y軸原點的縱座標 let y0=this.svgHeight-this.padding.bottom-this.axisHeight let rect=this.svg.selectAll('rect').data(data) .join(enter=>{ enter.append('rect').attr('fill','red') .attr('x',(d,i)=>xscale(names[i])+this.padding.left-0.5*this.rectWidth) .attr('y',d=>y0+d) .attr('width',this.rectWidth) .attr('height',d=>this.axisHeight-d) },update=>{ update.attr('fill','red') .attr('x',(d,i)=>xscale(names[i])+this.padding.left-0.5*this.rectWidth) .attr('y',d=>y0+d) .attr('width',this.rectWidth) .attr('height',d=>this.axisHeight-d) },exit=>{ exit.remove() }) //console.log(rect); let text=this.svg.selectAll('.text').data(data) .join(enter=>{ enter.append('text') .text(d=>yscale.invert(d)) .attr('x',(d,i)=>xscale(names[i])+this.padding.left) .attr('y',d=>y0+d) .attr('text-anchor','middle') },update=>{ update .text(d=>yscale.invert(d)) .attr('x',(d,i)=>xscale(names[i])+this.padding.left) .attr('y',d=>y0+d) .attr('text-anchor','middle') },exit=>{ exit.remove() }) //console.log(text); } }