// 原始数据 let data = [ { name: "测试数据", value: 4 }, { name: "测试原理", value: 2 }, { name: "测试功能", value: 8 }, { name: "测试功能1", value: 10 }, { name: "测试功能2", value: 6 }, ]; // 将数据根据从小到大排序 let newdata = sortObject(data); // 图例数据 let lengthData = []; // 返回数据 let resultData = data.map((item, index) => { let graw = 100; lengthData.push({ type: "group", top: index * 25, scale: [1, 1], children: [ { type: "circle", shape: { cx: 0, cy: 7, r: 5, }, style: { fill: index === 0 ? "#07a9ab" : index === 1 ? "#008CD2" : "#0847e7", }, }, { type: "text", style: { text: item.name, fill: "#ccc", fontSize: 14, x: 10, y: 2, }, }, { type: "text", name: item.name, style: { text: item.value, fill: "#ccc", fontSize: 17, x: 80, y: 0, }, }, { type: "text", style: { text: "个", fill: "#ccc", fontSize: 14, x: graw, y: 2, }, }, ], }); if (index === 0) { return { style: { fill: "#37CCCA", }, ...item, }; } else if (index === 1) { return { style: { fill: "#34A6BF", }, ...item, }; } else if (index === 2) { return { style: { fill: "#307AB3", }, ...item, }; } else if (index === 3) { return { style: { fill: "#2E54A9", }, ...item, }; } else if (index === 4) { return { style: { fill: "#2E43A9", }, ...item, }; } }); // 获取计算的数据 let getData = pyramidChart(resultData, document.getElementById("container")); option = { backgroundColor:"#000", tooltip: {}, graphic: [ { type: "group", left: "5%", top: "center", scale: [1, 1], onclick: function (params) {}, children: getData, }, { type: "group", left: "50%", top: "center", scale: [1, 1], onclick: function (params) {}, children: lengthData, }, ], series: [], }; // 排序 function sortObject(arr) { return arr.sort(function (a, b) { return a["value"] - b["value"]; }); } // 数据处理 function pyramidChart(data = [], dom, option = {}) { let domHeight = dom ? dom.clientHeight - 40 : 0; let domWidth = dom ? dom.clientWidth - 40 : 0; // 默认获取一个正方形空间 let maxDistance = domHeight > domWidth / 2 ? domWidth / 2 : domHeight; // 合并设置 let resultOption = Object.assign( { slanted: 1, // 每层底部的倾斜度 maxWidth: maxDistance, // 金字塔最大宽度 maxHeight: maxDistance, // 金字塔最大高度 offset: 35, //偏差 }, option ); if (data.length === 1) { resultOption.slanted = 40; } if (data.length === 2) { resultOption.slanted = 25; } if (data.length === 3) { resultOption.slanted = 15; } if (data.length === 4) { resultOption.slanted = 10; } if (data.length === 5) { resultOption.slanted = 6; } // 减去多余的误差边距 resultOption.maxHeight = resultOption.maxHeight - resultOption.offset; // 一半最大宽度,用于计算左右边距 let halfMaxWidth = resultOption.maxWidth / 2; // 数据最终 let resultData = []; // 数据值 数组 let dataNums = data.map((item) => item.value || 0); // 计算数据总和 let dataNumSum = dataNums.length > 0 && dataNums.reduce(function (prev, curr) { return Number(prev || 0) + Number(curr || 0); }); // 中间数据点坐标数组 根据长度比值算出 let midlinePoint = []; let multipleLayer = [0.6]; // 计算倍数等基础数据 dataNums.forEach((item, index, arr) => { let itemNext = arr[index + 1]; if (itemNext) { multipleLayer.push(itemNext / dataNums[0]); // 计算倍数 } // 计算点坐标 长度 let point = Math.round((item / dataNumSum) * resultOption.maxHeight * 1000) / 1000; midlinePoint.push(point); }); // 三角形的高度 let triangleHeight = 0; let triangleHeightLayer = []; // 三角形tan角度 let triangleRatio = halfMaxWidth / resultOption.maxHeight; midlinePoint.forEach((item) => { triangleHeight = triangleHeight + item; triangleHeightLayer.push(triangleHeight); }); // 中间数据点 最后的数据长度 let midlinePointFinally = triangleHeightLayer[triangleHeightLayer.length - 1] || 0; // 开始拼接数据 data.forEach((item, index) => { let arrObj = []; let triangleHeightLayerOne = triangleHeightLayer[index]; let triangleHeightLayerOneLast = triangleHeightLayer[index - 1] || 0; let multipleLayerOne = multipleLayer[index]; let multipleLayerOneLast = multipleLayer[index - 1] || 0; // 第一层数据单独处理 if (index === 0) { arrObj.push( [0, 0], [ -triangleRatio * (triangleHeightLayerOne - resultOption.slanted * multipleLayerOne), triangleHeightLayerOne - resultOption.slanted * multipleLayerOne, ], [0, triangleHeightLayerOne], [ triangleRatio * (triangleHeightLayerOne - resultOption.slanted * multipleLayerOne), triangleHeightLayerOne - resultOption.slanted * multipleLayerOne, ] ); } else { arrObj.push( [0, triangleHeightLayerOneLast], [ -triangleRatio * (triangleHeightLayerOneLast - resultOption.slanted * multipleLayerOneLast), triangleHeightLayerOneLast - resultOption.slanted * multipleLayerOneLast, ], [ -triangleRatio * (triangleHeightLayerOne - resultOption.slanted * multipleLayerOne), triangleHeightLayerOne - resultOption.slanted * multipleLayerOne, ], [0, triangleHeightLayerOne], [ triangleRatio * (triangleHeightLayerOne - resultOption.slanted * multipleLayerOne), triangleHeightLayerOne - resultOption.slanted * multipleLayerOne, ], [ triangleRatio * (triangleHeightLayerOneLast - resultOption.slanted * multipleLayerOneLast), triangleHeightLayerOneLast - resultOption.slanted * multipleLayerOneLast, ] ); } resultData.push({ type: "polygon", z: 1, shape: { points: arrObj, }, name: item.name, style: item.style, }); }); // 添加线 resultData.push({ type: "polyline", shape: { points: [ [0, 0], [0, midlinePointFinally], ], }, style: { stroke: "#f2f2f2", opacity: 0.2, lineWidth: 1, }, z: 2, }); // 返回 return resultData; }