金子塔图,自定义图表,伪漏斗图
简易的金字塔图,设置不太灵活,可供使用者参考,需要使用者根据页面的需求复杂度等再做修改。
另附链接地址:https://www.isqqw.com/pcenter?userid=6427
// 原始数据 let data = [ { name: '测试数据', value: 4 }, { name: '测试原理', value: 2 }, { name: '测试功能', value: 8 }, ] // 将数据根据从小到大排序 let newdata = sortObject(data); // 图例数据 let lengthData = []; // 返回数据 let resultData = data.map((item, index) => { let graw = item.value > 9 ? 78 : 83; 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: '#fff', fontSize: 14, x: 10, y: 2 } }, { type: 'text', name: item.name, style: { text: item.value, fill: '#fff', fontSize: 17, x: 70, y: 0 } }, { type: 'text', style: { text: '个', fill: '#fff', fontSize: 14, x: graw, y: 2 } } ] }); if (index === 0) { return { style: { fill: new echarts.graphic.LinearGradient(0, 0, 1, 0, [ { offset: 0, color: '#07a9ab' }, { offset: 1, color: '#09fffb' } ]) }, ...item }; } else if (index === 1) { return { style: { fill: new echarts.graphic.LinearGradient(0, 0, 1, 0, [ { offset: 0, color: '#025279' }, { offset: 1, color: '#16a7ef' } ]) }, ...item }; } else { return { style: { fill: new echarts.graphic.LinearGradient(0, 0, 1, 0, [ { offset: 0, color: '#0332a9' }, { offset: 1, color: '#0847e7' } ]) }, ...item }; } }); // 获取计算的数据 let getData = pyramidChart( resultData, document.getElementById('container') ); option = { backgroundColor: '#022c32', graphic: [ { type: 'group', left: '5%', top: 'center', scale: [1, 1], onclick: function (params) { }, children: getData }, { type: 'group', left: '55%', 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 : 0; let domWidth = dom ? dom.clientWidth : 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 = 50; } if (data.length === 2) { resultOption.slanted = 25; } if (data.length === 3) { resultOption.slanted = 10; } // 减去多余的误差边距 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; };
标签:塔图,index,resultOption,自定义,item,triangleHeightLayerOne,let,漏斗,slanted From: https://www.cnblogs.com/wangyongping/p/17039499.html