canvas+js绘制简单能力图

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <canvas id="canvas"></canvas>
    <script>
        window.onload = function() {
            const canvas = document.querySelector("#canvas");
            const context = canvas.getContext('2d');
            canvas.width = 400;
            canvas.height = 400;

            const ORIGIN_X = 200; // 原点横坐标
            const ORIGIN_Y = 200; // 原点纵坐标
            const BG_STROKE_COLOR = "rgb(121,121,121)"; // 背景填充的颜色连线的颜色
            const BG_FILL_COLOR = "rgb(242,242,242)"; // 背景
            const RADIUS = 56; // 图形的最外层半径
            const RING_NUMS = 4; // 图形的环数
            const FULL_VALUE = 100; // 数据的满值
            const FONT_COLOR = "rgb(121,121,121)"; // 文字颜色
            const POWER_BG_COLOR = "rgba(0,121,121,.4)"; // 能力图背景填充颜色
            const POWER_POINT_COLOR = "rgb(0,121,121)"; // 能力图点的颜色
            const POWER_STROKE_COLOR = "rgb(0,121,121)"; // 能力图连线的颜色

            let data = [{
                name: "javascript",
                value: 90
            }, {
                name: "html",
                value: 86
            }, {
                name: "css",
                value: 88
            }, {
                name: "计算机网络",
                value: 79
            }, {
                name: "算法",
                value: 85
            }]

            // 绘制环形背景  参数为环形中心横坐标,纵坐标,环形最外层半径,环数,数据,线条颜色,填充颜色
            CanvasRenderingContext2D.prototype.drawRing = function(x, y, r, ringNum, data, strokeColor = "rgba(0,0,0)", fillColor = "rgb(242,242,242)") {
                const PER_RADIUS = r / ringNum;
                for (let i = ringNum; i > 0; i--) {
                    this.beginPath();
                    this.strokeStyle = strokeColor;
                    if (i % 2 === 0) {
                        this.arc(x, y, PER_RADIUS * i, 0, 2 * Math.PI);
                        this.fillStyle = "rgb(255,255,255)";
                        this.stroke();
                        this.fill();
                    } else {
                        this.arc(x, y, PER_RADIUS * i, 0, 2 * Math.PI);
                        this.fillStyle = fillColor;
                        this.stroke();
                        this.fill();
                    }
                    this.closePath();
                }
                const PER_ANGLE = 2 * Math.PI / data.length;
                for (let i = 0; i < data.length; i++) {
                    this.beginPath();
                    this.strokeStyle = strokeColor;
                    this.moveTo(x, y);
                    this.lineTo(x + r * Math.sin(PER_ANGLE * i), y - r * Math.cos(PER_ANGLE * i));
                    this.stroke();
                    this.closePath();
                }
            }

            // 绘制能力形状  参数为环形中心横坐标,纵坐标,环形最外层半径,数据,能力图线条颜色,能力图填充颜色,能力图点颜色,满值
            CanvasRenderingContext2D.prototype.drawPowerShape = function(x, y, r, data, strokeColor, fillColor, pointColor, fullValue = FULL_VALUE) {
                if (!data || data.length < 3) {
                    throw new Error("An array with a length of more than 3 should be passed as the parameter")
                }
                this.beginPath();
                const PER_ANGLE = 2 * Math.PI / data.length;
                for (let i = 0; i < data.length; i++) {
                    const DATA_RADIUS = data[i].value / fullValue * r;
                    new Promise(resolve => {
                        this.lineTo(x + DATA_RADIUS * Math.sin(PER_ANGLE * i), y - DATA_RADIUS * Math.cos(PER_ANGLE * i))
                        resolve(DATA_RADIUS);
                    }).then(radius => { // 通过promise异步保证点的绘制在能力图背景的绘制之后
                        this.beginPath();
                        this.arc(x + radius * Math.sin(PER_ANGLE * i), y - radius * Math.cos(PER_ANGLE * i), 3, 0, Math.PI * 2);
                        this.fillStyle = pointColor;
                        this.fill();
                        this.closePath();
                    })
                }
                this.lineTo(x, y - data[0].value / fullValue * r)
                this.fillStyle = fillColor;
                this.strokeColor = strokeColor;
                this.fill();
                this.stroke();
                this.closePath();
            }

            // 绘制文字  参数为环形中心横坐标,纵坐标,文字绘制起点所在圆半径,数据,文字颜色
            CanvasRenderingContext2D.prototype.drawText = function(x, y, r, data, fontColor = "rgb(121,121,121)") {
                if (!data || data.length < 3) {
                    throw new Error("An array with a length of more than 3 should be passed as the parameter")
                }
                const PER_ANGLE = 2 * Math.PI / data.length;
                this.fillStyle = fontColor
                for (let i = 0; i < data.length; i++) {
                    this.beginPath();
                    this.textAlign = "center";
                    this.textBaseline = "middle";
                    this.font = "10px Adobe Ming Std";
                    this.fillText(data[i].name, x + r * Math.sin(PER_ANGLE * i), y - r * Math.cos(PER_ANGLE * i));
                    this.fill();
                    this.closePath();
                }
            }

            context.drawRing(ORIGIN_X, ORIGIN_Y, RADIUS, RING_NUMS, data, BG_STROKE_COLOR, BG_FILL_COLOR);
            context.drawPowerShape(ORIGIN_X, ORIGIN_Y, RADIUS, data, POWER_STROKE_COLOR, POWER_BG_COLOR, POWER_POINT_COLOR);
            context.drawText(ORIGIN_X, ORIGIN_Y, RADIUS + 20, data, FONT_COLOR)
        }
    </script>
</body>

</html>

只要修改data数据和相应的颜色就可以修改能力图了,上面例子效果如下
在这里插入图片描述

发布了195 篇原创文章 · 获赞 14 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/zemprogram/article/details/104117037