Category: Technology, Web-Applications
Tags: Chart, Charts, Javascript
Visualizing data in your web application can be achieved by using many frameworks. In one recent project the customer wanted to have an application that helps analyzing data provided by gas stock exchange markets. It was crucial to not use a flash based framework and to provide interactivity for the user.
I had to choose between libraries like Flot, FusionCharts, JS Charts, Emprise JS Charts and Highcharts. After some analysis these 5 Javascript libraries provide all functionality needed to generate interactive charts. But only Highcharts combines functionality, a very stable interface and a rich set of API methods with an eye pleasing design.
Have a look at this chart where data is shown for 2 years. Highcharts includes a very powerful tooltip function and makes it easy to implement your own functionality (like computing the moving average or providing custom zoom levels).

Here the code. Should be easy enough to understand. First the HTML:
[html]
[/html]
And then the Javascript to include.
[javascript]
var masterchart, detailchart;
var lastprice, lastdate;
var year = 2011;
function clearSeries(chart) {
if (chart.series.length>1) {
chart.series[1].remove(true);
}
}
function movingAverage(chart,range, days) {
$.getJSON(‘chart/moving-average-simple’,
{parameter : range, days : days, year : year},
function(data) {
start = data[0];
end = data[1];
chart.xAxis[0].setExtremes(start, end);
clearSeries(chart);
chart.addSeries(
{
type: ‘line’,
name: ‘Moving average for ‘ + range,
data : data[2],
color: ‘#FC0C10′,
lineWidth: 1
}
);
masterchart.xAxis[0].removePlotBand(‘mask-before’);
masterchart.xAxis[0].addPlotBand({
id: ‘mask-before’,
from: start,
to: end,
color: ‘rgba(0, 0, 0, 0.2)’
});
});
}
function loadMasterChart() {
options = {
chart: {
renderTo: ‘master-chart-container’,
defaultSeriesType: ‘line’,
zoomType: ‘x’,
height: 80,
margin: [10, 55, 16, 55],
events: {
selection: function(event) {
ex = event.xAxis[0];
detailchart.xAxis[0].setExtremes(ex.min, ex.max);
masterchart.xAxis[0].removePlotBand(‘mask-before’);
masterchart.xAxis[0].addPlotBand({
id: ‘mask-before’,
from: ex.min,
to: ex.max,
color: ‘rgba(0, 0, 0, 0.2)’
});
return false;
}
}
},
tooltip : {
formatter: function() {
return ” + Highcharts.numberFormat(this.y, 2) + ‘ EUR am ‘
+ Highcharts.dateFormat(‘%d.%m.%Y’, this.x);
}
},
title: {
text: null
},
exporting: {
enabled:false
},
legend: {
enabled:false
},
credits: {
enabled:false
},
xAxis: {
type: ‘datetime’,
min: Date.UTC(year-1, 8, 1),
max: Date.UTC(year, 11, 31),
maxZoom: 14 * 24 * 3600000, // fourteen days, 1000msec*60sec*60min
title: {
text: null
},
plotBands: [{
id: 'mask-before',
from: Date.UTC(year-1, 8, 1),
to: Date.UTC(year, 11, 31),
color: 'rgba(0, 0, 0, 0.2)'
}]
/*labels: {
formatter: function() {
return Highcharts.dateFormat(‘%m/%y’, this.value);
}
}*/
},
yAxis: {
title: {
text: null
},
min: 0.1,
startOnTick: true,
endOnTick : true,
showFirstLabel: false
},
plotOptions: {
line: {
dataLabels: {
enabled: false
},
enableMouseTracking: false,
lineWidth: 1,
marker: {
enabled: false,
states: {
hover: {
enabled: false
}
}
}
}
},
series: []
};
masterchart = new Highcharts.Chart(options);
}
function loadDetailChart() {
options = {
chart: {
renderTo: ‘detail-chart-container’,
defaultSeriesType: ‘line’,
zoomType: ”,
height: 300
},
tooltip : {
formatter: function() {
return ” + Highcharts.numberFormat(this.y, 2) + ‘ EUR am ‘
+ Highcharts.dateFormat(‘%d.%m.%Y’, this.x);
}
},
title: {
text: null
},
legend: {
enabled:false
},
credits: {
enabled: false
},
xAxis: {
type: ‘datetime’,
min: Date.UTC(year, 0, 1),
max: Date.UTC(year, 11, 31),
maxZoom: 14 * 24 * 3600000, // fourteen days, 1000msec*60sec*60min
title: {
text: ‘Datum’
}
/*labels: {
formatter: function() {
return Highcharts.dateFormat(‘%m/%y’, this.value);
}
}*/
},
yAxis: {
title: {
text: ‘EUR / MWh’
},
min: 0.1,
startOnTick: true,
endOnTick : true,
showFirstLabel: false
},
plotOptions: {
line: {
dataLabels: {
enabled: false
},
enableMouseTracking: true,
lineWidth: 1,
marker: {
enabled: false,
states: {
hover: {
enabled: true
}
}
}
}
},
series: []
};
detailchart = new Highcharts.Chart(options);
}
function loadData(onlydata) {
$.getJSON(‘/load/chart-data’, function(data) {
masterchart.addSeries(
{
type: ‘line’,
data : data,
color : ‘#25597E’
}
);
detailchart.addSeries(
{
type: ‘line’,
data : data,
color : ‘#0099FF’
}
);
});
}
function preloadTheme() {
Highcharts.setOptions({
colors: ['#0099FF', '#0099FF', '#ED561B', '#DDDF00',
'#24CBE5', '#64E572',
'#FF9655', '#FFF263', '#6AF9C4'],
chart: {
borderWidth: 0,
plotBackgroundColor: ‘rgba(255, 255, 255, .9)’,
plotShadow: false,
plotBorderWidth: 1,
margin : [12, 55, 20, 55]
},
title: {
style: {
color: ‘#000′,
font: ‘bold 16px “Trebuchet MS”, Verdana, sans-serif’
}
},
subtitle: {
style: {
color: ‘#666666′,
font: ‘bold 12px “Trebuchet MS”, Verdana, sans-serif’
}
},
xAxis: {
gridLineWidth: 1,
lineColor: ‘#000′,
tickColor: ‘#000′,
labels: {
style: {
color: ‘#000′,
font: ’11px Trebuchet MS, Verdana, sans-serif’
}
},
title: {
style: {
color: ‘#333′,
fontWeight: ‘bold’,
fontSize: ’12px’,
fontFamily: ‘Trebuchet MS, Verdana, sans-serif’
}
}
},
yAxis: {
minorTickInterval: ‘auto’,
lineColor: ‘#000′,
lineWidth: 1,
tickWidth: 1,
tickColor: ‘#000′,
labels: {
style: {
color: ‘#000′,
font: ’11px Trebuchet MS, Verdana, sans-serif’
}
},
title: {
style: {
color: ‘#333′,
fontWeight: ‘bold’,
fontSize: ’12px’,
fontFamily: ‘Trebuchet MS, Verdana, sans-serif’
}
}
},
legend: {
itemStyle: {
font: ’9pt Trebuchet MS, Verdana, sans-serif’,
color: ‘black’
},
itemHoverStyle: {
color: ‘#039′
},
itemHiddenStyle: {
color: ‘gray’
}
},
labels: {
style: {
color: ‘#99b’
}
}
});
}
$(document).ready(function() {
preloadTheme();
loadData(false);
});
[/javascript]