[Модификация] Строим графики Highstock

Вносятся изменения в файлы или устанавливаются доп программы

Модераторы: immortal, newz20

eygen
Сообщения: 393
Зарегистрирован: Чт сен 25, 2014 5:37 pm
Откуда: Екатеринбург
Благодарил (а): 25 раз
Поблагодарили: 52 раза

Re: Строим графики Highstock

Сообщение eygen » Вс мар 22, 2015 8:05 pm

Bagir писал(а):
скринПоказать
Изображение
кодПоказать

Код: Выделить всё

<script type="text/javascript" src="../../highcharts/js/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="../../highcharts/js/highstock.js"></script>
<script type="text/javascript">

$(function () {
    var seriesOptions = [],
          obsss = 0,
          seriesCounter = 0,
          timeback = 0,
          names = ['кухня','гостиная','спальня','холл','кабинет'], 
          sensornames = ['KitchenArea.Temperature', 
                                    'Livingroom.Temperature', 
                                    'Bedroom.Temperature',
                                    'HallArea.Temperature',
                                    'OfficeRoom.Temperature'];

    Highcharts.setOptions({
        lang: {
            months: ['Январь','Февраль','Март','Апрель','Май','Июнь','Июль', 
                          'Август','Сентябрь','Октябрь','Ноябрь','Декабрь'],

            shortMonths: ['Янв','Фев','Мар','Апр','Май','Июн','Июл', 
                                     'Авг','Сен','Окт','Ноя','Дек'],

            weekdays: ['Вск','Пнд','Втр','Срд','Чтв','Птн','Сбт'],

            rangeSelectorZoom: 'Маcштаб',
            rangeSelectorFrom: 'От',
            rangeSelectorTo: 'До',
            thousandsSep: ' '
        },
            global: {
                useUTC: false
            }
    });

    // create the chart when all data is loaded
    createChart = function () {
        $('#container').highcharts('StockChart', {


           rangeSelector: {
                buttons: [{ type: 'hour',    count: 1, text: '1h' },
                               { type: 'day',     count: 1, text: '1d' },
                               { type: 'day',     count: 2, text: '2d' },
                               { type: 'week',   count: 1, text: '1w' },
                               { type: 'month', count: 1, text: '1m' },
                               { type: 'month', count: 6, text: '6m' },
                               { type: 'year',    count: 1, text: '1y' },
                               { type: 'all', text: 'All' }],
                selected: 1  // Какая кнопка выбрана по умолчанию
            },
  
            title: { text : 'График температур в доме'},
            legend: { enabled : true,
                           layout : 'horizontal',
                           align : 'center',
                           verticalAlign : 'top',
                           borderWidth: 0,
                           x : 0,
                           y : 20 },

            xAxis : {
                minRange: 3600 * 1000 // one hour
            },

            yAxis: {
                title: {
                    text: 'Температура (°C)'
                }
            },

            plotOptions: {
                series: {
                    lineWidth: 1,
                    point: {
                        events: {
                            'click': function () {
                                if (this.series.data.length > 1) {
                                    this.remove();
                                }
                            }
                        }
                    }
                }
            },

            exporting: {
                enabled: false
            },

            series: seriesOptions
        });
    };

    $.each(names, function (i, name) {
        $.getJSON('/objects/?script=jconhs&name='+sensornames[i]+'&callback=?', function (data) {

            seriesOptions[i] = {
                name: name,
                data: data,
                type: 'spline'
            };

            // As we're loading the data asynchronously, we don't know what order it will arrive. So
            // we keep a counter and create the chart when all the data is loaded.
            seriesCounter += 1;

            if (seriesCounter === names.length) {
                createChart();
            }
        });
    });

});





$(function () {
    var seriesOptions = [],
          obsss = 0,
          seriesCounter = 0,
          timeback = 0,
          names = ['кухня', 'гостиная', 'спальня', 'кабинет'], 
          sensornames = ['KitchenArea.Humidity', 
                                    'Livingroom.Humidity', 
                                    'Bedroom.Humidity',
                                    'OfficeRoom.Humidity'];

    Highcharts.setOptions({
        lang: {
            months:   ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 
                            'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],

            shortMonths:   ['Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 
                                     'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'],

            weekdays: ['Вск', 'Пнд', 'Втр', 'Срд', 'Чтв', 'Птн', 'Сбт'],

            rangeSelectorZoom: 'Маcштаб',
            rangeSelectorFrom: 'От',
            rangeSelectorTo: 'До',
            thousandsSep: ' '
        },
            global: {
                useUTC: false
            }
    });


    // create the chart when all data is loaded
    createChart2 = function () {
        $('#container2').highcharts('StockChart', {

            rangeSelector: {
                buttons: [{ type: 'hour',    count: 1, text: '1h' },
                               { type: 'day',     count: 1, text: '1d' },
                               { type: 'day',     count: 2, text: '2d' },
                               { type: 'week',   count: 1, text: '1w' },
                               { type: 'month', count: 1, text: '1m' },
                               { type: 'month', count: 6, text: '6m' },
                               { type: 'year',    count: 1, text: '1y' },
                               { type: 'all', text: 'All' }],
                selected: 1  // Какая кнопка выбрана по умолчанию
            },
  
            title: { text : 'График влажности воздуха'},
            legend: { enabled : true,
                           layout : 'horizontal',
                           align : 'center',
                           verticalAlign : 'top',
                           borderWidth: 0,
                           x : 0,
                           y : 20 },

            xAxis : {
                minRange: 3600 * 1000 // one hour
            },

            yAxis: { title: { text: 'Влажность (%)' } },

            plotOptions: {
                series: {
                    lineWidth: 1,
                    point: {
                        events: {
                            'click': function () {
                                if (this.series.data.length > 1) {
                                    this.remove();
                                }
                            }
                        }
                    }
                }
            },

            exporting: {
                enabled: false
            },

            series: seriesOptions
        });
    };

    $.each(names, function (i, name) {
        $.getJSON('/objects/?script=jconhs&name='+sensornames[i]+'&callback=?', function (data) {

            seriesOptions[i] = {
                name: name,
                data: data
            };

            // As we're loading the data asynchronously, we don't know what order it will arrive. So
            // we keep a counter and create the chart when all the data is loaded.
            seriesCounter += 1;

            if (seriesCounter === names.length) {
                createChart2();
            }
        });
    });

});
</script>

<div id="container" style="height: 400px; min-width: 500px"></div>
<div id="container2" style="height: 400px; min-width: 500px"></div>
Код конечно для примера. Во второй группе изменены имена container2 и createChart2.
Спасибо дружище, получилось все в лучшем виде. :) Думается данный пример не мне одному интересен.
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Строим графики Highstock

Сообщение Bagir » Вс мар 22, 2015 8:43 pm

Да не за что ))
В этой теме еще очень много точек не расставлено. Я планировал потом вернуться к ее изучению. Данных в базе у меня уже достаточно, чтобы попробовать пример с 1,7 млн точек. Данные подгружаются при изменении масштаба.
Еще очень интересный пример с динамическим обновлением. График будет двигаться сам. Я пробовал этот пример на случайных точках. Надо будет подумать, как прикрутить его на реальные данные.
За это сообщение автора Bagir поблагодарил:
visitor2100 (Вт мар 24, 2015 12:27 am)
Рейтинг: 1.16%
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
eygen
Сообщения: 393
Зарегистрирован: Чт сен 25, 2014 5:37 pm
Откуда: Екатеринбург
Благодарил (а): 25 раз
Поблагодарили: 52 раза

Re: Строим графики Highstock

Сообщение eygen » Вс мар 22, 2015 8:46 pm

Bagir писал(а):Да не за что ))
В этой теме еще очень много точек не расставлено. Я планировал потом вернуться к ее изучению. Данных в базе у меня уже достаточно, чтобы попробовать пример с 1,7 млн точек. Данные подгружаются при изменении масштаба.
Еще очень интересный пример с динамическим обновлением. График будет двигаться сам. Я пробовал этот пример на случайных точках. Надо будет подумать, как прикрутить его на реальные данные.
Держи в курсе, по возможности буду у себя испытывать )))
За это сообщение автора eygen поблагодарил:
visitor2100 (Вт мар 24, 2015 12:26 am)
Рейтинг: 1.16%
visitor2100
Сообщения: 19
Зарегистрирован: Пт фев 20, 2015 5:24 pm
Благодарил (а): 5 раз
Поблагодарили: 1 раз

Re: Строим графики Highstock

Сообщение visitor2100 » Вт мар 24, 2015 12:26 am

Спасибо. Пригодилось.
Urbas81
Сообщения: 289
Зарегистрирован: Вс сен 16, 2012 9:39 am
Благодарил (а): 0
Поблагодарили: 1 раз

Re: Строим графики Highstock

Сообщение Urbas81 » Ср мар 25, 2015 4:41 pm

Спасибо за описание, я периодически стремился к этому года 2, но так и не смог слепить все в кучу. Сегодня благодаря этой теме получилось. Удалось реализовать и с помощью jsonp.php и через сценарии, теперь вопрос в плане быстродействия есть какая-то разница как получать данные, просто через jsonp.php мне кажется проще, т.к не надо комментировать index.php в папке objects. У меня кстати не работало пока не закоментировал еще и строчку

Код: Выделить всё

 //echo "\nRequest: ".$request; 
Еще в самом начале столкнулся с проблемой отсутствия графика как и Vit, пока искусственнно не ограничил количество точек в запросе иначе ничего не строилось, или же надо очень долго ждать, т.к у меня уже второй год данные пишутся, кто будет повторять обратите внимание. У меня если брать 11 датчиков и период неделя график появляется примерно через минуту, но у меня температура пишется каждую минуту.
Дальше хотелось бы динамическую подгрузку все таки организовать, чтоб можно было весь период просматривать. Я так понимаю нужно дополнительные таблицы составлять и в них заносить усредненный данные например за день считать среднюю температуру, за неделю, месяц и т.д.
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Строим графики Highstock

Сообщение Bagir » Ср мар 25, 2015 5:19 pm

Не могу утверждать без проведения замеров, но вроде бы вариант на сценарии работает быстрее. Да и не сторонник я привешивать разные свои финтиплюшки к системе, если можно обойтись штатными возможностями. Если что то где то и прикручиваю, так это в основном из-за нехватки знаний работы системы.

Код: Выделить всё

//echo "\nRequest: ".$request;   
Это уже есть в обновлениях, и самим комментировать не придется. Актуально только для тех, у кого не обновляется система.

Главная беда, при которой не строится график - это битые данные в истории. Возможно где то пустота или буква вместо цифры. Если данных и графиков очень много, то конечно будет подтормаживать. Есть отличный пример 1,7 млн. точек. Там данные как раз динамически подгружаются по выбранному периоду. Я пробовал его. Но в моей базе данных было очень мало. Поэтому до конца не доделав, этот код из примера я убрал, чтобы сделать его более понятным. Да и не всегда он нужен. Но отдельным примером конечно выложить надо. Через месяц уйду в отпуск, там и займусь этой темой вплотную, если кто нибудь не решит задачку раньше.
Ускорить можно будет дважды:
Первым ускорителем будет подгрузка итогов групп данных из этой же базы по средствам sql. Не стоит его недооценивать, штука довольно шустрая. График при этом будет шевелиться очень быстро, но время на загрузку данных сильно не уменьшится.
Второй ускоритель - промежуточные итоговые таблицы, которые будут периодически заполняться php скриптами. Способ не всегда удобный. И надо хорошенько подумать, где он может быть необходим.
В любом случае анализ скорости получения итогов средствами sql даст много ответов.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Строим графики Highstock

Сообщение Bagir » Ср мар 25, 2015 5:26 pm

Еще по поводу

Код: Выделить всё

 //echo "\nRequest: ".$request;   
Эта строка просто писала имя скрипта в ответе при его вызове. Удалив ее у нас появилась возможность использовать сценарии как генератор ответа.
При работе сценария можно собрать нужный ответ, скажем, в переменой $s, а в конце вывести его например так:

Код: Выделить всё

echo ($s);
Так что теперь мы получили еще один замечательный инструмент, пригодный не обязательно только для этих графиков.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Urbas81
Сообщения: 289
Зарегистрирован: Вс сен 16, 2012 9:39 am
Благодарил (а): 0
Поблагодарили: 1 раз

Re: Строим графики Highstock

Сообщение Urbas81 » Ср мар 25, 2015 5:35 pm

А как изменить часовой пояс на графике, сейчас у меня на графике отставание на 2 или 3 часа?
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Строим графики Highstock

Сообщение Bagir » Ср мар 25, 2015 5:38 pm

Мне помогает вот этот кусочек кода из примера, чтобы график использовал мое время

Код: Выделить всё

           global: {
                useUTC: false
            }  
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Urbas81
Сообщения: 289
Зарегистрирован: Вс сен 16, 2012 9:39 am
Благодарил (а): 0
Поблагодарили: 1 раз

Re: Строим графики Highstock

Сообщение Urbas81 » Чт мар 26, 2015 10:15 am

Bagir писал(а):Мне помогает вот этот кусочек кода из примера, чтобы график использовал мое время

Код: Выделить всё

           global: {
                useUTC: false
            }
Кажется понял где косяк, я когда ограничивал число выборок, то использовал время текущее а надо было к нему добавить смещение вперед. Вроде заработало. А код у меня тоже

Код: Выделить всё

useUTC: false
Ответить