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
                });
            },

 

posted @ 2021-11-23 14:41  朱依漾  阅读(490)  评论(0编辑  收藏  举报