html5 laboratory - drawing in the canvas

Creating a bar chart with canvas

21st February 2010

The experiment

The new <canvas> element is one of the new goodies that comes along with HTML5. The <canvas> element allows you to programmatically draw via JavaScript. This has all sorts of possibilites, from generating graphs and charts to showing ball animations. It is on the first of these that I will concentrate, showing how a simple bar chart can be created on the <canvas> element with JavaScript.

The process

To begin with, let's take a quick look at the <canvas> element itself and what it offers. I will only briefly go into what it provides, a detailed draft of what it provides can be found over at the WHATWG site. You may also want to have a look at the HTML5 canvas cheat sheet which shows you in a nutshell what is available, which you can then delve into deeper when you want.

The element currently only has two attributes available:

  • width — which specifies the width of the canvas area
  • height — which indicates the canvas' height

That's it. It does however also have two methods which are available:

  • getContext(string contextId) — which takes an id and returns a refence to a context of the <canvas> element
  • toDataURL([string type], arg1, arg2...) — which returns a URL to an image in a canvas

There are also a large number of attributes methods that are available for use with the <canvas> element context that is returned from getContext(string contextId) which of course requires JavaScript. I will list the ones that I use for my bar chart example here, but the HTML5 canvas cheat sheet gives you a condensed view of them all.

  • beginPath() — resets the current path
  • closePath() — marks the current sub-path as closed, and starts a new sub-path that points to the same start and end of the sub-path that was just closed
  • fill() — fills the sub-paths with the current fill style
  • stroke() — draws a stroke on the current sub-path using the current stroke style
  • moveTo(float x, float y) — creates a new sub-path with the given x y co-ordinates
  • lineTo(float x, float y) — adds the point indicated by the given x y co-ordinates to the sub-path and connects it to the previous sub-path with a straight line
  • rect(float x, float y, float w, float h) — adds a new closed sub-path to the path which represents a rectangle using the given values
  • fillText(string text, float x, float y, [float maxWidth]) — fills the given text in the given position

First of all, the canvas needs to be defined within the HTML(5) document:

<canvas id="graphSpace" width="800" height="400"></canvas>

Now to the JavaScript. The first thing that we must obtain is a handle to the canvas to ensure that the element is actually within the DOM, and to check if the browser actually supports it. Once this is obtained, a context to the canvas element is obtained:

var graphCanvas = document.getElementById('graphSpace');
// Ensure that the element is available within the DOM
if (graphCanvas && graphCanvas.getContext) {
// Open a 2D context within the canvas
var context = graphCanvas.getContext('2d'); // Bar chart data
var data = new Array(5);
data[0] = "apples,200";
data[1] = "oranges,120";
data[2] = "bananas,80";
data[3] = "kiwis,230";
data[4] = "tangarines,340"; // Draw the bar chart
drawBarChart(context, data, 50, 100, (graphCanvas.height - 20), 50);
}

The data for the bar chart is simply contained within an array, with each element containing the name of the data and the data's value separated by a comma. This is followed by a call to drawBarChart() which takes the data and draws the actual bar chart. The full code of this function is displayed below:

function drawBarChart(context, data, startX, barWidth, chartHeight, markDataIncrementsIn) {
// Draw the x and y axes
context.lineWidth = "1.0";
var startY = 380;
drawLine(context, startX, startY, startX, 30);
drawLine(context, startX, startY, 570, startY);
context.lineWidth = "0.0";
var maxValue = 0;
for (var i=0; i < data.length; i++) {
// Extract the data
var values = data[i].split(",");
var name = values[0];
var height = parseInt(values[1]);
if (parseInt(height) > parseInt(maxValue)) maxValue = height; // Write the data to the chart
context.fillStyle = "#b90000";
drawRectangle(context,startX + (i * barWidth) + i,(chartHeight - height),barWidth,height,true); // Add the column title to the x-axis
context.textAlign = "left";
context.fillStyle = "#000";
context.fillText(name, startX + (i * barWidth) + i, chartHeight + 10, 200);
}
// Add some data markers to the y-axis
var numMarkers = Math.ceil(maxValue / markDataIncrementsIn);
context.textAlign = "right";
context.fillStyle = "#000";
var markerValue = 0;
for (var i=0; i < numMarkers; i++) {
context.fillText(markerValue, (startX - 5), (chartHeight - markerValue), 50);
markerValue += markDataIncrementsIn;
}
}

There are two further functions, drawLine() and drawRectangle() which are called and are defined as such:

// drawLine - draws a line on a canvas context from the start point to the end point
function drawLine(contextO, startx, starty, endx, endy) {
contextO.beginPath();
contextO.moveTo(startx, starty);
contextO.lineTo(endx, endy);
contextO.closePath();
contextO.stroke();
} // drawRectangle - draws a rectangle on a canvas context using the dimensions specified
function drawRectangle(contextO, x, y, w, h, fill) {
contextO.beginPath();
contextO.rect(x, y, w, h);
contextO.closePath();
contextO.stroke();
if (fill) contextO.fill();
}

You can (probably) see this bar chart working, although Internet Explorer may have issues (see below). All this code, whilst quite self explanatory, probably requires some explanation.

drawBarChart() starts by drawing the x and y axes of the graph by calling drawLine() twice, with different co-ordinates. The attribute lineWidth is used to set the thickness of the lines and reset afterwards to 0.

The code then parses the data array which contains the actual data for the bar chart. This extracts the name of a bar for the chart, along with the value it should be set to. The function drawRectangle() is then called which draws the rectangle in it's appropriate place. The fillText() method is then called to add the name of the drawn column. This is repeated for each element in the array until all the bars are drawn.

The last stage is to draw some measurement markers on the y-axis. This is done using the markDataIncrementsIn paramenter which simply indicates the scale that the increments are to be indicated on this axis (e.g. every 50, or 100). In the example, the value is 50.

The resulting graph, if you've not already looked at the bar chart itself or you're using Internet Explorer (sigh), looks as follows:

 

As usual, there are some browser compatability issues that come in the way of Internet Explorer. The <canvas> element isn't supported at all with IE, but thankfully the clever guys over at explorercanvas have created a JavaScript file which when downloaded and included for IE:

<!--[if IE]><script src="j/excanvas.js"></script><![endif]-->

causes the <canvas> element to work correctly in Internet Explorer. Or mostly correctly. My bar chart example doesn't seem to work.

The results

This is just a very small part of what the <canvas> can help you do. As mentioned above, there are many other methods that can be called on the canvas context which allow you to manipulate images, add borders, drop a shadow, draw circles, arcs, Bezier and quadratic curves and others. Future experiments on this site will look into some of these various other methods.

Watch this space!

html5 laboratory - drawing in the canvas的更多相关文章

  1. html5 中的SVG 和canvas

    想到昨天看资料的时候,发现html5 中的SVG 和canvas 都可以表示图形,那它们到底有哪些区别呢?该如何正确的使用它们呢? 1.SVG:可缩放矢量图形,(Scalable Vector Gra ...

  2. Pro HTML5 Programming(Second Edition)2.Canvas API(2)

    1.在页面中加入canvas元素 eg: <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  3. Pro HTML5 Programming(Second Edition)2.Canvas API(1)

    1.在使用HTML5的Canvas元素时,考虑到有些浏览器不支持canvas元素,或是不支持HTML5 Canvas API中的某些特性,开发人员最好提供一份替代代码. 以下代码展示如何在canvas ...

  4. HTML5学习(六)---------SVG 与Canvas

    参考教程:http://www.w3school.com.cn/html5/html_5_canvas_vs_svg.asp Canvas 和 SVG 都允许您在浏览器中创建图形,但是它们在根本上是不 ...

  5. 自学HTML5第四节(canvas画布详解)

    canvas画布好像可是说是HTML5的精华了,一定要学好,嗯嗯,绚丽的东西就要从基础的开始.... 先看看啥玩意叫做canvas 什么是 Canvas? HTML5 的 canvas 元素使用 Ja ...

  6. 玩转html5(二)----用canvas结合脚本在画布上画简单的图(html5又一强大功能)

    在html5中可以使用canvas标签在画布上画图,先直接上代码,这篇文章先简单介绍一下canvas的使用方法,简单画几个圆,矩形,三角形,写字. 在代码中均给出了注释,在这里特别强调的一点是:使用c ...

  7. 有趣html5(两)----使用canvas结合剧本画在画布上的简单图(html5另一个强大)

    请珍惜劳动小编成果,这篇文章是原来小编,转载请注明出处. 于html5中能够使用canvas标签在画布上绘图,先直接上代码,这篇文章先简介一下canvas的用法.简单画几个圆,矩形,三角形,写字. 在 ...

  8. HTML5 & CSS3 初学者指南(4) – Canvas使用

    介绍 传统的HTML主要用于文本的创建,可以通过<img>标签插入图像,动画的实现则需要第三方插件.在这方面,传统的HTML极其缺乏满足现代网页多媒体需求的能力.HTML5的到来,带来了新 ...

  9. HTML5 & CSS3初学者指南(4) – Canvas使用

    介绍 传统的HTML主要用于文本的创建,可以通过<img>标签插入图像,动画的实现则需要第三方插件.在这方面,传统的HTML极其缺乏满足现代网页多媒体需求的能力.HTML5的到来,带来了新 ...

随机推荐

  1. Sum Root to Leaf Numbers 解答

    Question Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent ...

  2. mysql补充(1)校对集utf8_unicode_ci与utf8_general_ci

    创建数据库并设置编码utf-8 多语言(补充1 2) create database mydb default character set utf8 collate utf8_general_ci; ...

  3. 利用PHPExcel转Excel柱形图

    这在附还有一个转柱形图的效果及代码. 原PHP报表效果: 转成Excel后的效果: 附上代码: <? php /** * PHPExcel * * Copyright (C) 2006 - 20 ...

  4. Ubuntu的防火墙UFW

    这是个简单的防火墙,可以直接在命令行启停,也可安装提图形端gufw *安装 sudo apt-get install ufw gufw *常用命令 sudo ufw enable //启动 ufw d ...

  5. 16. Linux 文件目录权限

    # 文件参数 d:表示是一个目录-:表示这是一个普通的文件l: 表示这是一个符号链接文件,实际上它指向另一个文件b.c:分别表示区块设备和其他的外围设备,是特殊类型的文件s.p:这些文件关系到系统的数 ...

  6. fastclick.js介绍

    原文地址:http://www.uedsc.com/fastclick.html 用途:去掉移动端click事件的300ms的延迟. 延迟为什么存在   …在移动浏览器中,当你点击按钮的单击事件时,将 ...

  7. C#多线程之Parallel中 类似于for的continue,break的方法

    好久没写东西了,终于找到点知识记录下... 利用ParallelLoopState对象来控制Parallel.For函数的执行,ParallelLoopState对象是由运行时在后台创建的: Para ...

  8. Glide的加载图片的帮助类,用来把图片圆角或者改成圆形图片

    Glide虽然非常好用但是没找到把图片圆角的方法,所以百度了一个非常不错的加载类自己实现圆角图 感谢原文章作者:http://blog.csdn.net/weidongjian/article/det ...

  9. Windows7 无法打开ASA SSL VPN和ASDM首页

    原文地址:Windows7 无法打开ASA SSL VPN 首页和无法打开 ASDM GUI 页面作者:futhy              windows 7 无法打开ASA SSL VPN 和AS ...

  10. ARM编译空间属性(转)

    原文地址:http://www.cnblogs.com/hongzg1982/articles/2205093.html 1. 程序的空间属性 一般情况下,一个程序本质上都是由 bss段.data段. ...