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

Здравствуйте. Я представляю одну из ведущих танцевальных онлайн-радиостанций в России — 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. Также, независимо от версии, могут возникнуть проблемы с передачей большого массива объектов, графики могут просто не построиться.
Share post

Comments 12

    +1
    Я тоже прикупил highcharts для своей cms, у меня работает во всех браузерах, в том числе на айподе и айпаде
      0
      Но у меня другой тип графиков, и данных немного
        +1
        Highcharts это немного другой продукт. Он появился раньше стока, думаю багов там поменьше, и кроссбраузерная совместимость лучше.
          0
          Для непросвященных — в чем различия?
            0
            Насколько я понял, когда выбирал, что именно использовать/приобрести — это ориентированность HighStock на биржевые типы чартов, которые требуют несколько другого поведения и отображения (чего только стоит range в подвале, который позволяет гибко регулировать основное окно данных). Но расплата за это — отсутствие популярных «небиржевых» типов, таких, как stacked column и т.п.
              0
              Лично для меня, разница во встроенном навигаторе, с ним гораздо удобнее.
          0
          А ещё есть AmCharts.
          Очень симпатичный продукт.
          Мы использовали Flash-версию, сейчас перешли на чистый js.
            0
            Jquery Flot — очень удобно, плюс подробная документация.
            Работает на основе canvas.
              0
                0
                Во-первых, не всегда удобно или возможно использовать Google Charts API, если вам необходимо обеспечить работу веб-приложения при отсутствии доступа к интернету (и серверам гугла соответственно). Во-вторых, вы уверены, что все данные можно без зазрения совести отдавать на гугловские сервера? :)
                  0
                  Да я просто в общую копилку добавил )
                  А вообще — там данные в гугл (насколько я понял) не отдаются. Там с гугловского cdn'а их лоадером загружается библиотека и уже она табличные данные преобразует в графики. Так что не все так плохо.

                  А библиотека чудесная. Строит в свг (работает даже в ие6), поддерживает что угодно (в т.ч. реалтайм — всегда можно передать новые данные и вызвать redraw, или даже указать для данных внешний источник и выставить интервал обновления), неплохо кастомизируется.

                  С передачей данных у них старые чарты были, которые графики отдавали в виде картинки.
                    0
                    Ну, для этого уже очень давно существует HighCharts. Строит в SVG, умеет VML (для IE6). Умеет обновляться в реалтайме (причём с анимацией), легко конфигурируется и имеет вполне вменяемую документацию.

                    Короче, рекомендую. Пробовал, понравилось.

                    Что же касается паранойи, это данные сейчас не отдаются :) Но пока библиотека лежит на гугловском CDN и загружается оттуда ни в чём нельзя быть уверенным наверняка ;)

              Only users with full accounts can post comments. Log in, please.