Sencha Touch – Polar Chart


RadarChartAll

Problem Statement

Sencha Touch has been growing stronger and with the introduction of Charting & Drawing capability as a part of the main SDK, it has just become better than before. However, the chart documentation still needs certain improvement to make things further easier for the intended audience. As part of this article I am taking a dig at the PolarChart and in that process I am also going to touch few common topics which are often used when we talk about charts.
Polar Chart
The polar chart is similar to a usual pie chart with following differences

  • the angles are equal (in pie chart angles may be different)
  • different sectors may have different distances from the centre (in pie chart all the sectors have same radial distance) (i.e. different spoke length). The data length of a spoke is proportional to the magnitude of the variable for the data point relative to the maximum magnitude of the variable across all data points.

The polar chart is often used to plot cyclic phenomena such as

  • Number of children born during different months of a given year
  • Number of employees leaving a company during different quarters of the year
  • Share price of a script at the end of every month
  • etc

I have taken Radar series as an example to demonstrate polar chart.

Prerequisite

  • Sencha Touch 2.2
  • A Sencha Touch project

A project with basic panel

app.html
app

app.js

Ext.Loader.setConfig({
	src : 'sdk/src'
});

Ext.application({
    views: [
        'ChartPanel'
    ],
    name: 'MyApp',
    launch: function() {
        Ext.create('MyApp.view.ChartPanel', {fullscreen: true});
    }
});

ChartPanel.js

 Ext.define('MyApp.view.ChartPanel', {
    extend: 'Ext.Panel',
    config: {
		layout : 'fit',
		html : 'Simple Panel'
    }
});

Make sure that you have set up your project with the above code and you are able to see the below screen (which will mean that you are ready to get started with the polar chart):

SimplePanel

Get Started

Now that we have got the basic project, let’s replace the html attribute of the panel inside ChartPanel.js with following code:

      
        items : [
			Ext.create( 'Ext.chart.PolarChart', {
			store: {
			  fields: ['name', 'Y1998' ],
			  data: [
				  {'name':'Jan', 'Y1998':10 },
				  {'name':'Feb', 'Y1998':7},
				  {'name':'March', 'Y1998':5},
				  {'name':'Apr', 'Y1998':2},
				  {'name':'May', 'Y1998':10 },
				  {'name':'Jun', 'Y1998':7},
				  {'name':'Jul', 'Y1998':5},
				  {'name':'Aug', 'Y1998':2},
				  {'name':'Sep', 'Y1998':20 },
				  {'name':'Oct', 'Y1998':10 },
				  {'name':'Nov', 'Y1998':17},
				  {'name':'Dec', 'Y1998':5}
			  ]
			},
			series: [{
				type: 'radar',
				xField : 'name',
				yField: 'Y1998' 
			}], 
			axes: [
			  {
				type: 'numeric',
				position: 'radial',
				fields: 'Y1998'
			  },
			   {
				type: 'category',
				position: 'angular',
				fields: 'name'
			  }
			]
		})
		]

In the above code we are creating an instance of the polar chart. The store contains all the months of the year and for the year 1998, the data contains the number of people joining a company in different months of that year.

As you must have observed, the polar chart needs a series and an axes to be able to work.

  • An axes, which can be of type numeric (for numeric (quantative) and continuous data), category (for showing finite set of information(categorical data)) or time (for continuous date / time data), allows you to see a reference against which you will be visualizing the actual data. Depending on the type of the data that you want to display, you select appropriate axes layout.
    • For a given data type, you may like to represent them into various ways. For example if you want to show polar data (which is based on polar coordinates – i.e. angle and radius), then you need to select “radial” position.
    • Sencha touch supports following positions for axes:
      •  For cartesian representation
        • top
        • bottom
        • right
        • left
      • For polar representation
        • radial
        • angular
  • A series, which contains all the data points that need to be plotted on the chart. The series can be area, bar, candlestick, cartesian, gauge, line, pie, pie3d, radar, scatter or any of your custom series. Different types of charts can work with different kinds of series. Here we have selected radar as series. Sencha touch also provides other polar charts like pie and pie3d.

Now let’s run our sample and visualize the result:

RadarBasic_1

Not bad! We have got the numeric values radially and the month names on angular positions.  However, we don’t see all the month names. Also, instead of showing numbers in steps of 5, it would be nice to see in steps of 2 as visualization becomes easier.  Sencha Touch allows you to achieve just stated goal using estStepSize attribute of style object of axes. You need to modify axes definition as follows:

			axes: [
			  {
				type: 'numeric',
				position: 'radial',
				fields: 'Y1998',
				style: {
					estStepSize: 10
				}
			  },
			   {
				type: 'category',
				position: 'angular',
				fields: 'name',
				style: {
					estStepSize: 1
				}
			  }
			]

The estStepSize is used by Axes to return the estimated step size. In case of category, irrespective of whatever you pass, the preferredStep always returns { unit: 1, step: 1 } to indicate “show every item”. However, if you don’t provide the attribute estStepSize then it doesn’t show all the months. A bit strange, but now you know what you need to do in case you face this issue. In case of numeric axes refer to the preferredStep method on the link http://docs.sencha.com/touch/2-2/source/Numeric.html#Ext-chart-axis-segmenter-Numeric.

With above changes you see all the months and the numbers are defined at the distance of 2 as shown below:
RadarBasic_AllMonths

While we have got the axes in place, it will be good to have a clear indicator which will enable us to visualize the data length of a spoke. If we can have a circle drawn around the radial steps then it will be nice. Sencha Touch provides you grid attribute to achieve that. All you need to do is add “grid:true” in the numeric axes, as shown in below code:

 
			  {
				type: 'numeric',
				position: 'radial',
				fields: 'Y1998',
				style: {
					estStepSize: 10
				},
				grid: true
			  },

With above changes in place, you shall be able to see the required grid and with that the data visualization will definitely improve:

RadarBasic_NumericGrid

Further, you can pass a grid object to have a custom grid being drawn for you. For example – for the category access, instead of “grid:true”, if you pass below object you can control the appearance of odd and even rows and style them differently:

				grid : {
					odd: {
						stroke: '#555'
					},
					even: {
						stroke: '#ccc',
						'stroke-width': 2,
					}
				}

With above change in place, you will see a line corresponding to the angular position of the category axes, as shown in below image:
RadarBasic_AngularGrid

 

Visualizing the actual data

So far you have been able to setup axes and grid (which is of course based on the data). Now, in order to visualize the data of the series, you need to set the style object of the series as shown in below code:

 
                      series: [{
				type: 'radar',
				xField : 'name',
				yField: 'Y1998',
				style : {
					lineWidth: 2,
					fillStyle: 'rgba(155, 0, 255, .2)',
					strokeStyle: 'rgba(0, 255, 0, 1)'
				}
			}],

With above changes in place you get following radar chart:
RadarChart

Marker

By default the radar chart doesn’t show the markers on the graph. However, it will be really good to have the desired marker to give even a clear indicator. Sencha Touch provides you an attribute called “marker”.

Once you change you series configuration to following, the markers will be visible on the chart:

			series: [{
				type: 'radar',
				xField : 'name',
				yField: 'Y1998',
				title : 'First Year',
				// radius : 100,
				// rotation : 90,
				style : {
					lineWidth: 2,
					fillStyle: 'rgba(155, 0, 255, .2)',
					strokeStyle: 'rgba(0, 255, 0, 1)'
				},
				marker : {
					stroke: '#555',
					fill: '#4292C6',
					type : 'circle',
					radius: 5
				}
			}

			],

In above code, you will see that the marker is of type circle with radius 5. After applying above changes, following radar chart will be shown, which definitely enhances the data visualization:
RadarChart_Marker

Dragging a chart
Sencha Touch provides you an attribute called draggable through which you can allow dragging of the already drawn chart. Following is a sample configuration for the draggable attribute:

 
			draggable: {
				direction: 'horizontal',
				constraint: {
					min: {x: -100, y: 0},
					max: {x: 100, y: 0}
				},
				listeners: {
					dragstart: function(component, index, target, record, eventObject, options) {
						var elem = component.getElement();
						console.log("Dragging the polar chart!");
					}
				}
			},

Above configuration allows the graph to be moves 100 pixel to the right as well as left. Below screenshot shows a sample position during the drag (the chart is shifted towards left and console shows the desired message):
PolarChartDrag

 

Adding one more series

Sencha touch allows you to add as many series as you need in the polar chart. All you need is to add the series object in the series attribute array. When you replace your existing series definition with below code:

 
			series: [{
				type: 'radar',
				xField : 'name',
				yField: 'Y1998',
				title : 'First Year',
				// radius : 100,
				// rotation : 90,
				style : {
					lineWidth: 2,
					fillStyle: 'rgba(155, 0, 255, .2)',
					strokeStyle: 'rgba(0, 255, 0, 1)'
				},
				marker : {
					stroke: '#555',
					fill: '#4292C6',
					type : 'circle',
					radius: 5
				}
			},
			{
				type: 'radar',
				xField : 'name',
				yField: 'Y1999',
				style : {
					lineWidth: 2,
					fillStyle: 'rgba(155, 100, 0, .3)',
					strokeStyle: 'rgba(0, 0, 200, 1)'
				},
				marker : {
					stroke: '#555',
					fill: '#4200C6',
					type : 'ellipse',
					rx : 12,
					ry : 8
				}
			}
			],

You shall be see a radar chart with two set of data (corresponding to different years), as shown in below image:
RadarChart_TwoSeries
Inset Padding 

In the context of the chart, the inset padding is the padding from the boundary of the chart to any of its contents. In above image you might have noticed that it is extremely difficult to read Apr and Oct months. This is where I have used inset padding to give some space between the graph and its content so that I can see the axes details clearly. You need to add following configuration into the insetPadding attribute of the polarchart:

        insetPadding: {
            top: 20,
            left: 10,
            right: 10,
            bottom: 20
        },

With above code change in place, the graph looks like as shown below:
RadarChart_InsetPadding

Background
Now that you have got the basic radar chart, let’s add some background to this by adding following code into series object:

                               background : {
					fill: '#9ACA00',
					opacity : .6				
				}

While in above code I have just filled the background with the color and opacity, you can very well use gradient or images. You may like to refer to below link for gradient related example :
http://docs.sencha.com/touch/2-1/#!/api/Ext.chart.AbstractChart-cfg-background
Note
In case you have multiple series then you must add the background declaration in the last series object.

Animation
If you want to change the animation behaviour of the chart then you can do so using the animate property. In case you don’t want to see animation then you do need to set “animate : false”. By default the animation is true with duration of 500 ms and easing type set to ‘ease’. I have changed the animation object to following:

			animate : {
				duration : 4000,
				easing : 'cubic-bezier(10, 10, 40, 40)'
			},

Here duration of animation is 4000 and easing is achieved through bezier curve (which gives really cool animation).

Interaction
Sencha Touch provides you an optional module called Interactions, which can be plugged in to a chart to allow the user to interact with the chart and its data in special ways. For example we can make use of rotate interaction to rotate the radar chart. For this you need to set following attribute of the polar chart:

interactions: ['rotate'],

Depending on the chart type and user’s need, you can select other interactions types like iteminfo, itemhighlight, crosszoom, panzoom, rotatePie3D, etc. You may like to refer to below link for more detail about interactions:

http://docs.sencha.com/touch/2-2/#!/api/Ext.chart.AbstractChart-cfg-interactions

With all above changes in place the ChartPanel.js has following code:

 
Ext.define('MyApp.view.ChartPanel', {
    extend: 'Ext.Panel',

    config: {
		layout : 'fit',
        items : [
			Ext.create( 'Ext.chart.PolarChart', {
			animate : {
				duration : 1000,
				easing : 'cubic-bezier(0, 0, 50, 50)'
			},
			interactions: ['rotate'],
			draggable: {
				direction: 'horizontal',
				constraint: {
					min: {x: -100, y: 0},
					max: {x: 100, y: 0}
				},
				listeners: {
					dragstart: function(component, index, target, record, eventObject, options) {
						var elem = component.getElement();
						console.log("Dragging the polar chart!");
					}
				}
			},
			store: {
			  fields: ['name', 'Y1998', 'Y1999'],
			  data: [
				  {'name':'Jan', 'Y1998':10, 'Y1999':12 },
				  {'name':'Feb', 'Y1998':7, 'Y1999':19},
				  {'name':'March', 'Y1998':5, 'Y1999':13},
				  {'name':'Apr', 'Y1998':2, 'Y1999':16},
				  {'name':'May', 'Y1998':10, 'Y1999':10 },
				  {'name':'Jun', 'Y1998':7, 'Y1999':11},
				  {'name':'Jul', 'Y1998':5, 'Y1999':12},
				  {'name':'Aug', 'Y1998':2, 'Y1999':2},
				  {'name':'Sep', 'Y1998':20, 'Y1999':10 },
				  {'name':'Oct', 'Y1998':10, 'Y1999':14 },
				  {'name':'Nov', 'Y1998':17, 'Y1999':12},
				  {'name':'Dec', 'Y1998':5, 'Y1999':17}
			  ]
			},
			insetPadding: {
            top: 20,
            left: 10,
            right: 10,
            bottom: 20
        },
			series: [{
				type: 'radar',
				xField : 'name',
				yField: 'Y1998',
				title : 'First Year',
				// radius : 100,
				// rotation : 90,
				style : {
					lineWidth: 2,
					fillStyle: 'rgba(155, 0, 255, .2)',
					strokeStyle: 'rgba(0, 255, 0, 1)'
				},
				marker : {
					stroke: '#555',
					fill: '#4292C6',
					type : 'circle',
					radius: 5
				}
			},
			{
				type: 'radar',
				xField : 'name',
				yField: 'Y1999',
				style : {
					lineWidth: 2,
					fillStyle: 'rgba(155, 100, 0, .3)',
					strokeStyle: 'rgba(0, 0, 200, 1)'
				},
				marker : {
					stroke: '#555',
					fill: '#4200C6',
					type : 'ellipse',
					rx : 12,
					ry : 8
				},
				background : {
					fill: '#9ACA00',
					opacity : .6				
				}
			}

			], 
			axes: [
			  {
				type: 'numeric',
				position: 'radial',
				fields: 'Y1998',
				style: {
					estStepSize: 10
				},
				grid: true
			  },
			   {
				type: 'category',
				position: 'angular',
				fields: 'name',
				style: {
					estStepSize: 1
				},
				grid : {
					odd: {
						stroke: '#555'
					},
					even: {
						stroke: '#ccc',
						'stroke-width': 2,
					}
				}
			  }
			]
		})
		]
    }
});

When you view the radar chart, you shall be able to see background as well as animation. Following image shows the final radar chart using above code:
RadarFinal

Summary

As part of this article you got to know how to use Sencha Touch’s polar chart. You learnt about the basic building blocks like axes and series and you also came to know about the custom interaction module. Further you came to know about styling and animating the graph. I hope you have enjoyed reading this article and you are able to apply this learning to meet your business need.

At Walking Tree we practice and recommend Sencha Products like ExtJS and Sencha Touch to build amazing web / touch apps. In case you are looking for training or professional assistance, contact us by visiting our website.

Reference

Tagged with: , , , , , , ,
Posted in Sencha Touch
One comment on “Sencha Touch – Polar Chart
  1. Alok Ranjan says:

    Sencha Touch also allows you to handle resizing behaviour of your chart. In this article, whenever you resize the browser, the chart resizes itself based the available area. However, if you have any specific need to handle resize of the browser then Sencha Touch provides you a configuration called “resizeHandler”. For example, when you write below code inside your graph:
    resizeHandler : function() {
    console.log(‘Handle Resize’);
    return false;
    },

    it will print the “Handle Resize” text on user’s console. Of course, when you resize, the size of the graph will not change.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

We Have Moved Our Blog!

We have moved our blog to our company site. Check out https://walkingtree.tech/index.php/blog for all latest blogs.

Sencha Select Partner Sencha Training Partner
Xamarin Authorized Partner
Do More. With Sencha.

Recent Publication
%d bloggers like this: