JS代码实现使用canvas生成colorBar图表

最近因为工作原因,需要制作一个color bar的图表控件,网上百度了下,没有相关的源码,只能自己开发一个。

设计需求的colorBar样式如下图:

JS代码实现使用canvas生成colorBar图表_第1张图片

JS代码实现使用canvas生成colorBar图表_第2张图片

三角箭头所在是临界值,临界值数值使用灰色颜色标识在箭头下方,绿色或黄色或红色箭头表示当前值,数值标识在箭头上方。

使用canvas原生开发了一个

1、首先要创建一个canvas,如下:

2、创建colorBar的代码:

        /**
         * COLORBAR
         * @param {*} id canvas的ID
         * @param {*} val   当前值
         * @param {*} bValArr [2,5,9,12]    临界值数组,从小到大排序
         */
        function drawColorBar(id, val, bValArr) {

            let canvas = document.getElementById(id);
            let ctx = canvas.getContext('2d');
            let x = 100;    //colorBar在canvas里位置
            let y = 100;
            let w = 400;    //colorBar宽度
            let h = 40;     //高度

            // 以下代码解决字体模糊问题
            const ratio = getPixelRatio(ctx)
            canvas.style.width = canvas.width + 'px'
            canvas.style.height = canvas.height + 'px'
            canvas.width = canvas.width * ratio
            canvas.height = canvas.height * ratio
            ctx.scale(ratio, ratio)

            let num = bValArr.length;//临界值数量
            let len0 = Math.max(bValArr[num-1], Math.abs(val)) + bValArr[0];
            let len = len0 * 2;
            let arrowArr = [];
            let newVal = 0;
            for(let i = 0; i < num; i++){
                arrowArr.push(x + (len0 + bValArr[i]) * w / len);
                arrowArr.push(x + (len0 - bValArr[i]) * w / len);
            }
            if(val > 0){
                newVal = x + (len0 + Math.abs(val)) * w / len;
            }else{
                newVal = x + (len0 - Math.abs(val)) * w / len;
            }

            //当前值箭头颜色
            let color = 'green';  //范围内是绿色
            const defaultColor = '#666';
            if (Math.abs(val) > bValArr[num-1]) {
                color = '#ee6666';  //红色
            } else {
                if (Math.abs(val) > bValArr[0]) {
                    color = '#ff9901';  //黄色
                }
            }
            // 渐变色
            let my_gradient = ctx.createLinearGradient(x, y, x + w, y)
            my_gradient.addColorStop(0, '#ee6666')
            my_gradient.addColorStop((arrowArr[1] - x) / w / 2, '#fac858')
            my_gradient.addColorStop((arrowArr[1] - x) / w, '#91cc75')
            my_gradient.addColorStop(0.5, '#91cc75')
            my_gradient.addColorStop((arrowArr[0] - x) / w, '#91cc75')
            my_gradient.addColorStop(1 - (arrowArr[1] - x) / w / 2, '#fac858')
            my_gradient.addColorStop(1, '#ee6666')
            ctx.fillStyle = my_gradient
            // 绘制矩形
            ctx.fillRect(x, y, w, h)
            // 边框
            ctx.strokeStyle = defaultColor
            ctx.rect(x, y, w, h)
            ctx.stroke();

            for(let i = 0,l = arrowArr.length; i < l; i++){
                // 绘制矩形上面向下箭头
                drawColorBarArrow(ctx, arrowArr[i], y, 0, defaultColor)
                // 绘制矩形下面向上箭头
                let text = bValArr[parseInt(Math.floor(i/2))];
                if(arrowArr[i] < x + w / 2){
                    text = -text;
                }
                drawColorBarArrow(ctx, arrowArr[i], y + h, 1, defaultColor, text)
            }
            drawColorBarArrow(ctx, newVal, y, 0, color, val)
        }

3、创建箭头的方法:

        /**
         * 三角箭头
         * @param {*} ctx
         * @param {*} x 位置
         * @param {*} y 
         * @param {*} up 0=位于上方,1=下方
         * @param {*} color 颜色数值
         * @param {*} text 显示数字文字
         */
        function drawColorBarArrow(ctx, x, y, up, color, text){
            ctx.beginPath();
            ctx.moveTo(x, y);
            let newY, textY, textX;
            let fontSize = 12;
            if(up){
                newY = y + 16;
                textY = y + fontSize * 3;
            }else{
                newY = y - 16;
                textY = y - fontSize * 2;
            }
            ctx.lineTo(x - 8, newY);
            ctx.lineTo(x + 8, newY);
            ctx.fillStyle = color;
            ctx.fill();
            if(text){
                if(typeof text != 'string'){
                    text = text.toString();
                }
                ctx.font = "normal normal 500 " + fontSize + "px sans-serif";
                if(color == "#666")ctx.fillStyle = "black";
                textX = x - text.length / 4 * fontSize;
                ctx.fillText(text, textX, textY);
            }
        }

4、因为屏幕显示分辨率问题导致字体模糊,需要获取显示器和图像实际分辨率的比率:

        function getPixelRatio(ctx) {
            let backingStore = ctx.backingStorePixelRatio ||
            ctx.webkitBackingStorePixelRatio ||
            ctx.mozBackingStorePixelRatio ||
            ctx.msBackingStorePixelRatio ||
            ctx.oBackingStorePixelRatio ||
            ctx.backingStorePixelRatio || 1;
            return (window.devicePixelRatio || 1) / backingStore;
        };

5、最后输入参数调用方法后得到的结果图形:

drawColorBar('canvas', 19.86, [4,9.5,15]);

JS代码实现使用canvas生成colorBar图表_第3张图片

 6、DEMO地址访问:

你可能感兴趣的:(JS,HTML/CSS,javascript,canvas,color,bar,html5)