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

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

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

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

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

Сообщение Bagir » Чт фев 26, 2015 7:33 pm

Слова особенно не нужны, на скрине все видно. Уверен, что многие давно хотят это получить. Постараюсь написать по проще.
Изображение
1. Из обновления от 13.03.2015, которое уже выложено на github нам нужно, что бы при запуске сценариев не выводилась первой строка Running script:
Подробно посмотреть об этом можно тут
А если вкратце, то смотрим файл \objects\index.php, ищем строку echo "\nRunning script: ".$script; и комментируем ее //

2. Создайте новый сценарий с именем jconhs

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

 // Получить имя и проверить
 if ( isset($params['name'])  ) { $name = $params['name']; } else { returm; }
 // Разбить на объект и свойство
 $name = explode('.', $name);

 // Получить объект по имени
 $obj=getObject($name[0]); 
 // Получить id свойства
 $prop_id=$obj->getPropertyByName($name[1], $obj->class_id, $obj->id);
 // Получаем VALUE_ID для следующей таблицы
 $pvalue=SQLSelectOne("SELECT * FROM pvalues WHERE PROPERTY_ID='".$prop_id."' AND OBJECT_ID='".$obj->id."'");
 // Получаем таблицу
 $arr_s = SQLSelect("SELECT UNIX_TIMESTAMP(ADDED) as ADDED, VALUE FROM phistory WHERE VALUE_ID='".$pvalue['ID']."' ORDER BY ADDED");

 // Собрать структуру JSON
 $st = $params['callback'].'([';
 foreach($arr_s as $s) {
   if ($f) { $st .=','; }
   $st .= '['.$s['ADDED'].'000,'.$s['VALUE'].']' ;
   $f=1;
 }
 $st .= '])';

 // Ответ
 echo ($st); 


3. Создайте домашнюю страницу с кодом
КодПоказать

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

<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();
            }
        });
    });

});
</script>

<div id="container" style="height: 500px; min-width: 500px"></div>
4. Замените в коде Названия и имена Объект.Свойство на свои. Попробуйте для начала с одним графиком. Потом добавьте второй, и так далее. Не нарушайте структуру при редактировании!

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

          names = ['кухня','гостиная','спальня','холл','кабинет'], 
          sensornames = ['KitchenArea.Temperature', 
                                    'Livingroom.Temperature', 
                                    'Bedroom.Temperature',
                                    'HallArea.Temperature',
                                    'OfficeRoom.Temperature'];
 
Основная причина, по которой графики могут не строиться, это битые данные в истории свойства.
Тема с этими графиками подробно расписана тут http://smartliving.ru/forum/viewtopic.p ... 140#p14843 С тех пор много всего поменялось. Тут я выложил только самое основное.
За это сообщение автора Bagir поблагодарили (всего 7):
slgeo (Пт фев 27, 2015 1:33 am) • Vit (Вс мар 01, 2015 6:06 pm) • visitor2100 (Сб мар 14, 2015 9:46 am) • eygen (Вс мар 22, 2015 5:45 pm) • SergVl (Вт апр 21, 2015 1:03 pm) • astotskiy (Пн май 25, 2015 7:23 am) • kos (Вт июл 21, 2015 1:28 pm)
Рейтинг: 8.14%
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
PAV
Сообщения: 949
Зарегистрирован: Пт дек 06, 2013 11:30 am
Откуда: Москва
Благодарил (а): 68 раз
Поблагодарили: 94 раза

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

Сообщение PAV » Ср мар 11, 2015 11:01 am

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

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

Сообщение Bagir » Ср мар 11, 2015 1:05 pm

Посмотреть историю и самому удалить кривые данные. Например пустые значения вообще без цифр. У меня были такие, когда метод датчика растрепал )) Можно было бы добавить обработку в файл, который формирует jcon, но это сильно увеличит его время работы. Кстати, в скором будущем перенесу все содержимое этого файла в сценарий, и из html кода графиков буду обращаться уже к сценарию, а не к файлу. Не знаю почему я так сразу задумал. Наверное после темы MegaD )) Его может быть тоже можно перенести в сценарий. Надо будет попробовать.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
PAV
Сообщения: 949
Зарегистрирован: Пт дек 06, 2013 11:30 am
Откуда: Москва
Благодарил (а): 68 раз
Поблагодарили: 94 раза

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

Сообщение PAV » Чт мар 12, 2015 12:20 pm

А можно вот на пальцах объяснить?
Я полез в phpmyadmin - там черт ногу сломит, я даже простым способом не смог сделать сортировку по определенному свойству. Все запросами, а это ужас, как неудобно.
Пришлось экспортировать и смотреть в экселе.
Может есть пути более логичные, чтобы сразу в базе отсортировать свойство (температуру например) по значениям и выявить ошибки?
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

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

Сообщение Bagir » Чт мар 12, 2015 5:09 pm

В phpmyadmin очень удобно делать простые запросы чтобы смотреть данные. Конечно для этого нужно немножечко знать sql. Но если хочется способ по проще, он есть. Если для постройки графиков Вы использовали мой jsonp.php, то в браузере наберите запрос
http://localhost/jsonp.php?name=OfficeRoom.Temperature
где OfficeRoom.Temperature это нужное Объект.Свойство
В итоге получите весьма читаемый json, пригодный к анализу например в excel с помощью фильтров и функций для работы с текстом.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

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

Сообщение Bagir » Пт мар 13, 2015 12:26 am

Заменил файл jsonp.php на сценарий jconhs. Файл jsonp.php теперь больше не нужен, и его можно удалить!
В html коде надо везде поменять

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

$.getJSON('../../jsonp.php?name='+sensornames[i]+'&callback=?', function (data) { 
на

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

$.getJSON('/objects/?script=jconhs&name='+sensornames[i]+'&callback=?', function (data) { 
Еще там была лишняя неиспользуемая функция function afterSetExtremes(e) Ее тоже можно удалить. Смотрите новый код в первом сообщении.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
visitor2100
Сообщения: 19
Зарегистрирован: Пт фев 20, 2015 5:24 pm
Благодарил (а): 5 раз
Поблагодарили: 1 раз

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

Сообщение visitor2100 » Сб мар 14, 2015 9:45 am

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

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

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

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

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

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

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

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

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

скринПоказать
Изображение
кодПоказать

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

<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 поблагодарили (всего 2):
eygen (Вс мар 22, 2015 8:03 pm) • Ko/|xo3HUk (Ср май 10, 2017 1:50 pm)
Рейтинг: 2.33%
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Ответить