d3---餅圖

<!DOCTYPE html><html lang="en"><head>   <meta charset="UTF-8">   <style>      polyline {         opacity: .3;         stroke: black;         stroke-width: 2px;         fill: none;      }        .tooltip{            position: absolute;            width: 120px;            min-height: 50px;            font-size: 14px;            text-align: center;            border-style: solid;            border-width: 1px;            border-color: #666;            background:rgba(0,0,0,.5);            color:white;            border-radius: 5px;        }   </style></head><body><svg width="100%" height="500"></svg><script src="d3.min.js" charset="utf-8"></script><script>    const json = [        {name: '購物', value: 983},        {name: '平常', value: 300},        {name: '醫藥', value: 140},        {name: '交通', value: 402},        {name: '雜費', value: 134}    ];    class ReactPie {        constructor(props){            this.width = 600;            this.height = 300;            this.radius = 100;            this.pie = d3.layout.pie().value(d =>d.value);            this.svg = d3.select('svg').append('g').attr("transform",`translate(${this.width/2} ${this.height/2})`);            this.arc = d3.svg.arc().innerRadius(this.radius).outerRadius('10');            this.outerArc = d3.svg.arc().innerRadius(1.2 * this.radius).outerRadius(1.2 * this.radius);            this.oArc = d3.svg.arc().innerRadius(1.1 * this.radius).outerRadius(1.1 * this.radius);            this.color = d3.scale.category10();            this.tooltip = d3.select('body').append('div').attr('class','tooltip').style('opacity','0')        };        init(){            this.drawMap(json);            this.drawLine(json);            this.drawText(json);        }        drawMap(json){            const pieData = this.pie(json);            const _this = this;            this.svg.append('g').attr('class', 'slices').selectAll("g")                .data(pieData)                .enter()                .append('path')                .attr('fill',(d,i)=>this.color(i))                .attr('d',d=>this.arc(d))                .on('mouseover',function(d){                    _this.tooltip.html(`${d.data.name}:${d.data.value}`)                        .style('left',`${d3.event.pageX}px`)                        .style('top',`${d3.event.pageY-60}px`)                        .style('opacity',1);                    d3.select(this)                        .transition()                        .duration(300)                        .ease('bounce')                        .style('box-shadow','0 0 5px #000')                        .attr('transform',()=>`scale(1.1)`)                })                .on('mousemove',d =>{                    _this.tooltip.html(`${d.data.name}:${d.data.value}`)                        .style('left',`${d3.event.pageX}px`)                        .style('top',`${d3.event.pageY-60}px`)                        .style('opacity',1);                })                .on('mouseout',function (){                    _this.tooltip.style('opacity',0);                    d3.select(this)                        .transition()                        .duration(300)                        .ease('bounce')                        .attr('transform',()=>`scale(1)`)                });        }        drawLine(json){            const pieData = this.pie(json);            this.svg.append('g')                .attr('class','line')                .selectAll('polyline')                .data(pieData)                .enter()                .append('polyline')                .attr('points', d =>[this.arc.centroid(d), this.arc.centroid(d), this.arc.centroid(d)])                .attr('points',(d) =>{                    const pos = this.outerArc.centroid(d);                    pos[0] = this.radius * (this.midAngel(d)<Math.PI ? 1.5 : -1.5);                    return [this.oArc.centroid(d), this.outerArc.centroid(d), pos];                })        }        drawText(json){            const pieData = this.pie(json);            this.svg.append('g')                .attr('class','text')                .selectAll('text')                .data(pieData)                .enter()                .append('text')                .attr('dy','0.35em')                .attr('fill', (d, i)=>this.color(i))                .text(d =>d.data.name)                .style('text-anchor', d =>this.midAngel(d)<Math.PI ? 'start' : 'end')                .attr('transform', (d) => {                    // 找出外弧形的中心點                    const pos = this.outerArc.centroid(d);                    // 改變文字標識的x座標                    pos[0] = this.radius * (this.midAngel(d)<Math.PI ? 1.6 : -1.6);                    return 'translate(' + pos + ')';                })                .style('opacity', 1);        }        midAngel(d){            return d.startAngle + (d.endAngle - d.startAngle)/2;        }    }    const a = new ReactPie().init(json);</script></body></html>
相關文章
相關標籤/搜索