Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Sencha Charts Essentials
Sencha Charts Essentials

Sencha Charts Essentials: Create stunning charts and visualizations for both web and mobile applications

eBook
€8.99 €16.99
Paperback
€20.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Sencha Charts Essentials

Chapter 1. Fundamentals of Sencha Charts

Data visualization has always been an integral part of an application, because of its power to quickly disseminate information. It is no different for an application developed using Sencha Ext JS or Sencha Touch frameworks. Recently, with the launch of Ext JS 5, Sencha has created a separate charting package—Sencha Charts—to add charting capability to an application. The beauty is that the same Sencha Charts library works inside desktop applications that run Ext JS, as well as in touch- or mobile-based applications that run Sencha Touch.

There are two ways to draw in a browser—Scalable Vector Graphics (SVG) and Canvas API. Though VML also exists for older IE browsers, we have excluded it for brevity. All the JavaScript charting libraries use SVG and Canvas API to offer charting capability to their users—for rendering as well as interactions. Understanding them will provide the foundation that is needed to understand Sencha Charts and its capabilities, and more importantly, reasons to use it.

SVG and Canvas are supported by browsers to render graphics. SVG was introduced in 1999 to render vector graphics, which can scale up or down, based on the screen resolution, without any visual distortion, as compared to raster one. SVG works similar to XML where you work with elements, attributes, and styles. SVG is a retained mode graphics model that is persisted in browser memory and we can manipulate it through code. This manipulation leads to automatic re-rendering where the user sees the updated drawing.

Canvas was a new specification brought to us by Apple in 2004. It follows an immediate mode graphics model, where it renders the drawing and forgets it. It does not have a built-in scene graph that SVG has, where it retains the graphics in memory and allows its manipulation. So, to recreate the same drawing, you will have to call the APIs to redraw it on the canvas.

In this chapter, we will do the following:

  • Create a chart using SVG
  • Create a chart using the HTML5 Canvas API
  • Create a chart using the Sencha Charts API
  • Compare the three to understand the advantages of using Sencha Charts

Introducing the sample chart

For demonstration and comparison, we will create a chart using Canvas API and SVG, and then we will create the same using Sencha Charts APIs.

Our sample chart, as shown in the following figure, will have:

  • x (horizontal) and y (vertical) axes with labels
  • A column chart with circular markers in the middle of each bar
  • An area chart
  • A crosshair that appears on mousemove
    Introducing the sample chart

In our implementation, we will use a few terms, coordinates, and calculations. They are highlighted in the following diagram:

Introducing the sample chart

Canvas and SVG

In this section, we will see how we can create the sample chart, described earlier, using Canvas API and SVG. Each of these technologies has their own advantages and context in which they will be used. Their discussion is not in the scope of this book. You may refer to the W3 specifications for their detailed documentation.

Preparation

First of all, let's prepare our HTML to draw the chart. The Canvas APIs work with the <canvas> element, whereas SVG APIs work with the <svg> element.

The following table shows the HTML page for Canvas-based and SVG-based drawing approaches. The ch01_01.html code, which is on the left-hand side, contains the implementation using Canvas APIs, whereas ch01_02.html contains the implementation based on SVG APIs.

ch01_01.html

ch01_02.html

<!DOCTYPE HTML>
<html>
    <head>
    </head>
<body>
<canvas id="my-canvas" width="450" height="450" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
<canvas id="overlay" width="450" height="450" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas>

<script>
   //code will go here
</script>
</body>
</html>
<!DOCTYPE html>
<html>
    <head>
    </head>
<body>
<svg id="my-drawing" width="450" height="450" xmlns="http://www.w3.org/2000/svg"
      xmlns:xlink="http://www.w3.org/1999/xlink"></svg>

<script>
   //code will go here
</script>
</body>

</html>

All the JavaScript code that we will be writing will go inside the <script> tag.

Let's start by creating some helper methods for our chart, which we will use later to create the actual chart. We will have the Canvas and SVG code side by side for easier comparison.

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

Creating a line

To create a line, Canvas provides path APIs—moveTo and lineTo—whereas SVG provides the <line> element. The following screenshot shows the code to create a line, which we will use to create the chart axis, and crosshair lines:

ch01_01.html

ch01_02.html

<script>
  function createLine(ctx, x1, y1, x2, y2, sw) {
    ctx.beginPath();
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.lineWidth = sw ? sw : 2;
    ctx.strokeStyle = 'black';
    ctx.stroke();
    ctx.closePath();
  }
<script>
  var NS = "http://www.w3.org/2000/svg";
  function createLine(x1, y1, x2, y2, sw) {
    var line = document.createElementNS(NS, 'line');
    line.setAttribute('x1', x1);
    line.setAttribute('y1', y1);
    line.setAttribute('x2', x2);
    line.setAttribute('y2', y2);
    line.style.stroke = 'black';
    line.style["stroke-width"] = sw ? sw : 2;

    return line;
  }

Creating an axis

An axis is a combination of a line and an arrow head. In the following code, the createAxis method can create an axis and the arrow head based on the line coordinates and the axis direction value, which will be "v" to indicate vertical axis; or "h" to indicate horizontal axis. The direction value is used to calculate the path for drawing the arrow head.

In the following table, the code in the first column shows the implementation using the Canvas API, whereas the code in the second column shows the SVG equivalent of it:

ch01_01.html

ch01_02.html

  function createAxis(ctx, x1, y1, x2, y2, direction) {
    createLine(ctx, x1, y1, x2, y2);

    //draw arrow head
    if (direction === "v") {
      ctx.beginPath();
      ctx.moveTo(x1, y2);
      ctx.lineTo(x1 - 10*Math.sin(Math.PI/4), y2 + 10*Math.cos(Math.PI/4));
      ctx.moveTo(x1, y2);
      ctx.lineTo(x1 + 10*Math.sin(Math.PI/4), y2 + 10*Math.cos(Math.PI/4));
      ctx.lineWidth = 2,
      ctx.strokeStyle = 'black',
      ctx.stroke();
      ctx.closePath();
    }

    if (direction === "h") {
      ctx.beginPath();
      ctx.moveTo(x2, y1);
      ctx.lineTo(x2 - 10*Math.cos(Math.PI/4), x2 - 10*Math.sin(Math.PI/4));
      ctx.moveTo(x2, y1);
      ctx.lineTo(x2 - 10*Math.cos(Math.PI/4), x2 + 10*Math.sin(Math.PI/4));
      ctx.lineWidth = 2;
      ctx.strokeStyle = 'black';
      ctx.stroke();
      ctx.closePath();
    }
  }

  function createPath(p, stroke, fill) {
    var path = document.createElementNS(NS, 'path');

    path.setAttribute('d', p);
    path.style.stroke = stroke ? stroke : 'black';
    path.style["stroke-width"] = 2;
    path.style.fill = fill ? fill : 'none'


    return path;
  }

  function createAxis(x1, y1, x2, y2, direction) {
    var axis = document.createElementNS(NS, 'g');

    var line = createLine(x1, y1, x2, y2);
    var ah;

    //draw arrow head
    if (direction === "v") {
      var p = 'M' + x1 + ',' + y2 + ' L' + (x1 - 10*Math.sin(Math.PI/4)) + ',' + (maxY + 10*Math.cos(Math.PI/4));
      p += ' M' + x1 + ',' + y2 + ' L' + (x1 + 10*Math.sin(Math.PI/4)) + ',' + (maxY + 10*Math.cos(Math.PI/4));
      ah = createPath(p);
    }

    if (direction === "h") {
      var p = 'M' + x2 + ',' + y1 + ' L' + (x2 - 10*Math.cos(Math.PI/4)) + ',' + (x2 - 10*Math.sin(Math.PI/4));
      p += ' M' + x2 + ',' + y1 + ' L' + (x2 - 10*Math.cos(Math.PI/4)) + ',' + (x2 + 10*Math.sin(Math.PI/4));
      ah = createPath(p);
    }

    axis.appendChild(line);
    axis.appendChild(ah);

    return axis;
  }

Creating an axis label

The createLabel method creates a text label for an axis based on the specified direction. The Canvas approach uses transformation—translate and rotate—to render the vertical label, whereas the SVG approach uses the writing-mode style attribute of the <text> element. You may also use <tspan> with transformations to show the vertical axis label.

In the following table, the code in the first column shows the implementation of the method using the Canvas API, whereas the code in the second column shows the equivalent implementation using SVG specification:

ch01_01.html

ch01_02.html

  function createLabel(ctx, x, y, txt, direction) {

    ctx.font = 'Italic 1.1em Aerial';

    if (direction === 'v') {
      ctx.translate(x, y);
      ctx.rotate(-Math.PI/2);
      ctx.fillText(txt, 0, 0);

      //reset transformation
      ctx.setTransform(1, 0, 0, 1, 0, 0);
    } else {
      ctx.fillText(txt, x, y);
    }
  }
  function createLabel(x, y, txt, direction) {
    var text = document.createElementNS(NS, 'text');

    text.setAttribute('x', x);
    text.setAttribute('y', y);
    text.style.font = 'Italic 1.1em Aerial';
    if (direction === 'v') {
      text.style['writing-mode'] = 'tb';
    }

    var node = document.createTextNode(txt);
    text.appendChild(node);

    return text;
  }

Creating a bar

To create a bar for our column chart, the createBar method draws a rectangle using the rect API of Canvas and the <rect> element of SVG.

ch01_01.html

ch01_02.html

  function createBar(ctx, x, y, w, h) {
    ctx.beginPath();
    ctx.moveTo(x, y);
    ctx.rect(x, y, w, h);

    ctx.fillStyle = '#E13987';
    ctx.lineWidth = 2;
    ctx.strokeStyle = '#E13987';
    ctx.stroke();
    ctx.fill();
    ctx.closePath();
  }

  function createBar(x, y, w, h) {
    var rect = document.createElementNS(NS, 'rect');

    rect.setAttribute('x', x);
    rect.setAttribute('y', y);
    rect.setAttribute('width', w);
    rect.setAttribute('height', h);
    rect.style.fill = '#E13987';
    rect.style.stroke = '#E13987';
    rect.style['stroke-width'] = 2;

    return rect;
  }

Creating a marker on the bar

In our chart, we want to show circular markers on the top of the bars. The createMarker method will help us add markers to our drawing based on the location of its center and radius.

ch01_01.html

ch01_02.html

  function createMarker(ctx, cx, cy, r) {
    ctx.beginPath();

    ctx.arc(cx, cy, r, 0, 2*Math.PI, false);
    ctx.fillStyle = '#6F5092';
    ctx.lineWidth = 2;
    ctx.strokeStyle = '#6F5092';
    ctx.stroke();
    ctx.fill();

    ctx.closePath();
  }

  function createMarker(cx, cy, r) {
    var circle = document.createElementNS(NS, 'circle');

    circle.setAttribute('cx', cx);
    circle.setAttribute('cy', cy);
    circle.setAttribute('r', r);
    circle.style.fill = '#6F5092';
    circle.style.stroke = '#6F5092';
    circle.style['stroke-width'] = 2;

    return circle;
  }

This ends the list of helper methods that we need to create our chart. Let's see how we can use them to create the final output.

Creating a chart

Now, we will enhance our script to create the chart in a step-by-step approach. We will start with the axis.

Axes

Before we start, we first need access to our drawing surface, either the canvas or <svg> element. Since we have already set the ID on the element, we can use the document.getElementById method to access them. Canvas API, however, requires us to additionally get the drawing context and use it for the drawing.

Once we have access to the drawing surface, we use the createAxis method to create the x and y axes, as shown in the following table:

ch01_01.html

ch01_02.html

  var canvas = document.getElementById('my-canvas');
  var ctx = canvas.getContext('2d');

  var samples = [100, 250, 175],
    gutter = 50,
    barWidth = 50,
    x0 = 50,
    y0 = 400,
    markerRadius = 10;

    
  //draw axes
  var maxX = x0 + samples.length*(barWidth + gutter) + gutter;
  var maxY = y0 - 250 - 50;
  createAxis(ctx, x0, y0, maxX, y0, 'h');
  createAxis(ctx, x0, y0, x0, maxY, 'v');

  var svg = document.getElementById('my-drawing');

  var samples = [100, 250, 175],
        gutter = 50,
        barWidth = 50,
        x0 = 50,
        y0 = 400,
        markerRadius = 10;

  //draw axes
  var maxX = x0 + samples.length*(barWidth + gutter) + gutter;
  var maxY = y0 - 250 - 50;
  var xAxis = createAxis(x0, y0, maxX, y0, 'h');
  var yAxis = createAxis(x0, y0, x0, maxY, 'v');

  svg.appendChild(xAxis);
  svg.appendChild(yAxis);

The following screenshot shows the output with x and y axes. Each axis has an arrowhead as well:

Axes

Axis label

To draw a label on an axis, use the createLabel method, as shown in the following table:

ch01_01.html

ch01_02.html

  //create axis label
  createLabel(ctx, maxX/2, y0 + 30, 'Samples');
  createLabel(ctx, x0 - 20, y0 - (y0 - maxY)/2, 'Value', 'v');

  //create axis label
  var xLabel = createLabel(maxX/2, y0 + 30, 'Samples');
  var yLabel = createLabel(x0 - 20, y0 - (y0 - maxY)/2, 'Value', 'v');

  svg.appendChild(xLabel);
  svg.appendChild(yLabel);

The following output is produced to show the axis label:

Axis label

Bar chart with a marker

To create the bar for each sample data, we will use the createBar method and createMarker to show the marker on the top of each bar, as shown in the following table:

ch01_01.html

ch01_02.html

  //draw bars
  for (var i=0; i<samples.length; i++) {
    var x, y, w = barWidth, h = samples[i];
    x = x0 + gutter + i*(w + gutter);
    y = y0 - h;

    createBar(ctx, x, y, w, h);
    createMarker(ctx, x + w/2, y, markerRadius);
  }

  //draw bars
 for (var i=0; i<samples.length; i++) {
    var x, y, w = barWidth, h = samples[i];
    x = x0 + gutter + i*(w + gutter);
    y = y0 - h;

    var bar = createBar(x, y, w, h);
    var marker = createMarker(x + w/2, y, markerRadius);

    svg.appendChild(bar);
    svg.appendChild(marker);
    
  }

You may refer to the second figure in the Introducing the sample chart section for the barWidth and gutter values. The following screenshot shows the output produced from the two applications:

Bar chart with a marker

Creating an area chart with line stroking

Our next step is to create an area chart. First, we will show the line and then we will fill the area.

The following code shows how to create the area chart with line stroke using a different sample—areaSamples:

ch01_01.html

ch01_02.html

  //draw area chart
  var areaSamples = [20, 30, 20, 100, 140, 80, 40, 30, 60, 10, 75];
  var n = areaSamples.length;
  var d = (maxX - x0)/n;
  //distance between the points
  var start = true;
  for (var i=0; i<n; i++) {
    var x = x0 + i*d , y = y0 - areaSamples[i];

    if (start) {
      ctx.beginPath();
      ctx.moveTo(x, y);
      start = false;
    }
    ctx.lineTo(x, y);
  }
  ctx.lineWidth = 2,
  ctx.strokeStyle = '#00904B',
  ctx.stroke();
  ctx.closePath();

  //draw area chart
  var areaSamples = [20, 30, 20, 100, 140, 80, 40, 30, 60, 10, 75];
  var n = areaSamples.length;
  var d = (maxX - x0)/n;
  //distance between the points
  var start = true;
  var p = '';
  for (var i=0; i<n; i++) {
    var x = x0 + i*d , y = y0 - areaSamples[i];

    if (start) {
      p += 'M' + x + ',' + y;
      start = false;
    }
    
    p += ' L' + x + ',' + y;
  }

  //area - with border
  var area = createPath(p, '#00904B');
  svg.appendChild(area);

We have used path APIs to create the line chart, which we will fill in the next section to make it an area chart. Run the two codes and you will see the following output:

Creating an area chart with line stroking

Creating an area chart with fill

Now, let's fill the area under the line chart that we drew earlier to make it an area chart. To fill the area, we will have to end the path at its starting point.

Since we have added the area chart after the bar, the bar would be hidden behind the area chart. So, we will set the transparency when we fill the area. This way, the user can see the bar behind the area. To set the transparency in Canvas, we set the globalAlpha parameter, whereas in SVG, it is a bit more involved. We have to create a mask element with transparency level and use it to fill the area.

In the following table, the code in the first column shows the implementation using the Canvas API, whereas, the code in the second column shows the corresponding implementation using SVG:

ch01_01.html

ch01_02.html

  //fill the area chart
  start = true;
  ctx.globalAlpha = 0.5;
  ctx.fillStyle = '#64BD4F';
  for (var i=0; i<n; i++) {
    var x = x0 + i*d , y = y0 - areaSamples[i];

    if (start) {
      ctx.beginPath();
      ctx.moveTo(x, y0);
      start = false;
    }
    ctx.lineTo(x, y);

    if (i === (n - 1)) {
      ctx.lineTo(x, y0);
    }
  }
  ctx.fill();
  ctx.closePath();

  //fill the area chart
  p += ' L' + x + ',' + y0 + ' L' + x0 + ',' + y0 + ' Z';
  var fillArea = createPath(p, 'none', '#64BD4F');

  //transparency for the fill area
  var defs = document.createElementNS(NS, 'defs');
  var mask = document.createElementNS(NS, 'mask');
  mask.setAttribute('id', 'areamask');
  mask.setAttribute('x', 0);
  mask.setAttribute('y', 0);
  mask.setAttribute('width', 450);
  mask.setAttribute('height', 450);
  var fillArea1 = document.createElementNS(NS, 'path');
  fillArea1.setAttribute('d', p);
  fillArea1.style.fill = '#666666';
  mask.appendChild(fillArea1);
  defs.appendChild(mask);
  svg.appendChild(defs);

  fillArea.style.fill = '#64BD4F';
  fillArea.setAttribute('mask', 'url(#areamask)');
  svg.appendChild(fillArea);

The following screenshot shows the output produced by these two codes:

Creating an area chart with fill

Crosshair lines

The last item we are left with is crosshair lines. To show the crosshair line on mousemove in the Canvas approach, we will add one more <canvas> element on top (that is, higher z-index) of the existing one as an overlay layer. It is this overlay canvas that we will use to render crosshair lines. Here is the code snippet showing an additional overlay <canvas> element added to the document body:

<body>
    <canvas id="my-canvas" width="450" height="450" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
    <canvas id="overlay" width="450" height="450" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas>
<script>
...

We register the handler for mousemove on the overlay canvas. The handler clears the canvas using the clearRect API so that old lines get cleared before adding the crosshair lines.

In the SVG approach, we will use the same <svg> element. The lines are added beforehand and the handler code moves them to the new location based on mouse position by setting their coordinate related attributes.

There is a check we can make to ensure that we don't show the crosshair if the mouse is outside of the chart area.

The following table shows the code related to crosshair for Canvas as well as SVG:

ch01_01.html

ch01_02.html

  //show cross-hair
  var overlay = document.getElementById('overlay');
  var overCtx = overlay.getContext('2d');

  var lineDash = overCtx.getLineDash();
  overCtx.setLineDash([5,5]);
  overlay.addEventListener('mousemove', function(evt) {
    overCtx.clearRect(0, 0, overlay.width, overlay.height);
    var rect = overlay.getBoundingClientRect();
    var x = evt.clientX - rect.left,
    y = evt.clientY - rect.top;
    //don't show the cross-hair if we are outside the chart area
    if (x < x0 || x > maxX || y < maxY || y > y0) {
      return;
    }

    overCtx.beginPath();
    overCtx.moveTo(x0 - 5, y);
    overCtx.lineTo(maxX, y);
    overCtx.moveTo(x, maxY);
    overCtx.lineTo(x, y0 + 10);
    overCtx.strokeStyle = 'black',
    overCtx.stroke();
    overCtx.closePath();
  }, false);

  //show cross-hair
    var hl = createLine(-x0, -y0, -maxX, -y0);
    var vl = createLine(-x0, -y0, -x0, -maxY);
    hl.style['stroke-dasharray'] = [5,5];
    vl.style['stroke-dasharray'] = [5,5];
    svg.appendChild(hl);
    svg.appendChild(vl);
    svg.addEventListener('mousemove', function(evt) {
    var x = evt.offsetX || evt.clientX,
    y = evt.offsetY || evt.clientY; 
    //don't show the cross-hair if we are outside the chart area
    if (x < x0 || x > maxX || y < maxY || y > y0) {
      return;
    }

    hl.setAttribute('x1', x0 - 5);
    hl.setAttribute('y1', y);
    hl.setAttribute('x2', maxX);
    hl.setAttribute('y2', y);
    
    vl.setAttribute('x1', x);
    vl.setAttribute('y1', maxY);
    vl.setAttribute('x2', x);
    vl.setAttribute('y2', y0 + 10);

  });

Here is the output of the two codes showing the crosshair lines when a user moves the mouse in the chart area:

Crosshair lines

So, we have our final output. Great! But wait! Imagine that you are a charts library developer or someone who wants to add charting capability to your application and has to support different browsers; some of them support SVG (for example, older ones), whereas some of them support Canvas. You can visit http://caniuse.com/ to review specific browser-related support. To ensure that your charts render on both types of browser, you will have to implement your code in SVG as well as Canvas, and then, based on the browser support, your code has to use one of them. The problem becomes even bigger if you have to support old IE browsers that support VML, as the APIs and approaches differ.

This is exactly the kind of problem we can solve using an abstraction called Surface, which is offered by Sencha Charts. Let's look at the Surface abstraction, what mechanism it offers for drawing, and how we can use them to create the same chart that we have created using the SVG and Canvas APIs.

Sencha Charts Surface API

Sencha Charts offers complete charting capability with built-in charts to serve your data visualization needs. While we will look at the different out-of-box charts and their extensions in subsequent chapters, here we will look at their abstraction class—Ext.draw.Surface—which abstracts the underlying API differences across browsers and provides a single consistent API, which renders drawings on SVG, Canvas, or VML based on what the underlying browser supports. The following diagram depicts the Surface class that translates its APIs to the underlying VML, SVG, or Canvas APIs based on the browser support:

Sencha Charts Surface API

To demonstrate the Surface API and its benefits, let's create a project using Sencha Cmd by running the following command:

sencha generate app SCE /path/to/application/folder

Modify your app.json file to add Sencha Charts support to your project by adding sencha-charts to the requires config. After this, refresh the application by running the following command so that Sencha Charts package is included into the application:

sencha app refresh 

Axes

Sencha Cmd will generate a Main view class inside the app/view/main folder, which is the initial view rendered on the screen. Replace the content of the file with the following code to show the axes:

Ext.define('SCE.view.main.Main', {
   extend: 'Ext.container.Container',

   xtype: 'app-main',

   height: 850,
   width: 850,
   
   items: [{
       xtype: 'draw',
       title: 'Chart',
       height: 500,
       width: 500
   }],

   createLine: function(x1, y1, x2, y2, sw) {
       return {
           type: 'path',
           stroke: 'black',
           path: 'M' + x1 + ',' + y1 + ' L' + x2 + ',' + y2,
           lineWidth: sw ? sw : 2
       };

   },

   createPath: function(p, stroke, fill, opacity) {
       return {
           type: 'path',
           path: p,
           stroke: stroke ? stroke : 'black',
           lineWidth: 2,
           fillStyle: fill ? fill : 'none',
           fillOpacity: opacity ? opacity : 1
       };
   },

   createAxis: function(x1, y1, x2, y2, direction) {
       var line = this.createLine(x1, y1, x2, y2);
       var ah;

       //draw arrow head
       if (direction === "v") {
           var p = 'M' + x1 + ',' + y2 + ' L' + (x1 - 10*Math.sin(Math.PI/4)) + ',' + (this.maxY + 10*Math.cos(Math.PI/4));
           p += ' M' + x1 + ',' + y2 + ' L' + (x1 + 10*Math.sin(Math.PI/4)) + ',' + (this.maxY + 10*Math.cos(Math.PI/4));

           ah = this.createPath(p);
       }

       if (direction === "h") {
           var p = 'M' + x2 + ',' + y1 + ' L' + (this.maxX - 10*Math.cos(Math.PI/4)) + ',' + (this.maxX - 10*Math.sin(Math.PI/4));
           p += ' M' + x2 + ',' + y1 + ' L' + (this.maxX - 10*Math.cos(Math.PI/4)) + ',' + (this.maxX + 10*Math.sin(Math.PI/4));

           ah = this.createPath(p);
       }

       var axis = Ext.create('Ext.draw.sprite.Composite', {});
       axis.add(line);
       axis.add(ah);

       return axis;
   },

   afterRender: function() {
       var samples = [100, 250, 175],
           gutter = 50,
           barWidth = 50,
           x0 = 50,
           y0 = 400,
           markerRadius = 10;

       var drawCt = this.down('draw');

       var surface = drawCt.getSurface();

      //draw axes
       this.maxX = x0 + samples.length*(barWidth + gutter) + gutter;
       this.maxY = y0 - 250 - 50;
       surface.add(this.createAxis(x0, y0, this.maxX, y0, 'h'));
       surface.add(this.createAxis(x0, y0, x0, this.maxY, 'v'));

       this.callParent(arguments);
   }
});

The preceding code creates a container with a draw component that shows the x and y axes. The draw component contains the surface object that offers drawing APIs.

The createLine method creates a line using the path sprite. The createPath method creates a path using the path sprite. This is used to create the arrowhead of the axis.

The following code snippet creates two axes and adds them to the surface. The Surface class internally and uses VML/SVG/Canvas APIs to render the drawing on the screen:

surface.add(this.createAxis(x0, y0, this.maxX, y0, 'h'));
surface.add(this.createAxis(x0, y0, x0, this.maxY, 'v'));

The following screenshot shows the output produced by the preceding code:

Axes

Axis label, bars, and markers

Let's add a member method to the SCE.view.main.Main class to create the axis label. The following method uses the text sprite to create a label:

createLabel: function(x, y, txt) {

       return {
           type: 'text',
           x: x,
           y: y,
           text: txt,
           font: '1.1em arial italic'
       };

   }

The createBar member method uses a rectangle sprite to create a bar for our bar chart.

   createBar: function(x, y, w, h) {
       return {
           type: 'rect',
           x: x,
           y: y,
           width: w,
           height: h,
           fillStyle: '#E13987',
           stroke: '#E13987',
           lineWidth: 2
       };
   }

The following member method creates a marker at the specified coordinate:

   createMarker: function(cx, cy, r) {
       return {
           type: 'circle',
           cx: cx,
           cy: cy,
           r: r,
           fillStyle: '#6F5092',
           stroke: '#6F5092',
           lineWidth: 2
       };
   }

Now, let's add the following code to the afterRender method, before the this.callParent() call, to draw the axis label and bars with markers:

//create axis label
var xLabel = this.createLabel(this.maxX/2, y0 + 30, 'Samples');
var yLabel = this.createLabel(x0 - 40, y0 - (y0 - this.maxY)/2, 'Value');
yLabel.rotationRads = -Math.PI/2;

surface.add(xLabel);
surface.add(yLabel);

//draw bars
for (var i=0; i<samples.length; i++) {
   var x, y, w = barWidth, h = samples[i];
   x = x0 + gutter + i*(w + gutter);
   y = y0 - h;

   var bar = this.createBar(x, y, w, h);
   var marker = this.createMarker(x + w/2, y, markerRadius);

   surface.add(bar);
   surface.add(marker);
   
}

Refreshing the URL in the browser, the code will produce the following output:

Axis label, bars, and markers

Area chart

To create the area chart, add the following code to the afterRender member method before the this.callParent() call:

//draw area chart
var areaSamples = [20, 30, 20, 100, 140, 80, 40, 30, 60, 10, 75];
var n = areaSamples.length;
var gutter = (this.maxX - x0)/n;
var start = true;
var p = '';
for (var i=0; i<n; i++) {
   var x = x0 + i*gutter , y = y0 - areaSamples[i];

   if (start) {
       p += 'M' + x + ',' + y;
       start = false;
   }
   
   p += ' L' + x + ',' + y;
}

//area - with border
var area = this.createPath(p, '#00904B');
surface.add(area);

//fill the area chart
p += ' L' + x + ',' + y0 + ' L' + x0 + ',' + y0 + ' Z';
var fillArea = this.createPath(p,'none','#64BD4F', 0.5);
surface.add(fillArea);

The following screenshot shows the output produced after the preceding code is added:

Area chart

Creating the crosshair

The last item is creating the crosshair. The following code adds two lines to the overlay surface and then the mousemove handler changes its position by setting its path attributes:

//show cross-hair
var overlay = drawCt.getSurface('overlay');
var hl, vl, headerOffset;

hl = this.createLine(-x0, -y0, -x0, -y0);
vl = this.createLine(-x0, -y0, -x0, -y0);
hl.lineDash = [5,5];
vl.lineDash = [5,5];
hl = overlay.add(hl);
vl = overlay.add(vl);
this.getEl().addListener('mousemove', function(evt, target) {
   var x = evt.getX(),
       y = evt.getY();

   //don't show the cross-hair if we are outside the chart area
   if (x < x0 || x > this.maxX || y < this.maxY || y > y0) {
       return;
   }

   headerOffset = drawCt.getHeader().getHeight();

   hl.setAttributes({
       path: 'M' + (x0 - 5) + ',' + (y - headerOffset) + ' L' + this.maxX + ',' + (y - headerOffset)
   });

   vl.setAttributes({
       path: 'M' + x + ',' + this.maxY + ' L' + x + ',' + (y0 + 10)
   });
   
   overlay.renderFrame();
}, this);

The overlay surface sits on top of the main surface that we used earlier to draw the axes, bar, area chart, and so on. We will discuss in more detail the different types of surfaces when we get to Chapter 3, Sencha Charts Architecture.

Creating the crosshair

Summary

In this chapter, we reviewed the supported browser drawing formats—Canvas and SVG—to create a drawing and we used them to create a basic chart. These are basic building blocks of any JavaScript charting library, such as Sencha Charts, FusionCharts, HighCharts, amCharts, and so on. In the second half of the chapter, we looked at the issues that these different APIs present when it comes to creating charts that work on different browsers and platforms, and how we can use the Surface APIs of Sencha Charts to address them. In the subsequent chapters, we will build on top of these fundamentals to understand more about Sencha Charts.

Left arrow icon Right arrow icon

Description

If you are an Ext JS or Sencha Touch developer, designer, or architect who wants to build enterprise-scale data visualization capabilities using Sencha, then this book is ideal for you. You should have a knowledge of HTML, JavaScript, CSS, and Sencha Ext JS or Sencha Touch fundamentals, in particular. Some familiarity with SVG and HTML5 Canvas would be preferred, but not required.

Who is this book for?

If you are an Ext JS or Sencha Touch developer, designer, or architect who wants to build enterprise-scale data visualization capabilities using Sencha, then this book is ideal for you. You should have a knowledge of HTML, JavaScript, CSS, and Sencha Ext JS or Sencha Touch fundamentals, in particular. Some familiarity with SVG and HTML5 Canvas would be preferred, but not required.

What you will learn

  • Set up and configure Sencha Charts and understand its extensibility capabilities
  • Create interactive HTML5 charts that are portable across the Web and touch/mobile
  • Deliver rich, professional, and engaging visualizations of complex, customized data including financial data, infographics, and so on
  • Understand the basic building blocks and the overall architecture of Sencha Charts
  • Get to grips with SVG and Canvas APIs to draw basic geometrical shapes
  • Create different types of charts, such as cartesian, polar, and spacefilling, in your application using outofbox charts from Sencha Charts
  • Compare Sencha Charts with other charting libraries/SDKs
Estimated delivery fee Deliver to Malta

Premium delivery 7 - 10 business days

€32.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : May 30, 2015
Length: 214 pages
Edition : 1st
Language : English
ISBN-13 : 9781785289767
Category :
Languages :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to Malta

Premium delivery 7 - 10 business days

€32.95
(Includes tracking information)

Product Details

Publication date : May 30, 2015
Length: 214 pages
Edition : 1st
Language : English
ISBN-13 : 9781785289767
Category :
Languages :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 99.97
Learning Ext JS_Fourth Edition
€41.99
Ext JS Application Development Blueprints
€36.99
Sencha Charts Essentials
€20.99
Total 99.97 Stars icon
Banner background image

Table of Contents

10 Chapters
1. Fundamentals of Sencha Charts Chevron down icon Chevron up icon
2. Working with Out-of-the-box Charts Chevron down icon Chevron up icon
3. Sencha Charts Architecture Chevron down icon Chevron up icon
4. Creating a Custom Cartesian Chart Chevron down icon Chevron up icon
5. Creating a Custom Polar Chart Chevron down icon Chevron up icon
6. Creating a Custom Spacefilling Chart Chevron down icon Chevron up icon
7. Theming Chevron down icon Chevron up icon
8. Working with Touch Gestures Chevron down icon Chevron up icon
9. Comparison with Other JavaScript Charting Libraries Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Rating distribution
Full star icon Full star icon Full star icon Full star icon Full star icon 5
(1 Ratings)
5 star 100%
4 star 0%
3 star 0%
2 star 0%
1 star 0%
Philip Arad Sep 02, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
If you are an Ext JS or Sencha Touch developer who wants to build enterprise-scale data visualization using Sencha, this book is ideal for you.Sencha Charts is a new and powerful library used to create rich and beautiful charts for your Mobile Sencha Touch and Ext JS applications. Built in HTML5, Sencha Charts is optimized for performance and fully support gestures and touch devices on mobile, thus making visualizing data effortless.With your knowledge of HTML, JavaScript, CSS, and Sencha Ext JS or Sencha Touch fundamentals, you will be able to upgrade your application on desktop and mobile, to meet enterprise standard.First in the book, you will get familiar with charting fundamentals and then engage with the Sencha Charts architecture. You will then learn how to use out-of-the-box charts, and then create your own custom Cartesian, polar, and space filling charts to visualize your own data.Finally, you will see how Sencha Charts compares with other charting libraries for all your data expression needs.During your studies you will discover out-of-the-box enterprise visualizations, develop your own custom charts and learn to make your charts work on desktop and touch-sensitive devicesYou will create interactive HTML5 charts that are portable across the Web and touch/mobile and deliver rich, professional, and engaging visualizations of complex, customized data including financial data, infographics, and so on.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela