Integrating with other Frameworks

Exclusive offer: get 50% off this eBook here
Highcharts Cookbook

Highcharts Cookbook — Save 50%

80 hands-on recipes to create, integrate, and extend dynamic and interactive charts in your web projects with this book and ebook

€19.99    €10.00
by Nicholas Terwoord | March 2014 | Cookbooks

In this article by Nicholas Terwood, the author of Highcharts Cookbook, there exists a wide variety of different tools and frameworks spanning different languages and paradigms, and this list of tools continues to grow and expand. This article examines a few of the more popular tools and gives us some idea on how to integrate these different tools with highcharts.

In this article, we will cover:

  • Using NodeJS as a data provider
  • Using Django as a data provider
  • Using Flask / Bottle as a data provider
  • Integrating with Backbone
  • Using AngularJS data-bindings and controllers

(For more resources related to this topic, see here.)

Using NodeJS as a data provider

JavaScript has become a formidable language in its own right. Google's work on the V8 JavaScript engine has created something very performant, and has enabled others to develop Node.js, and with it, allow the development of JavaScript on the serverside. This article will take a look at how we can serve data using NodeJS, specifically using a framework known as express.

Getting ready

We will need to set up a simple project before we can get started:

  1. Download and install NodeJS (http://nodejs.org/download/).
  2. Create a folder nodejs for our project.
  3. Create a file nodejs/package.json and fill it with the following contents:

    {
    "name": "highcharts-cookbook-nodejs",
    "description": "An example application for using highcharts
    with nodejs",
    "version": "0.0.1",
    "private": true,
    "dependencies": {
    "express": "3.4.4"
    }
    }

  4. From within the nodejs folder, install our dependencies locally (that is, within the nodejs folder) using npm (NodeJS package manager):

    npm install

    If we wanted to install packages globally, we could have instead done the following:

    npm install -g

  5. Create a folder nodejs/static which will later contain our static assets (for example, a webpage and our JavaScript).
  6. Create a file nodejs/app.js which will later contain our express application and data provider.
  7. Create a file nodejs/bower.json to list our JavaScript dependencies for the page:

    {
    "name": "highcharts-cookbook-chapter-8",
    "dependencies": {
    "jquery": "^1.9",
    "highcharts": "~3.0"
    }
    }

  8. Create a file nodejs/.bowerrc to configure where our JavaScript dependencies will be installed:

    { "directory": "static/js" }

How to do it...

Let’s begin:

  1. Create an example file nodejs/static/index.html for viewing our charts

    <html> <head> </head> <body> <div id='example'></div> <script src = './js/jquery/jquery.js'></script> <script src = './js/highcharts/highcharts.js'></script> <script type = 'text/javascript'>
    $(document).ready(function() { var options = {
    chart: { type: 'bar', events: {
    load: function () { var self = this; setInterval(function() {
    $.getJSON('/ajax/series', function(data) { var series = self.series[0];
    series.setData(data); }); }, 1000); } } }, title: { text: 'Using AJAX for polling charts'
    }, series: [{ name: 'AJAX data (series)', data: [] }] }; $('#example').highcharts(options); }); </script> </body> </html>

  2. In nodejs/app.js, import the express framework:

    var express = require('express');

  3. Create a new express application:

    var app = express();

  4. Tell our application where to serve static files from:

    var app = express(); app.use(express.static('static'));

  5. Create a method to return data:

    app.use(express.static('static')); app.get('/ajax/series', function(request, response) { var count = 10, results = []; for(var i = 0; i < count; i++) { results.push({ "y": Math.random()*100 }); } response.json(results); });

  6. Listen on port 8888:

    response.json(results); }); app.listen(8888);

  7. Start our application:

    node app.js

  8. View the output on http://localhost:8888/index.html

How it works...

Most of what we've done in our application is fairly simple: create an express instance, create request methods, and listen on a certain port.

With express, we could also process different HTTP verbs like POST or DELETE. We can handle these methods by creating a new request method. In our example, we handled GET requests (that is, app.get) but in general, we can use app.VERB (Where VERB is an HTTP verb). In fact, we can also be more flexible in what our URLs look like: we can use JavaScript regular expressions as well. More information on the express API can be found at http://expressjs.com/api.html.

Using Django as a data provider

Django is likely one of the more robust python frameworks, and certainly one of the oldest. As such, Django can be used to tackle a variety of different cases, and has a lot of support and extensions available. This recipe will look at how we can leverage Django to provide data for Highcharts.

Getting ready

  1. Download and install Python 2.7 (http://www.python.org/getit/)
  2. Download and install Django (http://www.djangoproject.com/download/)
  3. Create a new folder for our project, django.
  4. From within the django folder, run the following to create a new project:

    django-admin.py startproject example

  5. Create a file django/bower.json to list our JavaScript dependencies

    { "name": "highcharts-cookbook-chapter-8", "dependencies": { "jquery": "^1.9", "highcharts": "~3.0" } }

  6. Create a file django/.bowerrc to configure where our JavaScript dependencies will be installed.

    { "directory": "example/static/js" }

  7. Create a folder example/templates for any templates we may have.

How to do it...

To get started, follow the instructions below:

  1. Create a folder example/templates, and include a file index.html as follows:

    {% load staticfiles %} <html> <head> </head> <body> <div class='example' id='example'></div> <script src = '{% static "js/jquery/jquery.js" %}'></script> <script src = '{% static "js/highcharts/highcharts.js" %}'></script> <script type='text/javascript'> $(document).ready(function() { var options = { chart: { type: 'bar', events: { load: function () { var self = this; setInterval(function() { $.getJSON('/ajax/series', function(data) { var series = self.series[0]; series.setData(data); }); }, 1000); } } }, title: { text: 'Using AJAX for polling charts' }, series: [{ name: 'AJAX data (series)', data: [] }] }; $('#example').highcharts(options); }); </script> </body> </html>

  2. Edit example/example/settings.py and include the following at the end of the file:

    STATIC_URL = '/static/' TEMPLATE_DIRS = ( os.path.join(BASE_DIR, 'templates/') ) STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static/'), )

  3. Create a file example/example/views.py and create a handler to show our page:

    from django.shortcuts import render_to_response def index(request): return render_to_response('index.html')

  4. Edit example/example/views.py and create a handler to serve our data:

    import json from random import randint from django.http import HttpResponse from django.shortcuts import render_to_response def index(request): return render_to_response('index.html') def series(request): results = [] for i in xrange(1, 11): results.append({ 'y': randint(0, 100) }) json_results = json.dumps(results) return HttpResponse(json_results, mimetype='application/json')

  5. Edit example/example/urls.py to register our URL handlers:

    from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() import views urlpatterns = patterns('', # Examples: # url(r'^$', 'example.views.home', name='home'), # url(r'^blog/', include('blog.urls')), url(r'^admin/', include(admin.site.urls)), url(r'^/?$', views.index, name='index'), url(r'^ajax/series/?$', views.series, name='series'), )

  6. Run the following command from the django folder to start the server: python example/manage.py runserver
  7. Observe the page by visiting http://localhost:8000
Highcharts Cookbook 80 hands-on recipes to create, integrate, and extend dynamic and interactive charts in your web projects with this book and ebook
Published: March 2014
eBook Price: €19.99
Book Price: €32.99
See more
Select your format and quantity:

Using Flask / Bottle as a data provider

Many different microframeworks have emerged to tackle small, specific problems that developers may have. In the Python world, there are two prominent examples: Flask, and Bottle. Flask and Bottle are very similar, and so in this recipe we examine how we can use either as a data provider for Highcharts.

Getting ready

First, we will need to setup Python:

  1. Download and install Python 2.7 (http://www.python.org/getit/)
  2. Download and install Flask (http://flask.pocoo.org)
  3. Download and install Bottle (http://bottlepy.org/)
  4. Create a folder flask_bottle for our project.
  5. Create a file flask_bottle/bower.json to list our JavaScript dependencies

    { "name": "highcharts-cookbook-chapter-8", "dependencies": { "jquery": "^1.9", "highcharts": "~3.0" } }

  6. Create a file flask_bottle/.bowerrc to configure where our JavaScript dependencies will be installed.

    { "directory": "static/js" }

How to do it...

To get started, follow the instructions below:

  1. Create a file static/index.html as follows:

    <html> <head> </head> <body> <div id='example'></div> <script src = './js/jquery/jquery.js'></script> <script src = './js/highcharts/highcharts.js'></script> <script type = 'text/javascript'> $(document).ready(function() { var options = { chart: { type: 'bar', events: { load: function () { var self = this; setInterval(function() { $.getJSON('/ajax/series', function(data) { var series = self.series[0]; series.setData(data); }); }, 1000); } } }, title: { text: 'Using AJAX for polling charts' }, series: [{ name: 'AJAX data (series)', data: [] }] }; $('#example').highcharts(options); }); </script> </body> </html>

  2. Create a file server.py and create a Flask instance:

    from flask import Flask app = Flask(__name__)

  3. Create a route to serve our data:

    from flask import Flask app = Flask(__name__) @app.route('/ajax/series') def series(): return None

  4. Return some data in our route:

    from flask import Flask, Response import json import random app = Flask(__name__) @app.route('/ajax/series') def series(): series = [] for x in xrange(0,11): series.append({ 'y': random.randint(0,100) }) return Response(json.dumps(series), mimetype='application/json')

  5. If the file is run as an executable, run our application in debug mode:

    from flask import Flask, Response import json import random app = Flask(__name__) @app.route('/ajax/series') def series(): series = [] for x in xrange(0,11): series.append({ 'y': random.randint(0, 100) }) return Response(json.dumps(series), mimetype='application/json') if __name__ == '__main__': app.run(debug=True)

  6. Start the server:

    python server.py

  7. Visit http://localhost:5000/static/index.html

How it works...

app.route is a decorator we can apply to python methods to handle HTTP requests. In addition to specifying the path, we can also specify which HTTP methods we want to handle (e.g. app.route('/path', methods=['GET']) to just handle GET requests).

Flask will automatically server files from the static folder at http://localhost:5000/static, which is why we did not need to add any special configuration to see index.html.

Integrating with Backbone

In addition to serverside microframeworks, a number of client-side microframeworks have also appeared. Many aim to provide a simple means to send data from end-to-end with a clear separation of concerns. In this recipe, we'll take a look at Backbone, specifically, integrating with its models (an abstraction of our interface with a backend) and collections (a means of managing multiple models).

Getting ready

We will need to make some small changes.

  1. Create a folder, backbone, for our project, and setup a basic project in that folder as described above.
  2. Modify backbone/bower.json as follows:

    { "name": "highcharts-cookbook-chapter-8", "dependencies": { "highcharts": "~3.0", "jquery": "^1.9", "underscore": "^1.5", // Used by Backbone, functional programming "backbone": "~1.1.0", // Model-view-controller library for JavaScript "backbone.localStorage": "~1.1.7"
    // Handles persistence using brower's localStorage
    } }

  3. Install our dependencies from within the backbone folder:

    bower install

How to do it...

To get started, follow the instructions below:

  1. Create our skeleton HTML file, backbone/index.html:

    <!doctype html> <html> <head> <script src = './bower_components/jquery/jquery.js'></script> <script src = './bower_components/highcharts/highcharts.src.js'></script> <script src = './bower_components/highcharts/
    highcharts-more.src.js'></script> <script src = './bower_components/underscore/underscore.js'></script> <script src = './bower_components/backbone/backbone.js'></script> <script src = './bower_components/backbone.localStorage/
    backbone.localStorage.js'></script> <script src = './example.js'></script> <style type='text/css'> #monsters { list-style: none; padding: 0px; } #monsters li { margin-bottom: 5px; } #monsters .card { clear: both; padding: 10px; border: 1px solid #aaa; } #monsters .card .graph { float: left; width: 300px; height: 300px; } #monsters .card .stats .row > label { display: inline-block; width: 100px; font-size: 1.0em; text-transform: capitalize; } #monsters .card .stats .row > input { width: 50px; padding: 5px; text-align: right; font-size: 1.2em; } </style> </head> <body> <div id='main'> <input id='monster-name' type='text' /> <input id='new-monster' type='button'
    value='Create New Monster' /> <ul id='monsters'> </ul> </div> </body> </html>

  2. Create a template for our model instances:

    <!doctype html> <html> <head> <!-- … --> </head> <body> <div id='main'> <!-- … --> </div> <script type='text/template' id='monster-template'> <div class='card'> <div class='graph' id='monster-<%= stats.name %>'> </div> <div class='stats'> <h2><%= stats.name %> <input class='feed'
    type='button' value='Feed Me!' /></h2> <% var keys = ['hp', 'attack', 'defense', 'special_attack',
    'special_defense', 'speed']; %> <% var key_stats = _.chain(stats).pick(keys).value(); %> <% _.each(key_stats , function(value, key) { %> <div class='row'> <label for='<%= key %>'><%= key %></label> <input type='text' name='<%= key %>' value='<%= value %>' /> </div> <% }); %> </div> </div> </script>
    </body> </html>

  3. Create a file backbone/example.js, and include an immediate function using jQuery:

    $(function() { });

  4. Define a Backbone model:

    $(function() { var Monster = Backbone.Model.extend({ defaults: { name: 'Unknown', height: 0.0, weight: 0.0, hp: 0, attack: 0, defense: 0, special_attack: 0, special_defense: 0, speed: 0 } }); });

  5. Define a Backbone collection:

    $(function() { //... var MonsterCollection = Backbone.Collection.extend({ model: Monster , localStorage: new Backbone.LocalStorage("example") }); });

  6. Create a MonsterCollection:

    $(function(){ // ... var MonsterCollection = Backbone.Collection.extend(/* … */); var Monsters = new MonsterCollection(); });

  7. Create a view for our Monster model. This will handle interaction with our model as well as make any changes to the UI for a model:

    $(function() { // ... var MonsterView = Backbone.View.extend({ tagName: 'li', template: _.template($('#monster-template').html()), initialize: function () { this.listenTo(this.model, 'change', this.render); }, render: function() { this.$el.html(this.template({ 'stats': this.model.toJSON() })); return this; } }); });

  8. Create a view for our application in general

    $(function() { // ... var AppView = Backbone.View.extend({ el: $('#main'), events: { 'click #new-monster': 'createMonster', 'keypress #monster-name': 'createMonster' }, initialize: function() { this.listenTo(Monsters, 'add', this.addMonster); }, createMonster: function(event) { var $name = $('#monster-name'); if (event.type === 'keypress' && event.keyCode !== 13) { return; } if (!$name.val()) { return; } Monsters.create({name: $name.val()}); $name.val(''); }, addMonster: function(monster) { var view = new MonsterView({model: monster}); this.$("#monsters").append(view.render().el); }, }); });

  9. Create an instance of our application view

    $(function() { // ... var App = new AppView(); });

  10. Modify MonsterView.render to render our highchart:

    var MonsterView = Backbone.View.extend({ // … chartOptions: { chart: { polar: true, type: 'line' }, legend: { enabled: false }, xAxis: { tickmarkPlacement: 'on', labels: { overflow: 'justify', style: { fontSize: '10px' } } }, yAxis: {gridLineInterpolation: 'polygon', min: 0}, tooltip: { pointFormat: '<span style="color:series.color}
    ">{series.name}: <b>{point.y:,.0f}</b><br/>' } }, render: function() { this.$el.html(this.template({ 'stats': this.model.toJSON() })); // get the key stats from the model var key_stats = this.model.pick([ 'hp', 'attack', 'defense', 'special_attack', 'special_defense', 'speed' ]); // turn those stats into a highcharts data series var series = _.chain(key_stats).map(function(value, key) { return parseInt(value, 10); }); // extend the default options var options = _.extend(this.chartOptions, { title: { text: this.model.get('name') }, xAxis: { categories: _.chain(key_stats).keys().value() }, series: [{ data: series.value() }] }); this.$('.graph').highcharts(options); return this; }, });

  11. Modify MonsterView to handle us changing the different stats:

    var MonsterView = Backbone.View.extend({ // ... events: { 'keyup .row input': 'statChange' }, statChange: function(event) { // figure out which element this is from var $target = this.$(event.target) // get the text value from the element var value = parseInt($target.val(), 10); var key = $target.attr('name'); if (!_.isNumber(value) || _.isNaN(value) || value < 0) { return; } // update the underlying model this.model.set(key, value); } });

How it works...

Our models and collections are fairly straightforward, especially as there is presently no backend interaction: we only store information in a local copy of our models. Our models only contain some simple information, a set of default values, and our collection only has one really interesting piece, the key model which defines what type of models this collection holds.

Most of the interesting work in our example comes from our two views. Backbone is able to handle events after we've defined either a template (as we did in our MonsterView) or an existing element with el (as we did in AppView). After that, we're able to register events via the events object using jQuery-like selectors of the form '<event> <selector>': 'function_name'.

Summary

In this article we looked at some of the more popular Web frameworks and tools and how we can get them up and running with Highcharts.

Resources for Article:


Further resources on this subject:


Highcharts Cookbook 80 hands-on recipes to create, integrate, and extend dynamic and interactive charts in your web projects with this book and ebook
Published: March 2014
eBook Price: €19.99
Book Price: €32.99
See more
Select your format and quantity:

About the Author :


Nicholas Terwoord

Nicholas Terwoord is a software developer, professional geek, and graduate from the University of Waterloo with a Bachelor of Computer Science (Honors). When not developing software, which is not often, he can be found helping his wife, Amanda, with her business, or more likely working his way through a growing list of distractions on Steam. He can be reached at http://nt3r.com.

He is happily employed at Willet Inc., a company in Kitchener, Ontario that develops Second Funnel, a marketing solution for brands, and online retailers. More information can be found at http://secondfunnel.com

Books From Packt


Instant Highcharts [Instant]
Instant Highcharts [Instant]

Learning Highcharts
Learning Highcharts

The Business Analyst's Guide to Oracle Hyperion Interactive Reporting 11
The Business Analyst's Guide to Oracle Hyperion Interactive Reporting 11

Oracle Hyperion Interactive Reporting 11 Expert Guide
Oracle Hyperion Interactive Reporting 11 Expert Guide

IPython Interactive Computing and Visualization Cookbook
IPython Interactive Computing and Visualization Cookbook

Statistical Analysis with R
Statistical Analysis with R

Oracle E-Business Suite Financials R12: A Functionality Guide
Oracle E-Business Suite Financials R12: A Functionality Guide

Google Visualization API Essentials
Google Visualization API Essentials

Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software