import * as d3 from 'd3'; import { pieInner, pieTop, pieOuter } from '../utils/renderUtils' /** * 生成3d饼图 * @param {*} id :id唯一标识 * @param {*} width :svg的宽 * @param {*} height :svg的高 * @param {*} data :要渲染的数据 * @param {*} x :横向偏移量 * @param {*} y :纵向偏移量 * @param {*} rx :饼图的横向半径 * @param {*} ry :饼图的纵向半径 * @param {*} h :饼图的高度 */ export default function pie(id, width, height, data, x, y, rx, ry, h, config,ir=0){ //先移除所有的svg d3.select(id).selectAll('svg').remove(); //创建一个svg容器,用来存放饼图 const pieSvg = d3 .select(id) .append('svg') .attr('width','100%') .attr('height','100%'); pieSvg.append('g').attr('id','pie_chart'); //生成饼图数据 const dataset = d3 .pie() .sort(null) .value((d) => { return d.value })(data); // 获取上面插入的g const slices = d3 .select('#pie_chart') .append('g') .attr('transform','translate(350,200)') .attr('class','slices') .style('cursor','pointer'); //生成环形内曲面 slices .selectAll('.innerSlice') .data(dataset) .enter() .append('path') .attr('class','innerSlice') .style('fill',(d,index) => { let colorIndex = index % config.color.length return d3.hsl(config.color[colorIndex]).darker(0.7) }) .attr('d',d => { return pieInner(d, rx+0.5, ry+0.5, h, ir) }); //上层2D平面 slices.selectAll('.topSlice') .data(dataset) .enter() .append('path') .transition() .delay(0) .duration(500) .attrTween('d',(d) => { //动画效果 let interpolate = d3.interpolate(d.startAngle, d.endAngle); return function(t){ d.endAngle = interpolate(t); return pieTop(d, rx, ry, ir) } }) .attr('class','topSlice') .style('fill',(d,index) => { let colorIndex = index % config.color.length return config.color[colorIndex] }) .style('stroke',(d,index) => { let colorIndex = index % config.color.length console.log(config.color[colorIndex],'==config.color[colorIndex]') return config.color[colorIndex] }) //侧面曲面 slices.selectAll('.outerSlice') .data(dataset) .enter() .append('path') .transition() .delay(0) .duration(500) .attrTween('d',(d) => { //动画效果 let interpolate = d3.interpolate(d.startAngle, d.endAngle); return function(t){ d.endAngle = interpolate(t); return pieOuter(d, rx- 0.5, ry - 0.5, h) } }) .attr('class','outerSlice') .style('fill',(d,index) => { let colorIndex = index % config.color.length return d3.hsl(config.color[colorIndex]).darker(0.7) }); //是否显示标签 if(config.sfShowLabel){ //创建文本标签引导线 const line = d3.select('#pie_chart') .append('g') .attr('transform',`translate(350,200)`) .attr('class','line'); //引导线 line.selectAll('.line') .data(dataset) .enter() .append('line') .attr('stroke',(d,index) => { let colorIndex = index % config.color.length return config.color[colorIndex] }) .attr('x1',0) .attr('y1',0) .attr('x2',d => { return 1.5 * rx * Math.cos(0.5 * (d.startAngle + d.endAngle)) }) .attr('y2',d => { return 1.5 * ry * Math.sin(0.5 * (d.startAngle + d.endAngle)) }) .style('visibility', d => { return 'visible' }); //文本 const textbox = d3.select('#pie_chart') .append('g') .attr('transform','translate(350,200)') .attr('class','textbox'); const text = textbox.selectAll('desc') .data(dataset) .enter() .append('text') .attr('font-size','14px') .attr('text-anchor','middle') .style('visibility', d => { return 'visible' }) .attr('fill',(d,index) => { let colorIndex = index % config.color.length return config.color[colorIndex] }) .text(d => { return `${d.data.label}:${d.data.value}${d.data.DWMC}` }) .attr('transform', d => { let x = 1.5 * (rx + 10) * Math.cos(0.5 * (d.startAngle + d.endAngle)) let y = 1.5 * (ry + 10) * Math.sin(0.5 * (d.startAngle + d.endAngle)) return `translate(${x},${y})` }) } }