function getCoordinates(startArc: number, endArc: number) { const posi = [ Math.sin(startArc), -Math.cos(startArc), Math.sin(endArc), -Math.cos(endArc), ]; const dx = posi[2] - posi[0]; const dy = posi[3] - posi[1]; return getLocation(dx, dy); } function getLocation(dx: number, dy: number) { const tanV = dx / dy; const directSign = Math.abs(tanV) < 1; const t = directSign ? tanV : 1 / tanV; const sign1 = t > 0 ? 1 : -1; const sign2 = dx > 0 ? 1 : -1; const sign = directSign ? sign1 * sign2 : sign2; const group1 = [0.5 - (sign * t) / 2, 0.5 + (sign * t) / 2]; const group2 = sign > 0 ? [0, 1] : [1, 0]; const group = [...group1, ...group2]; const keys = directSign ? ["x", "x2", "y", "y2"] : ["y", "y2", "x", "x2"]; let res: { [key: string]: any } = {}; keys.forEach((k, idx) => { res[k] = group[idx]; }); return res; } // 数据格式 // const dataProps = [ // {value: 14,name:'缺陷1'}, // {value: 20,name:'缺陷2'}, // {value: 22,name:'缺陷3'}, // {value: 14,name:'缺陷4'}, // {value: 30,name:'缺陷5'} // ] let rangArrValue: any[] = []; let dataList: any = []; let totalValue = 0; const colors = [ "rgb(39, 96, 255)", "rgb(91, 155, 255)", "rgb(153, 214, 108)", "rgb(18, 255, 245)", "rgb(221, 177, 18)", ]; const getPersonnelList = async (dataProps: any) => { totalValue = dataProps.reduce( (total: any, value: any) => total + value.value, 0 ); let cacheNum = 0; for (let i = 0; i < dataProps.length; i++) { const endNum = cacheNum + dataProps[i].value; rangArrValue.push([cacheNum, endNum]); cacheNum = endNum; } const angleArr = rangArrValue.map((arr) => arr.map((num: any) => (num / totalValue) * Math.PI * 2) ); dataList = dataProps.map((item: any, index: any) => { const range = getCoordinates(angleArr[index][0], angleArr[index][1]); const startColor = colors[index%5]; const color = { type: "linear", x: range.x, x2: range.x2, y: range.y, y2: range.y2, colorStops: [ { offset: 0, color: startColor, // 起始颜色 }, { offset: 1, color: `${startColor.substring(0, startColor.length - 1)}, 0.2)`, // 终点颜色 }, ], global: false, }; return { name: item.name, value: item.value, itemStyle: { color: color, }, }; }); }; export default function getOptions(dataProps: any) { if (dataProps.length === 0) return null; getPersonnelList(dataProps); return { color: colors, graphic: [ { type: "text", left: "center", top: "44%", style: { text: totalValue, fill: "#fff", width: 150, height: 44, fontSize: 31, fontWeight: 400, }, }, { type: "text", left: "center", top: "55%", style: { text: "总数/件", fill: "rgba(255, 255, 255, 0.70)", width: 32, height: 16, fontSize: 16, fontWeight: 400, }, }, ], series: [ { name: "产线缺陷分类", type: "pie", radius: ["45%", "60%"], center: ["50%", "50%"], // label: { // formatter: "{d}%", // color: "#fff", // }, label:{ formatter:function(params:any){ return `{color${params.dataIndex}|${params.percent}%}\n{style2|${params.name}}` }, rich:{ color0:{color:'rgb(39, 96, 255)',fontSize:22}, color1:{color:'rgb(91, 155, 255)',fontSize:22}, color2:{color:'rgb(153, 214, 108)',fontSize:22}, color3:{color:'rgb(18, 255, 245)',fontSize:22}, color4:{color:'rgb(221, 177, 18)',fontSize:22}, color5:{color:'rgb(39, 96, 255)',fontSize:22}, color6:{color:'rgb(91, 155, 255)',fontSize:22}, color7:{color:'rgb(153, 214, 108)',fontSize:22}, color8:{color:'rgb(18, 255, 245)',fontSize:22}, color9:{color:'rgb(221, 177, 18)',fontSize:22}, style2:{ color:'#fff', fontSize:14 } } }, data: dataList, }, ], }; }