Home  >  Article  >  Web Front-end  >  canvas dynamic chart

canvas dynamic chart

大家讲道理
大家讲道理Original
2017-05-28 10:42:372542browse

Preface

canvas The powerful functions make it a very important part of HTML5. As for what it is, I don’t need to introduce it here. . Visual charts are one of the manifestations of the powerful functions of canvas.

Now there are many mature chart plug-ins that are implemented using canvas. Chart.js, ECharts, etc. can create beautiful and cool charts, and cover almost all charts. accomplish.

Sometimes I just want to draw a histogram, but it's troublesome to write it myself, and it's cumbersome to use other people's plug-ins. Finally, I open Baidu, copy a piece of code, and paste it in to modify it. You might as well pick one up yourself.

Effect

AnimationEffectPicture cannot be displayed, you can go to the bottom to find the demo address

canvas dynamic chart

Analysis

This chart consists of xy axis, data bar and title.

  • Axis: You can use moveTo() & lineTo() to achieve

  • Text: You can use fillText() to achieve

  • Rectangle: You can use fillRect() to achieve

It seems that it is not that difficult.

Implementation

Definition of canvas


<canvas id="canvas" width="600" height="500"></canvas>


The canvas tag is just a container, which truly realizes drawing. Or JavaScript.

Drawing the coordinate axis

The coordinate axis is two horizontal lines, which is the most basic knowledge in canvas.

  • Start a new path by ctx.beginPath()

  • ctx.lineWidth=1 Set line Width

  • ctx.strokeStyle='#000000' Set the line color

  • ##ctx.moveTo(x,y) Define the starting point of the line

  • ctx.lineTo(x1,y1) defines the end point of the line

  • Finally ctx.stroke() connects the starting point and the end point into a line


var canvas = document.getElementById(&#39;canvas&#39;);var ctx = canvas.getContext(&#39;2d&#39;);var width = canvas.width;var height = canvas.height;var padding = 50;       // 坐标轴到canvas边框的边距,留边距写文字ctx.beginPath();ctx.lineWidth = 1;// y轴线ctx.moveTo(padding + 0.5, height - padding + 0.5);ctx.lineTo(padding + 0.5, padding + 0.5);ctx.stroke();// x轴线ctx.moveTo(padding + 0.5, height - padding + 0.5);ctx.lineTo(width - padding + 0.5, height - padding + 0.5);ctx.stroke();


Draw coordinate points

How many coordinate points on the y-axis are defined by yourself, you need to Get the maximum value of the data to calculate the coordinate value on the y-axis. The x-axis point is determined by the length of the incoming data, and the coordinate value is determined by the xAxis

property of the incoming data.

  • The coordinate value is the text, which is filled with text by ctx.fillText(value, x, y), value is the text value, x y is the coordinate of the value

  • ctx.textAlign='center' Set the text center alignment

  • ctx.fillStyle='#000000' Set the text fill color


var yNumber = 5;                                                // y轴的段数var yLength = Math.floor((height - padding * 2) / yNumber);     // y轴每段的真实长度var xLength = Math.floor((width - padding * 2) / data.length);  // x轴每段的真实长度ctx.beginPath();ctx.textAlign = &#39;center&#39;;ctx.fillStyle = &#39;#000000&#39;;ctx.strokeStyle = &#39;#000000&#39;;// x轴刻度和值for (var i = 0; i < data.length; i++) {
    var xAxis = data[i].xAxis;
    var xlen = xLength * (i + 1);
    ctx.moveTo(padding + xlen, height - padding);
    ctx.lineTo(padding + xlen, height - padding + 5);
    ctx.stroke();                                       // 画轴线上的刻度
    ctx.fillText(xAxis, padding + xlen - xLength / 2, height - padding + 15);   // 填充文字}// y轴刻度和值for (var i = 0; i < yNumber; i++) {
    var y = yFictitious * (i + 1);
    var ylen = yLength * (i + 1);
    ctx.moveTo(padding, height - padding - ylen);
    ctx.lineTo(padding - 5, height - padding - ylen);
    ctx.stroke();
    ctx.fillText(y, padding - 10, height - padding - ylen + 5);}


Column Animation

Next, we need to display the data through the height of the column. There is an animation effect here. The column will rise from 0 to the corresponding value. To implement animation on canvas we can use

setInterval, setTimeout and requestAnimationFrame.

requestAnimationFrame does not need to set the timing time yourself, but follows the drawing of the browser. This way there will be no frame drops and it will be smooth naturally.

requestAnimationFrame originally only supported IE10 and above, but it can be compatible with IE6 through compatible writing methods.


function looping() {
    looped = requestAnimationFrame(looping);
    if(current < 100){      
    // current 用来计算当前柱状的高度占最终高度的百分之几,通过不断循环实现柱状上升的动画
        current = (current + 3) > 100 ? 100 : (current + 3);
        drawAnimation();
    }else{
        window.cancelAnimationFrame(looped);
        looped = null;
    }}function drawAnimation() {
    for(var i = 0; i < data.length; i++) {
        var x = Math.ceil(data[i].value * current / 100 * yRatio);
        var y = height - padding - x;
        ctx.fillRect(padding + xLength * (i + 0.25), y, xLength/2, x);
        // 保存每个柱状的信息
        data[i].left = padding + xLength / 4 + xLength * i;
        data[i].top = y;
        data[i].right = padding + 3 * xLength / 4 + xLength * i;
        data[i].bottom = height - padding;
    }}looping();


  • Column is to draw a rectangle, by ctx.fillRect(x, y, width, height) Implementation, x y is the coordinate of the upper left corner of the rectangle, width height is the width and height of the rectangle, the unit is pixels

  • ctx.fillStyle='#1E9FFF' Set the fill color

At this point, a basic histogram is completed. Next, we can add a title for him.

Title

To place the title, you will find that the padding

Padding we defined early in the morning is really useful. You can’t cover the title on the histogram. . But some titles are at the top and some are at the bottom, so they cannot be written to death. Set a variable position to determine the position and draw it. This one is simple.


// 标题if(title){                      // 也不一定有标题
    ctx.textAlign = &#39;center&#39;;
    ctx.fillStyle = &#39;#000000&#39;;  // 颜色,也可以不用写死,个性化嘛
    ctx.font = &#39;16px Microsoft YaHei&#39;
    if(titlePosition === &#39;bottom&#39; && padding >= 40){
        ctx.fillText(title,width/2,height-5)    }else{
        ctx.fillText(title,width/2,padding/2)    }}


Listen to mouse movement

Event

We see that in some charts, move the mouse When you move it up, the current column changes color, and when you move it it changes back to its original color. Here you need to listen to the mouseover event. When the mouse position is within the columnar area, the event is triggered.

那我怎么知道在柱状里啊,发现在 drawAnimation() 里会有每个柱状的坐标,那我干脆把坐标给保存到 data 里。那么鼠标在柱状里的条件应该是:

  • ev.offsetX > data[i].left

  • ev.offsetX

  • ev.offsetY > data[i].top

  • ev.offsetY


canvas.addEventListener(&#39;mousemove&#39;,function(ev){
    var ev = ev||window.event;
    for (var i=0;i<data.length;i++){
    for (var i=0;i<data.length;i++){
        if(ev.offsetX > data[i].left &&
        ev.offsetX < data[i].right &&
        ev.offsetY > data[i].top &&
        ev.offsetY < data[i].bottom){
            console.log(&#39;我在第&#39;+i+&#39;个柱状里。&#39;);
        }
    }})


总结

为了更方便的使用,封装成构造函数。通过

var chart = new sBarChart('canvas',data,{
    title: 'xxx公司年度盈利',   // 标题
    titleColor: '#000000',      // 标题颜色
    titlePosition: 'top',       // 标题位置
    bgColor: '#ffffff',         // 背景色
    fillColor: '#1E9FFF',       // 柱状填充色
    axisColor: '#666666',       // 坐标轴颜色
    contentColor: '#a5f0f6'     // 内容横线颜色
});

参数可配置,很简单就生成一个个性化的柱状图。代码地址:canvas-demo

最后加上折线图、饼图、环形图,完整封装成sChart.js插件,插件地址:sChart.js

The above is the detailed content of canvas dynamic chart. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn