uni小程序通过canvas绘制极简横向柱状图
HTML部分
<canvas :style="{height:charHeight}" style="width:100vw;" canvas-id="columnarCanvas" id="columnarCanvas"></canvas>
JS部分
messureCanvas() { let query = uni.createSelectorQuery().in(this); // 然后逐个取出navbar和header的节点信息 // 选择器的语法与jQuery语法相同 query.select('#columnarCanvas').boundingClientRect(); // exec:执行上面所指定的请求,结果会按照顺序存放于一个数组中,在callback的第一个参数中返回 const that = this let canvasInfo = {} query.exec((res) => { // 获取选中元素的宽高 canvasInfo.width = res[0].width canvasInfo.height = res[0].height that.drawColumnar(canvasInfo) }) }, drawColumnar(canvasInfo) { const color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc' ], corlorSub = color const ctxColumnar = uni.createCanvasContext("columnarCanvas") const categories = this.chartDatasBar.categories const seriesData = this.chartDatasBar.series[0].data let maxColumnarValue = 0 //最大值 const distance = 15 //常用间距 let totalValue = 0 //总值 const titleWidth = 60 const width = canvasInfo.width - 20 - 60 //条形可以展示最大的宽 const arr = [] // 计算总数 for (let i = 0; i < categories.length; i++) { totalValue = totalValue + seriesData[i] * 1 //累加总值 } // 按照百分比展示 for (let i = 0; i < categories.length; i++) { arr.push(width * (seriesData[i] * 1 / totalValue).toFixed(5) + '') } // 绘制底部数字 let str = Math.floor(totalValue/5)+'' let num = [] for(let i = 0; i < str.length; i++){ num.push(0) } num[0] = str[0] const baseNum = num.join('')*1 const lineLength = Math.floor(totalValue/baseNum) for(let i = 0; i < lineLength; i++){ if(i==0){ ctxColumnar.fillText(i,titleWidth,(categories.length) * 40+20) } if(i!=0){ ctxColumnar.fillText(baseNum*i,titleWidth+baseNum*i,(categories.length) * 40+20) } } // 绘制网格线 ctxColumnar.fillStyle = '#666666' for(let i = 0; i < totalValue; i++){ if(i%(num[0]*10)==0){ ctxColumnar.fillRect(i+titleWidth,0, 1,(categories.length) * 40) } } // 绘制主体 for (let i = 0; i < categories.length; i++) { if (arr[i] > maxColumnarValue) { maxColumnarValue = arr[i] } ctxColumnar.fillStyle = '#333333' ctxColumnar.font = "12rpx Arial"; if (categories[i]) { ctxColumnar.fillText(categories[i], 20, i * 40 + distance) //要显示的字,x轴y轴 ctxColumnar.fillText(seriesData[i], arr[i] * 1 + titleWidth + 20, i * 40 + distance) //后边显示的值 ctxColumnar.fillStyle = color.concat(corlorSub)[i] ctxColumnar.fillRect(titleWidth, i * 40, arr[i], 20) } } // 绘制底部横线 ctxColumnar.fillStyle = '#333333' ctxColumnar.fillRect(60, (categories.length) * 40, maxColumnarValue*5, 1) setTimeout(() => { ctxColumnar.draw() }, 300) }, clickLeft() { this.$mRouter.reLaunch({ route: this.$store.state.homePage }); },