const LinearGradientColor = { 0: { left: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: '#87F4FD', }, { offset: 1, color: '#67A8FF', }, ]), right: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: '#6AC3CB', }, { offset: 1, color: '#5280BF', }, ]), top: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: '#87F4FD', }, { offset: 0.5, color: '#69ACFF', }, { offset: 1, color: '#67A8FF', }, ]), }, 1: { left: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: '#A5DDE1', }, { offset: 1, color: '#FFFFFF', }, ]), right: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: '#A5DDE1', }, { offset: 1, color: '#FFFFFF', }, ]), top: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: '#A5DDE1', }, // { // offset: 0.5, // color: '#69ACFF', // }, { offset: 1, color: '#FFFFFF', }, ]), }, 2: { left: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: '#FFBD0A', }, { offset: 1, color: '#9F7503', }, ]), right: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: '#FFBD0A', }, { offset: 1, color: '#9F7503', }, ]), top: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: '#FFE6A4', }, { offset: 1, color: '#FFBD0A', }, ]), }, } const offsetX = 10 // 10 面宽度 const offsetY = 5 // 5 倾斜度 const offsetYY = 10 // 柱形整体下移距离 // 绘制左侧面 const CubeLeft = echarts.graphic.extendShape({ shape: { x: 0, y: 0, }, buildPath: function (ctx, shape) { const xAxisPoint = shape.xAxisPoint const yBase = shape.yBase const c0 = [shape.x, shape.y + yBase] // t-r const c1 = [shape.x - offsetX, shape.y - offsetY + yBase] // t-l const c2 = [xAxisPoint[0] - offsetX, xAxisPoint[1] - offsetY + yBase] // b-l const c3 = [xAxisPoint[0], xAxisPoint[1] + yBase] // b-r ctx.moveTo(c0[0], c0[1]).lineTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).closePath() }, }) // 绘制右侧面 const CubeRight = echarts.graphic.extendShape({ shape: { x: 0, y: 0, }, buildPath: function (ctx, shape) { const xAxisPoint = shape.xAxisPoint const yBase = shape.yBase const c1 = [shape.x, shape.y + yBase] const c2 = [xAxisPoint[0], xAxisPoint[1] + yBase] const c3 = [xAxisPoint[0] + offsetX, xAxisPoint[1] - offsetY + yBase] const c4 = [shape.x + offsetX, shape.y - offsetY + yBase] ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath() }, }) // 绘制顶面 const CubeTop = echarts.graphic.extendShape({ shape: { x: 0, y: 0, }, buildPath: function (ctx, shape) { if (shape.yValue == 0) return const yBase = shape.yBase const c1 = [shape.x, shape.y + yBase] const c2 = [shape.x + offsetX, shape.y - offsetY + yBase] //右点 const c3 = [shape.x, shape.y - offsetX + yBase] const c4 = [shape.x - offsetX, shape.y - offsetY + yBase] ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath() }, }) // 注册三个面图形 echarts.graphic.registerShape('CubeLeft', CubeLeft) echarts.graphic.registerShape('CubeRight', CubeRight) echarts.graphic.registerShape('CubeTop', CubeTop) // 计算叠加绘制高度值 const calcSuperpositionVal = (params, api, yData) => { const currentSeriesIndices = api.currentSeriesIndices() const seriesIndex = params.seriesIndex if (seriesIndex == 0 || currentSeriesIndices.length == 1 || currentSeriesIndices[0] === seriesIndex) return offsetYY const dataIndex = params.dataIndex const seriesData = yData.map(x => x[dataIndex]) const yBaseNum = currentSeriesIndices.reduce((pre, cur) => { if (cur < seriesIndex) { pre = pre + seriesData[cur] } return pre }, 0) const chazhi = api.coord([0, yBaseNum])[1] - api.coord([0, 0])[1] + offsetYY return params.seriesIndex > 0 ? chazhi : offsetYY } const axisColor = 'rgba(211,228,242,0.6)' const markTextColor = '#D3E4F2' const splitLineColor = 'rgba(211,228,242,0.16)' const marks = [ { name: '已消缺', color: '#68BEFE' }, { name: '已忽略', color: '#DDFDFF' }, { name: '未消缺', color: '#FFBD0A' }, ] const arr = [ { wxqslY: 0, x: '0', xStr: '#1主变', yxqslY: 1, yhlslY: 5 }, { wxqslY: 1, x: '1', xStr: '110kV断路器', yxqslY: 0, yhlslY: 6 }, { wxqslY: 5, x: '2', xStr: '35kV断路器', yxqslY: 5, yhlslY: 5 }, { wxqslY: 3, x: '3', xStr: '10kV断路器', yxqslY: 1, yhlslY: 5 }, ] const x = [], y = [[], [], []] for (const i of arr) { x.push(i.xStr) y[0].push(i.yxqslY) // 已消缺数量 y[1].push(i.yhlslY) // 已忽略数量 y[2].push(i.wxqslY) // 未消缺数量 } option = { title: { left: '2%', top: '-8%', subtext: '台', subtextStyle: { fontSize: 14, color: axisColor, }, }, grid: { show: true, left: '2%', bottom: '8%', top: '16%', right: 0, borderWidth: 0, backgroundColor: '#081532', containLabel: true, // 不支持渐变 // backgroundColor: 'linear-gradient(to top, rgba(46,124,255,0.3), rgb(235,243,250,0.1))', }, legend: { show: true, top: 0, right: 0, itemWidth: 8, itemHeight: 8, itemGap: 14, icon: 'circle', textStyle: { color: markTextColor, fontSize: 14, }, data: marks.map(i => { return { name: i.name, itemStyle: { color: i.color }, } }), }, tooltip: { trigger: 'axis', }, xAxis: { type: 'category', data: x, axisLabel: { color: axisColor, fontSize: 14, margin: 15, interval: 0, }, axisTick: { show: false, }, }, yAxis: { type: 'value', axisLabel: { color: axisColor, fontSize: 14, margin: 14, }, axisLine: { show: true, lineStyle: { color: splitLineColor, }, }, min: 0, minInterval: 1, splitLine: { lineStyle: { color: splitLineColor, }, }, }, series: marks.map((i, j) => { return { type: 'custom', name: i.name, stack: 'Ad', color: i.color, // emphasis: { // focus: 'series' // }, renderItem: (params, api) => { const location = api.coord([api.value(0), api.value(1)]) const yBase = calcSuperpositionVal(params, api, y) const xAxisPoint = api.coord([api.value(0), 0]) return { type: 'group', children: [ { type: 'CubeLeft', shape: { api, params, x: location[0], y: location[1], xAxisPoint, yBase, }, style: { fill: LinearGradientColor[params.seriesIndex].left, }, }, { type: 'CubeRight', shape: { api, x: location[0], y: location[1], xAxisPoint, yBase, }, style: { fill: LinearGradientColor[params.seriesIndex].right, }, }, { type: 'CubeTop', shape: { api, yValue: api.value(1), x: location[0], y: location[1], xAxisPoint, yBase, }, style: { fill: LinearGradientColor[params.seriesIndex].top, }, }, ], } }, data: y[j], } }), };