Pull to refresh

Динамические графики на основе highstock

Reading time 4 min
Views 23K
Здравствуйте. Я представляю одну из ведущих танцевальных онлайн-радиостанций в России — FreshBeat Radio.

У нас, как у интернет-радио, есть одно огромное преимущество перед FM вещанием. Нам не надо проводить дорогостоящие исследования рынка, чтобы узнать количество слушателей, их местоположение, длительность и частоту прослушивания.

Мы постоянно имеем доступ к огромному количеству статистических данных, которые можно и нужно использовать для того чтобы еще больше соответствовать своей целевой аудитории. Перед тем как проанализировать данные по слушателям, их нужно собрать и систематизировать так, чтобы с ними было удобно работать.

В этой статье, я расскажу вам о том, как это визуализировать и периодически обновлять с помощью Highstock. На Хабрахабре уже было несколько статей про этот набор инструментов, но все они описывали работу только со статическими данными.

Сбор данных


В нашем случае, вся необходимая информация обрабатывается php скриптом, который парсит стандартную страницу icecast со всеми нужными данными и формирует массив значений (для каждого из аудио потоков нужно получить кол-во слушателей).

Т.к. нас интересует только значение по оси Y, мы выбрали самый простой простой формат, который принимает Highstock. Для динамического графика передавать значение X бессмысленно, т.к. мы используем текущее время в качестве значения для новой точки.
На выходе php скрипта получаем данные в формате JSON:
[214,2,13,2,35,0,0,65,97]


Получение данных


Сразу после загрузки страницы нужно получить данные и настроить график. Отправляем ajax запрос, в callback функции создаем серии точек (графики) для каждого потока. Каждый из них заполняем первой точкой, и скрываем все графики, кроме общего (сумма всех потоков). В качестве значения X устанавливаем текущее время в формате Unix timestamp.
var seriesOptions=[], data=[], chart;

$(function() {
    $.getJSON('protected/live_values.php', function(lst) {
        time = (new Date()).getTime()+14400000; //текущее время (utc+4)
		
		//общий график
		data.push({x:time, y:lst[0]});
                seriesOptions[0] = {
	           name: '/all',
    	           data: data
	        };
		data=[];
		
		//все остальные графики, скрываем их
		for (i=1; i<9; i++) {
	        data.push({x:time, y:lst[i]});
	        seriesOptions[i] = {
	            name: 'series '+i,
    	            data: data,
		    visible: false
	        };
	        data=[];
	    };   
	    createChart();
    });
});


Построение графиков


После этого создаем и настраиваем графики на основе полученных данных. В основном эти настройки скрывают лишние элементы. Покажу только основные из них:
function createChart() {
	chart = new Highcharts.StockChart({
		series: seriesOptions,
                //Заголовок вверху страницы
		title: {text: 'Live Statistics Viewer v0.8'},
                //максимальное увеличение по оси Х 30 секунд 
		xAxis: {maxZoom: 30000},
                //ступенчатый вид графиков
		plotOptions: {line: {step: true}},

Формируем вид подсказки при наведении на точку графика. Скрываем всё, кроме времени и количества слушателей. Немного увеличиваем текст.
tooltip: {
            yDecimals: 0,
            xDateFormat: '%H:%M:%S',
            headerFormat: '<span style="font-size: 12px">{point.key}</span>',
            pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b>'
},

Также форматируем селектор увеличения графиков. Годы и месяцы нам не нужны, оставляем только 3 периода, максимальный — 15 минут.
rangeSelector: {
	        buttons: [
			    {type: 'minute', count: 1, text: '1m'},
			    {type: 'minute', count: 5, text: '5m'},
			    {type: 'minute', count: 15, text: '15m'},
			    {type: 'all', text: 'All'}
			],
	        selected: 0
},

Для переключения графиков обязательно нужна легенда. В настройках указываем положение, ориентацию и отступы между элементами.
legend: {
            enabled: true,
            layout: 'vertical',
            align: 'right',
            verticalAlign: 'top',			
            x: -10,
            y: 60,
	    itemStyle: {padding: '10px'}
},

В Highstock есть возможность экспорта в картинку или печать графиков. Оставляем только печать и экспорт в png:
exporting: {
		    type: 'image/png',
                    buttons: {
			    exportButton: {
				    menuItems: null,
					onclick: function() {
					    this.exportChart();
					}
				}
			}
}


Динамическое добавление точек


Наконец, самое главное. Указываем функцию, которая будет добавлять точки, и задаем интервал её вызова в миллисекундах. Графики обновляются очень быстро, хоть каждые 50 мс. Тут же указываем имя div, в который будут выводиться графики.

chart: {
			renderTo: 'containerlive',
		        zoomType: 'x',
			events: {
				load: function() {
					setInterval(load, 50);
				}
			}
		}
	});
};

Эта функция отправляет такой же ajax запрос, как и при инициализации графиков. В качестве параметров для метода addPoint указываем текущее время и количество слушателей для каждого потока. Если нужно по достижению какого-либо количества точек сдвигать график, то последнее значение в методе addPoint меняем на true.
function load() {
    $.getJSON('protected/live_values.php', function(lst) {
	    x = (new Date()).getTime()+14400000;
	    for (i=0; i<9; i++)
	        chart.series[i].addPoint([x, lst[i]], true, false); 
    });
};


Вот и всё


Для вывода графика на html страницу подключаем наш js скрипт, jquery, сам highstock и модуль экспорта к нему. Ну и создаем div с id равным тому, который указали при настройке графика.

Результат


График обновлялся, примерно, в течение часа:

Несколько графиков:


Highstock очень мощная штука, но довольно капризная. Например, последняя версия 1.1.0 некорректно работает в хроме, даже на официальном сайте. Поэтому в своём проекте я пока использую версию 1.0.2. Также, независимо от версии, могут возникнуть проблемы с передачей большого массива объектов, графики могут просто не построиться.
Tags:
Hubs:
+15
Comments 12
Comments Comments 12

Articles