• html5 laboratory


    html5 laboratory - drawing in the canvas

    html5 laboratory

    Creating a bar chart with canvas

    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:

    bar chart

     

    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!

  • 相关阅读:
    可序列化serializable的作用是什么
    HelloWorld编译正常运行报noclassdeffounderror
    dtd对xml没有起到约束作用
    Ajax发送XML请求案例
    Ajax发送GET和POST请求案例
    Ajax发送简单请求案例
    初识Ajax
    数据库设计
    数据库和实例的区别
    Flask
  • 原文地址:https://www.cnblogs.com/lexus/p/3741354.html
Copyright © 2020-2023  润新知