3D柱状图1
预览图:

import React, { Component } from 'react'; import * as echart from 'echarts'; import { compare } from '@/utils/tools'; import style from './index.less'; /** * 3D柱状图 * @param {string[]} xAxis X轴数据 * @param {string} barColor 柱状颜色 * @param {object[]} barData 柱状数据 * @param {number} barWidth 柱状宽度 * @param {number|number[]} barBorderRadius 柱状圆角 * @param {Object} optionObj * */ class ManyPie extends Component { constructor(props) { super(props); this.chartRef = React.createRef(); } chartRef; chart; componentDidUpdate() { this.init() } componentDidMount() { this.init() } init() { // 基于准备好的dom,初始化echart实例 if (this.chart != null && this.chart != "" && this.chart != undefined) { this.chart.dispose();//解决echarts dom已经加载的报错 } // 基于准备好的dom,初始化echart实例 this.chart = echart.init(this.chartRef.current, null, { devicePixelRatio: 2.5 }); this.chart.clear(); this.setOptions(); window.addEventListener("resize", () => { this.chart.resize(); }); } barColor = ['#41C6E8', '#F5D66E', '#95D171']; barData = [ { x: "Sun", value: 22 }, { x: "Mon", value: 18 }, { x: "Tue", value: 19 }, { x: "Wed", value: 23 }, { x: "Thu", value: 29 } ] setOptions() { const { title = false, subtitle = '', xAxis = this.xAxis, barColor = this.barColor, barWidth = 4, barData = this.barData, barBorderRadius = [10, 10, 0, 0], optionObj = {} } = this.props; const offsetX = 20; const offsetY = 10; let x = []; let y = []; barData.forEach((item, index) => { x.push(item.x) y.push(item.value) }) // 绘制左侧面 const CubeLeft = echart.graphic.extendShape({ shape: { x: 0, y: 0, }, buildPath: function (ctx, shape) { // 会canvas的应该都能看得懂,shape是从custom传入的 const xAxisPoint = shape.xAxisPoint; const c0 = [shape.x, shape.y - 1]; // 右上 const c1 = [shape.x - offsetX + 5, shape.y - offsetY + 2]; // 左上 const c2 = [xAxisPoint[0] - offsetX + 5, xAxisPoint[1] - offsetY + 2]; // 左下 const c3 = [xAxisPoint[0], xAxisPoint[1]]; // 右下 ctx.moveTo(c0[0], c0[1]).lineTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).closePath(); }, }); // 绘制右侧面 const CubeRight = echart.graphic.extendShape({ shape: { x: 0, y: 0, }, buildPath: function (ctx, shape) { const xAxisPoint = shape.xAxisPoint; const c1 = [shape.x, shape.y - 1]; // 左上 const c2 = [xAxisPoint[0], xAxisPoint[1]]; // 左下 const c3 = [xAxisPoint[0] + offsetX - 5, xAxisPoint[1] - offsetY + 2]; // 右下 const c4 = [shape.x + offsetX - 5, shape.y - offsetY + 2]; // 右上 ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath(); }, }); // 绘制顶面 const CubeTop = echart.graphic.extendShape({ shape: { x: 0, y: 0, }, buildPath: function (ctx, shape) { const c1 = [shape.x, shape.y - 1]; // 下点 const c2 = [shape.x + offsetX - 5, shape.y - offsetY + 2]; //右点 const c3 = [shape.x, shape.y - offsetX + 5]; // 上点 const c4 = [shape.x - offsetX + 5, shape.y - offsetY + 2]; // 左点 ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath(); }, }); // 绘制底面 const CubeBottom = echart.graphic.extendShape({ shape: { x: 0, y: 0, }, buildPath: function (ctx, shape) { const xAxisPoint = shape.xAxisPoint; const c1 = [xAxisPoint[0] - offsetX + 5, xAxisPoint[1] - offsetY + 2]; // 左 const c2 = [xAxisPoint[0], xAxisPoint[1]]; // 下 const c3 = [xAxisPoint[0] + offsetX - 5, xAxisPoint[1] - offsetY + 2]; // 右 const c4 = [xAxisPoint[0], xAxisPoint[1] - 16]; // 上 ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath(); }, }); // 注册三个面图形 echart.graphic.registerShape('CubeLeft', CubeLeft); echart.graphic.registerShape('CubeRight', CubeRight); echart.graphic.registerShape('CubeTop', CubeTop); echart.graphic.registerShape('CubeBottom', CubeBottom); var option = { backgroundColor: 'transparent', tooltip: { trigger: 'axis', axisPointer: { type: 'shadow', }, formatter: function (params, ticket, callback) { const item = params[1]; return item.name + ' : ' + item.value; }, }, grid: { left: 0, right: 0, top: '5%', bottom: '5%', containLabel: true, }, xAxis: { type: 'category', data: x, offset: 5, axisLine: { show: true, lineStyle: { width: 2, color: 'rgba(255, 255, 255, 0.2)', }, }, axisTick: { show: false, }, axisLabel: { fontSize: 12, color: 'rgba(255, 255, 255, 1)', fontFamily: 'TengXunZiTi' }, }, yAxis: { type: 'value', axisLine: { show: true, lineStyle: { width: 2, color: 'rgba(255, 255, 255, 0.2)', }, }, splitLine: { show: false }, axisTick: { show: false, }, axisLabel: { fontSize: 12, color: 'rgba(255, 255, 255, 1)', fontFamily: 'TengXunZiTi' }, // boundaryGap: ['20%', '20%'], }, series: [ { type: 'custom', renderItem: (params, api) => { const location = api.coord([api.value(0), api.value(1)]); return { type: 'group', children: [ { type: 'CubeLeft', shape: { api, xValue: api.value(0), yValue: api.value(1), x: location[0], y: location[1], xAxisPoint: api.coord([api.value(0), 0]), }, style: { stroke: new echart.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: 'rgba(38, 206, 255, 0.2)', }, { offset: 1, color: 'rgba(38, 206, 255, 1)', }, ]), fill: new echart.graphic.LinearGradient(0, 0, 0, 0.8, [ { offset: 0, color: 'rgba(2, 107, 138, 0.1)', // color: 'red', }, { offset: 0.6, color: 'rgba(38, 206, 255, 0.3)', // color: 'gold', }, { offset: 1, color: 'rgba(38, 206, 255, 0.7)', // color: 'gold', }, ]), }, }, { type: 'CubeRight', shape: { api, xValue: api.value(0), yValue: api.value(1), x: location[0], y: location[1], xAxisPoint: api.coord([api.value(0), 0]), }, style: { stroke: new echart.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: 'rgba(38, 206, 255, 0.2)', }, { offset: 1, color: 'rgba(38, 206, 255, 1)', }, ]), fill: new echart.graphic.LinearGradient(0, 0, .7, 0.8, [ { offset: 0, color: 'rgba(2, 107, 138, 0.1)', // color: 'red', }, { offset: 0.6, color: 'rgba(38, 206, 255, 0.3)', // color: 'gold', }, { offset: 1, color: 'rgba(38, 206, 255, 0.7)', // color: 'gold', }, ]), }, }, { type: 'CubeTop', shape: { api, xValue: api.value(0), yValue: api.value(1), x: location[0], y: location[1], xAxisPoint: api.coord([api.value(0), 0]), }, style: { fill: new echart.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: 'rgba(5, 150, 193, 1)', }, { offset: 1, color: 'rgba(38, 206, 255, 1)', }, ]), }, }, { type: 'CubeBottom', shape: { api, xValue: api.value(0), yValue: api.value(1), x: location[0], y: location[1], xAxisPoint: api.coord([api.value(0), 0]), }, style: { stroke: 'rgba(105, 213, 243, 0.6)', fill: new echart.graphic.LinearGradient(0, 0, 0.7, 0.4, [ { offset: 0, color: 'rgba(105, 213, 243, 0.28)', }, { offset: 1, color: 'rgba(105, 213, 243, 0.28)', }, ]), }, }, ], }; }, data: y, }, { type: 'bar', label: { normal: { show: false, position: 'top', formatter: (e) => { return e.value + '次'; /*console.log(e) switch (e.name) { case '1001': return e.value; case '1002': return y[1]; case '1003': return y[2]; }*/ }, fontSize: 16, color: '#43C4F1', offset: [0, -25], }, }, itemStyle: { color: 'transparent', }, tooltip: {}, data: y }, ], }; // 绘制图表 this.chart.setOption(option); window.onresize = () => { this.chart.resize(); } } render() { const { width, height } = this.props; return ( <div ref={this.chartRef} style={{ width: width ? width : `100%`, height: height ? height : '100%' }}></div> ) } } export default ManyPie;
参考:http://analysis.datains.cn/finance-admin/index.html#/chartLib/all
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通