>웹 프론트엔드 >H5 튜토리얼 >캔버스 동적 차트

캔버스 동적 차트

大家讲道理
大家讲道理원래의
2017-05-28 10:42:372578검색

머리말

canvas 강력한 기능은 HTML5의 매우 중요한 부분이므로 여기서 소개할 필요가 없습니다. 시각적 차트는 캔버스의 강력한 기능을 표현하는 것 중 하나입니다.

이제 캔버스를 사용하여 구현되는 성숙한 차트 플러그인이 많이 있습니다.js, ECharts 등은 아름답고 멋진 차트를 만들고 거의 모든 차트 구현을 다룰 수 있습니다.

가끔 그냥 히스토그램을 그리고 싶은데 직접 작성하기도 귀찮고, 남의 플러그인을 사용하기도 귀찮고, 드디어 바이두를 열고 코드 한 조각을 복사해서 붙여넣어 수정합니다. 당신이 직접 하나를 선택할 수도 있습니다.

Effect

AnimationEffectPicture을 표시할 수 없습니다. 하단으로 이동하여 데모 주소

캔버스 동적 차트

Analytics

를 확인하세요. 이 차트는 xy축, 데이터 막대, 제목으로 구성되어 있습니다.

  • Axis: moveTo() & lineTo()를 사용하여

  • Text: fillText()를 사용하여

  • Rectangle: fillRect()를 사용하여

을 구현할 수 있습니다. 그렇지 않은 것 같지만 그리 어렵지는 않습니다.

Implementation

define canvas


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


canvas 태그는 단지 컨테이너일 뿐이며 그리기의 실제 구현은 JavaScript입니다.

좌표축 그리기

좌표축은 두 개의 수평선으로 캔버스에 있어서 가장 기본적인 지식입니다. E ctx.beginpath()에서 새 경로 시작

  • CTX.LI

    New
  • Idth = 1 선 너비 설정
  • CTX.Strokestyle = '#000000' 선 색상 설정

  • ctx.moveTo( x,y)는 선의 시작점을 정의합니다

  • ctx.lineTo(x1,y1)는 선의 끝점을 정의합니다

  • 마지막으로 ctx.Stroke()는 시작점과 끝점을 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();


좌표점 그리기


y축 좌표값을 직접 정의하려면 데이터의 최대값을 구해야 합니다. 중심선. x축 지점은 들어오는 데이터의 길이에 따라 결정되고, 좌표 값은 들어오는 데이터의 xAxis

속성

에 의해 결정됩니다.

좌표 값은 ctx.fillText(value, x, y)로 텍스트로 채워진 텍스트이고, value는 텍스트 값, x y는 값의 좌표입니다.

  • ctx.textAlign='center' 텍스트 중앙 정렬 설정

  • ctx.fillStyle='#000000' 텍스트 채우기 색상 설정

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


열 애니메이션


다음으로, 높이를 통해 데이터를 표시해야 합니다. 여기에는 애니메이션 효과가 있습니다. 열은 0 상승에서 해당 값으로 변경됩니다. 캔버스에 애니메이션을 구현하려면

set

Interval, set

Time

out 및 requestAnimationFrame을 사용할 수 있습니다. requestAnimationFrame은 타이밍 시간을 직접 설정할 필요가 없으며 브라우저의 그림을 따릅니다. 이렇게 하면 프레임 드랍이 발생하지 않고 자연스럽게 매끄러워집니다. requestAnimationFrame은 원래 IE10 이상만 지원했지만 호환 가능한 작성 방법을 통해 IE6과도 호환될 수 있습니다.


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();



Cylinder는 직사각형을 그리는 것인데, 이는 ctx.fillRect(x, y, width, height)로 구현됩니다. x y는 직사각형의 왼쪽 위 모서리 좌표, 너비 높이입니다. 는 직사각형의 너비와 높이, 단위는 픽셀입니다.

    ctx.fillStyle='#1E9FFF' 채우기 색상 설정
  • 이제 기본 히스토그램이 완성됩니다. 다음으로 제목을 추가할 수 있습니다.
  • Title

  • 제목을 배치하려면 아침 일찍 정의한 패딩
inner margin

이 정말 유용하다는 것을 알게 될 것입니다. 히스토그램에서는 제목을 가릴 수 없습니다. 그런데 어떤 제목은 위쪽에 있고 어떤 제목은 아래쪽에 있어서 죽을 지경으로 쓸 수가 없습니다.

변수

position

을 설정하여 위치를 결정하고 그려줍니다. 이것은 간단합니다.

// 标题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)    }}

마우스 움직임 듣기
events


일부 차트에서는 마우스를 위로 올리면 현재 열의 색이 바뀌고, 마우스를 움직이면 다시 원래 색으로 돌아오는 것을 볼 수 있습니다. . 여기서 마우스 오버 이벤트를 수신해야 합니다. 마우스 위치가 기둥 영역 내에 있으면 이벤트가 트리거됩니다.

那我怎么知道在柱状里啊,发现在 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

위 내용은 캔버스 동적 차트의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.