【带着canvas去漂泊】(1)绘制柱状图

《【带着canvas去漂泊】(1)绘制柱状图》

示例代码托管在:
http://www.github.com/dashnowords/blogs

博客园地点:《大史住在大前端》原创博文目次

华为云社区地点:【你要的前端打怪晋级指南】

[TOC]

一. 任务说明

运用原生canvasAPI绘制柱状图。(柱状图截图来自于百度Echarts官方示例库【检察示例链接】

《【带着canvas去漂泊】(1)绘制柱状图》

二. 重点提醒

柱状图或许是最轻易完成的图表范例了,矩形的部份直接运用fillRect()来绘制即可,为了将坐标轴标签笔墨绘制在小分割线中心,须要用measureText()来丈量文本的宽度,然后举行响应的偏移,不然直接绘制的话笔墨的左边境会和直线相对齐。其他部份都是一些基础API的运用,愿望列位小伙伴经由过程做演习来熟习这些API的用法。

三. 示例代码

提醒:代码中将一般图表参数直接写在了函数里(也就是所谓的“魔鬼数字”),这类做法是不首倡的,由于它违反了开辟的基础准绳之一“开放关闭准绳”。假如你运用过Echarts图表库就会发明,图表中险些一切要素都可以经由过程参数来定制,此处只须要关注canvasAPI的完成要领即可。

/**
 * 猎取canvas画图上下文
 * @type {[type]}
 */
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');

//画图设置
let options = {
        chartZone:[50,50,1000,700],//标识画图地区
        yAxisLabel:['0','100','200','300','400'],//标示Y轴坐标
        yMax:400,//Y轴最大值
        xAxisLabel:['Mon','Tue','Wed','Thu','Fri','Sat','Sun'],//X轴坐标
        data:[10,50,200,330,390,320,220],//柱状图数据
        barStyle:{
            width:70,//柱状图宽度
            color:'#1abc9c'//柱状图色彩
        }
    }

/*Echarts运用时,会挪用实例要领echartsInstance.setOptions(options)来启动画图*/
drawBarChart(options);

/**
 * 绘制柱状图
 */
function drawBarChart(options) {
    drawAxis(options); //绘制坐标轴
    drawYLabels(options); //绘制y轴坐标
    drawXLabels(options); //绘制x轴坐标
    //drawData(options);//绘制柱状图
    drawDataGradient(options);//绘制渐变色柱状图
}

/**
 * 绘制坐标轴
 */
function drawAxis(options) {
    let chartZone = options.chartZone;
    context.strokeWidth = 4;
    context.strokeStyle = '#353535';
    context.moveTo(chartZone[0],chartZone[1]);
    context.lineTo(chartZone[0],chartZone[3]); //y轴总高从50到700
    context.lineTo(chartZone[2],chartZone[3]); //x轴总长从50到1000
    context.stroke();
}

/**
 * 绘制y轴坐标
 */
function drawYLabels(options) {
    let labels = options.yAxisLabel;
    let yLength = (options.chartZone[3] - options.chartZone[1])*0.98;
    let gap = yLength / (labels.length - 1);
    
    labels.forEach(function (label, index) {
        //绘制坐标笔墨
        let offset = context.measureText(label).width + 20;
        context.strokeStyle = '#eaeaea';
        context.font = '16px';
        context.fillText(label, options.chartZone[0] - offset ,options.chartZone[3] - index * gap);
        //绘制小距离
        context.beginPath();
        context.strokeStyle = '#353535';
        context.moveTo(options.chartZone[0] - 10, options.chartZone[3] - index * gap);
        context.lineTo(options.chartZone[0], options.chartZone[3] - index * gap);
        context.stroke();
        //绘制辅助线
        context.beginPath();
        context.strokeStyle = '#eaeaea';
        context.strokeWidth = 2;
        context.moveTo(options.chartZone[0], options.chartZone[3] - index * gap);
        context.lineTo(options.chartZone[2], options.chartZone[3] - index * gap);
        context.stroke();
    });
}

/**
 * 绘制x轴坐标
 */
function drawXLabels(options) {
    let labels = options.xAxisLabel;
    let xLength = (options.chartZone[2] - options.chartZone[0])*0.96;
    let gap = xLength / labels.length;
    
    labels.forEach(function (label, index) {
        //绘制坐标笔墨
        let offset = context.measureText(label).width;
        context.strokeStyle = '#eaeaea';
        context.font = '18px';
        context.fillText(label, options.chartZone[0] + (index + 1) * gap - offset ,options.chartZone[3] + 20);
        //绘制小距离
        context.beginPath();
        context.strokeStyle = '#353535';
        context.moveTo(options.chartZone[0] + (index + 1) * gap - offset / 2 ,options.chartZone[3]);
        context.lineTo(options.chartZone[0] + (index + 1) * gap - offset / 2,options.chartZone[3]+5);
        context.stroke();
        //存储偏移量
        options.offsetXLabel = offset / 2;
    });
}

/**
 * 绘制数据
 */
function drawData(options) {
    let data = options.data;
    let xLength = (options.chartZone[2] - options.chartZone[0])*0.96;
    let yLength = (options.chartZone[3] - options.chartZone[1])*0.98;
    let gap = xLength / options.xAxisLabel.length;

    //绘制矩形
    data.forEach(function (item, index) {
        context.fillStyle = options.barStyle.color || '#1abc9c'; //02BAD4
        let x0 = options.chartZone[0] + (index + 1) * gap - options.barStyle.width / 2 - options.offsetXLabel;
        let height = item / options.yMax * (options.chartZone[3] - options.chartZone[1])*0.98;
        let y0 =  options.chartZone[3] - height;
        let width = options.barStyle.width;
        context.fillRect(x0,y0,width,height);
    });
}

/**
 * 绘制线性渐变色柱状图
 */
function drawDataGradient(options) {
    let data = options.data;
    let xLength = (options.chartZone[2] - options.chartZone[0])*0.96;
    let yLength = (options.chartZone[3] - options.chartZone[1])*0.98;
    let gap = xLength / options.xAxisLabel.length;
    //建立渐变色
    let fillStyleGradient = context.createLinearGradient(50,50,50,700);
        fillStyleGradient.addColorStop(0, options.barStyle.color);
        fillStyleGradient.addColorStop(1, 'rgba(1,176,241,0.6)');

    //绘制矩形
    data.forEach(function (item, index) {
        context.fillStyle = fillStyleGradient;
        let x0 = options.chartZone[0] + (index + 1) * gap - options.barStyle.width / 2 - options.offsetXLabel;
        let height = item / options.yMax * (options.chartZone[3] - options.chartZone[1])*0.98;
        let y0 =  options.chartZone[3] - height;
        let width = options.barStyle.width;
        context.fillRect(x0,y0,width,height);
    });
}

浏览器中可检察结果:

《【带着canvas去漂泊】(1)绘制柱状图》

四. 思考题

假如愿望在坐标轴末尾加一个箭头,须要怎么做呢?

/*x轴箭头示例*/
//1.options中增添箭头色彩和大小的设置
let options = {
    //...
    axisArrow:{
            size:2,
            color:'#DA5961'
        }
}
//箭头绘制函数

/**
 * x轴绘制箭头
 */
function drawArrow(options) {
    let factor = options.axisArrow.size;//猎取箭头大小因子
    context.save();//保留当前设置的画图上下文
    context.translate(options.chartZone[2], options.chartZone[3]);//挪动坐标系原点至x轴末尾
    context.beginPath();//最先绘制箭头
    context.moveTo(0,0);//挪动至新原点
    context.lineTo(2 * factor,-3 * factor);
    context.lineTo(10 * factor,0);
    context.lineTo(2 * factor, 3 * factor);
    context.lineTo(0,0);
    context.globalAlpha = 0.7; //设置添补色透明度
    context.fillStyle = options.axisArrow.color;//猎取箭头色彩
    context.fill();//添补箭头途径
    context.restore();//恢复画图上下文款式设置
}        

箭头结果:

《【带着canvas去漂泊】(1)绘制柱状图》

y轴的箭头请自行完成即可。

    原文作者:大史不说话
    原文地址: https://segmentfault.com/a/1190000019357364
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞