小程序 - 條形圖畫法

效果圖

首先是XML佈局
<!-- 折線圖 -->
<view class="canvas-view">
    <canvas class="canvas" canvas-id="canvasId"></canvas>
</view>

樣式CSS
/* 折線圖 */
.canvas-view {
    height: 100%;
    background: #fff;
    display: flex;
    align-items: center;
    margin-top: 48rpx;
}

.canvas {
    width: 100%;
    height: 640rpx;
}

完整JS代碼
const app = getApp()
Page({
    data: {
        //條形框值
        list: [50, 100, 130, 40, 160, 200, 220, 140, 300, 140],
        h32: 32,
        h64: 64,
        h360: 360,
        h420: 420,
        s28: 28,
        s18: 18,
        //Y軸分成的大分段
        heightLineNum: 7,
        //X軸分成的大分段
        widthLineNum: 10,
        //Y軸一個分段的值
        yOneDuan: 50
    },

    onLoad: function (options) {
        //畫圖
        this.initChart()
    },

    // 初始化條形圖
    initChart: function () {
        const ctx = wx.createCanvasContext('canvasId')

        ctx.beginPath()
        ctx.setStrokeStyle('#999999')
        ctx.setFillStyle('#AAAAAA')
        ctx.setLineWidth(1)

        //座標原點,Y軸座標值從上往下是增加
        const leftBottomX = this.getEleWidth(this.data.h64)
        const leftBottomY = this.getEleWidth(this.data.h360)
        //Y座標
        const leftTopX = this.getEleWidth(this.data.h64)
        const leftTopY = this.getEleWidth(this.data.h32)
        //X座標
        const rightBottomX = this.getEleWidth(this.data.h420)
        const rightBottomY = this.getEleWidth(this.data.h360)

        const yHeight = this.getEleWidth(this.data.h360 - this.data.h32)
        const xWidth = this.getEleWidth(this.data.h420 - this.data.h64)

        //從Y軸座標開始畫座標系
        //Y軸座標到原點座標畫出Y軸線
        //畫完Y軸線,再從原點座標到X軸座標畫出X軸線
        ctx.moveTo(leftTopX, leftTopY)
        ctx.lineTo(leftBottomX, leftBottomY)
        ctx.lineTo(rightBottomX, rightBottomY)
        //設置字體大小
        ctx.setFontSize(this.getEleWidth(this.data.s28))
        //設置字的位置
        ctx.fillText("條形圖", this.getEleWidth(340), this.getEleWidth(32))

        //劃分Y軸
        this.drawYScale(ctx);
        //劃分X軸
        this.drawXScale(ctx);
        //畫條形圖
        this.drawRectScale(ctx);

        ctx.stroke()
        ctx.draw(true)
    },

    //劃分Y軸
    drawYScale: function (ctx) {
        var that = this;

        //Y軸座標刻度橫座標起點
        var scaleStartX = this.getEleWidth(this.data.h64)
        //長的刻度
        var scaleEndX = this.getEleWidth(this.data.h64 + 18)
        //短的刻度
        var littleScaleEndX = this.getEleWidth(this.data.h64 + 9)

        //Y軸刻度總高度
        const yHeight = this.getEleWidth(this.data.h360)
        //一個大分段的長度,一共分爲6段
        var oneScaleX = yHeight / this.data.heightLineNum
        //大分段數字字體大小
        ctx.setFontSize(this.getEleWidth(this.data.s18))
        //大分段數字位置橫座標
        var textX = this.getEleWidth(this.data.h64 - 42)
        //大分段,長刻度:50-300
        for (var i = 1; i < this.data.heightLineNum; i++) {
            var scaleEndY = yHeight - oneScaleX * i
            //畫長刻度線條
            ctx.moveTo(scaleStartX, scaleEndY)
            ctx.lineTo(scaleEndX, scaleEndY)
            ctx.fillText(this.data.yOneDuan * i, textX, scaleEndY + this.getEleWidth(10))
            var littleScaleStartY = yHeight - oneScaleX * (i - 1)
            //小分段,短刻度
            for (var j = 1; j < 5; j++) {
                var littleScaleEndY = littleScaleStartY - (oneScaleX / 5) * j
                //畫短刻度線條
                ctx.moveTo(scaleStartX, littleScaleEndY)
                ctx.lineTo(littleScaleEndX, littleScaleEndY)
                ctx.stroke();
            }
        }
    },

    //劃分X軸
    drawXScale: function (ctx) {
        var that = this;
        //X軸刻度值Y座標
        var scaleStartY = this.getEleWidth(that.data.h360)
        //X軸總長度=X軸橫座標-向右偏移長度
        const xWidth = this.getEleWidth(that.data.h420 - that.data.h64)
        //X軸起始點
        const xMaginLeft = this.getEleWidth(that.data.h64)
        //一個分段的寬度
        const oneScaleX = xWidth / (that.data.widthLineNum + 1)
        for (var i = 0; i < that.data.widthLineNum + 1; i++) {
            var toEndX = xMaginLeft + oneScaleX * i;
            ctx.fillText(i, toEndX - this.getEleWidth(5), scaleStartY + this.getEleWidth(24))
        }
    },

    //畫條形方框
    drawRectScale: function (ctx) {
        var that = this;
        //X軸總長度=X軸橫座標-向右偏移長度
        const xWidth = this.getEleWidth(that.data.h420 - that.data.h64)
        const yHeight = this.getEleWidth(that.data.h360)

        //X軸起始點
        const xMaginLeft = this.getEleWidth(that.data.h64)
        //X座標,一個空格的值
        const oneScaleX = xWidth / (that.data.widthLineNum + 1)
        //Y座標,一個空格的值
        var oneScaleY = yHeight / this.data.heightLineNum

        for (var i = 0; i < that.data.list.length; i++) {
            const currentRect = that.data.list[i];
            //條矩形的寬度
            const rectWidth = oneScaleX / 3 * 2;
            //條矩形的高度
            const rectHeight = currentRect / this.data.yOneDuan * oneScaleY;
            //矩形左上角的x座標和y座標
            const x = xMaginLeft - (oneScaleX - rectWidth) / 2 + oneScaleX * (i + 1);
            const y = yHeight - rectHeight
            //綠色填充
            ctx.setFillStyle('#66FF00')
            //畫框
            ctx.fillRect(x, y, rectWidth, rectHeight);
        }
    },

    //獲取屏幕自適應寬度
    getEleWidth: function (w) {
        var real = 0;
        try {
            var res = wx.getSystemInfoSync().windowWidth;
            //以寬度480px設計做寬度的自適應
            var scale = (480 / 2) / (w / 2);
            real = Math.floor(res / scale);
            return real;
        } catch (e) {
            return false;
        }
    }
})

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章