Невозможно отобразить метки оси X в многостолбцовом массиве mysql в Highcharts

У меня есть база данных mysql, содержащая несколько столбцов значений мощности, захваченных с течением времени, причем время захвачено в первом столбце. Я хотел бы построить значения мощности и отобразить время суток на оси X диаграммы Highcharts. В настоящее время я могу отображать несколько значений Power на оси Y, но я не могу отобразить время суток на диаграмме. Вот код PHP, который частично работает:

<?php
// Connect to database
$con = mysqli_connect("localhost","userid","passwd","power_readings");
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }

// Set the variable $rows to the columns Energy_Date and Total_watts
$query = mysqli_query($con,"SELECT Energy_Date,Total_watts FROM combined_readings");
$rows = array();
$rows['name'] = 'Total_watts';
while($tmp = mysqli_fetch_array($query)) {
  $rows['data'][] = $tmp['Total_watts'];
}

// Set the variable $rows1 to the columns Energy_Date and Power_watts
$query = mysqli_query($con,"SELECT Energy_Date,Power_watts FROM combined_readings");
$rows1 = array();
$rows1['name'] = 'Neurio_watts';
while($tmp = mysqli_fetch_array($query)) {
    $rows1['data'][] = $tmp['Power_watts'];
}

// Set the variable $rows2 to the columns Energy_Date and Solar_watts
$query = mysqli_query($con,"SELECT Energy_Date,Solar_watts FROM combined_readings");
$rows2 = array();
$rows2['name'] = 'Solar_watts';
while($tmp = mysqli_fetch_array($query)) {
    $rows2['data'][] = $tmp['Solar_watts'];
}

$result = array();
array_push($result,$rows);
array_push($result,$rows1);
array_push($result,$rows2);

print json_encode($result, JSON_NUMERIC_CHECK);

mysqli_close($con);
?>

Может ли кто-нибудь сказать мне, как изменить код для правильной передачи значений из столбца времени суток?

Вот как сейчас выглядит график:

Объединенные значения мощности

Когда я внес изменения в PHP, чтобы добавить поле «Energy_Date» в массив, переданный в Highcharts (показанный ниже), это привело к пустой диаграмме.

Массив состоит из полей, которые выглядят следующим образом (отметка времени, за которой следует значение мощности, разделенное точкой):

"2018-02-21 16:56:00.052","2018-02-21 16:59:00.052","2018-02-21 17:02:00.039","2018-02-21 17:05:00.039","2018-02-21 17:08:00.039"

<?php
// Connect to database
$con = mysqli_connect("localhost","userid","passwd","power_readings");
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }

// Set the variable $rows to the columns Energy_Date and Total_watts
$query = mysqli_query($con,"SELECT Energy_Date,Total_watts FROM combined_readings");
$rows = array();
$rows['name'] = 'Total_watts';
while($tmp = mysqli_fetch_array($query)) {
  $rows['data'][] = $tmp['Energy_Date'].$tmp['Total_watts'];
}

// Set the variable $rows1 to the columns Energy_Date and Power_watts
$query = mysqli_query($con,"SELECT Energy_Date,Power_watts FROM combined_readings");
$rows1 = array();
$rows1['name'] = 'Neurio_watts';
while($tmp = mysqli_fetch_array($query)) {
    $rows1['data'][] = $tmp['Energy_Date'].$tmp['Power_watts'];
}

// Set the variable $rows2 to the columns Energy_Date and Solar_watts
$query = mysqli_query($con,"SELECT Energy_Date,Solar_watts FROM combined_readings");
$rows2 = array();
$rows2['name'] = 'Solar_watts';
while($tmp = mysqli_fetch_array($query)) {
    $rows2['data'][] = $tmp['Energy_Date'].$tmp['Solar_watts'];
}

$result = array();
array_push($result,$rows);
array_push($result,$rows1);
array_push($result,$rows2);

print json_encode($result, JSON_NUMERIC_CHECK);

mysqli_close($con);
?>

HTML-код, получающий этот массив, выглядит так:

<!DOCTYPE html>
<html lang="en">
<title>Combined Values Graph</title>
<head>
 <meta http-equiv="refresh" content="180">
 <meta charset="utf-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
 <script type="text/javascript">
         $(function () {
             var x_values = [];
             var chart;
             $(document).ready(function() {
                 Highcharts.setOptions({
                     colors: ['#4083e9', '#99ccff', '#00ffff', '#e6e6e6', '#DDDF00', '#64E572', '#FF9655', '#FFF263', '#6AF9C4']
                 });

                 $.getJSON("values.php", function(json) {

                     chart = new Highcharts.Chart({
                         chart: {
                             renderTo: 'mygraph',
                             type : 'spline',
                             borderWidth: 1,
                             zoomType: 'x',
                             panning: true,
                             panKey: 'shift',
                             plotShadow: false,
                             marginTop: 100,
                             height: 500,
                             plotBackgroundImage: 'gradient.jpg'
                         },
                         plotOptions: {
                             series: {
                                 fillOpacity: 1
                             }
                         },
                         plotOptions: {
                             series: {
                                marker: {
                                     enabled: false
                                }
                             }
                         },
                         title: {
                             text: 'Combined Power Readings'

                         },
                         subtitle: {
                             text: 'Total = Neurio + Solar Readings in Watts'

                         },
                         xAxis : {
                             title : {
                                 text : 'Time of Day'
                             }
                         },
                         yAxis: {
                             title: {
                                 text: 'Power (watts)'
                             },
                             plotLines: [{
                                 value: 0,
                                 width: 2,
                                 color: '#ff0000',
                                 zIndex:4,
                                 dashStyle: 'ShortDot'
                             }]
                         },
                         tooltip: {
                             formatter: function() {
                                     return '<b>'+ this.series.name +'</b><br/>'+
                                     this.x +': '+ this.y;
                             }
                         },
                         legend: {
                             layout: 'vertical',
                             align: 'right',
                             verticalAlign: 'top',
                             x: -10,
                             y: 120,
                             borderWidth: 1
                         },
                         plotOptions : {
                             spline : {
                                 marker : {
                                     radius : 0,
                                     lineColor : '#666666',
                                     lineWidth : 0
                                 }
                             }
                         },
                         series: json
                         });
                 });

             });

         });
 </script>
 <script src="https://code.highcharts.com/highcharts.src.js"></script>
 <script src="http://code.highcharts.com/modules/exporting.js"></script>

</head>
<body>
<div class="container" style="margin-top:20px">
 <div class="col-md-10">
  <div class="panel panel-primary">
    <div class="panel-body">
     <div id ="mygraph"></div>
    </div>
  </div>
 </div>
</div>
</body>
</html>

Я добавил оператор консоли в конец js следующим образом:

                 series: json
                 });
                 console.log(json);
         });

Вот что показано в консоли браузера для PHP версии 1 (версия, в которой отображаются графики).

Консоль браузера 1

Вот что показано в консоли браузера для PHP версии 2 (версия, которая дает пустую диаграмму).

Консоль браузера 2

Спасибо за ваши полезные предложения. Я изменил циклы while, чтобы они выглядели так:

while($tmp = mysqli_fetch_array($query)) {
  $rows['data'][] = $tmp['Energy_UTC'];
  $rows['data'][] = $tmp['Total_watts'];
}

Вывод PHP теперь выглядит так:

[{"name":"Total_watts","data":[1519315164,93,1519315344,354]},{"name":"Neurio_watts","data":[1519315164,76,1519315344,309]},{"name":"Solar_watts","data":[1519315164,17,1519315344,45]}]

Данные, передаваемые в Highcharts (из консоли), теперь выглядят так:

Консоль браузера 3

Диаграмма по-прежнему неверна: ось X не показывает временные метки, и диаграмма неверна. Может ли кто-нибудь предложить, как изменить PHP или html, чтобы исправить это?

Хорошо, я обновил циклы while, чтобы они выглядели так:

$query = mysqli_query($con,"SELECT Energy_UTC,Total_watts FROM combined_readings");
$rows = array();
$rows['name'] = 'Total_watts';
while($tmp = mysqli_fetch_array($query)) {
  $rows['data'][] = [$tmp['Energy_UTC'],$tmp['Total_watts']];
}

Вывод PHP теперь выглядит так:

[{"имя":"Всего_ватт","данные":[[1519387869,423],[1519388049,423],[1519388229,332],[1519388410,514],[1519388590,514]...

и на диаграмме теперь отображаются временные метки UTC для каждого значения мощности.


person tgraf2    schedule 21.02.2018    source источник
comment
можете ли вы добавить вывод print json_encode($result, JSON_NUMERIC_CHECK); это поможет нам добавить ответ   -  person Deep 3015    schedule 22.02.2018
comment
Или добавьте console.log(json) в JS, чтобы мы могли видеть, что передается в Highcharts.   -  person Paweł Fus    schedule 22.02.2018
comment
Как вы можете видеть, ваш набор данных неверен, здесь у вас есть две проблемы: 1) значения x - это строковые даты, которые должны быть временными метками (числом). 2) Ваши обновленные данные содержат только значения x, а не значения y. Данные должны выглядеть так data: [ [1519280220000, 233], [ ..., ... ], [ ..., ... ] ]   -  person Paweł Fus    schedule 22.02.2018
comment
Обновленные данные фактически состоят из значений x и y, разделенных точкой: 2018-02-22 07:17:00.0233. Я могу изменить дату строки на отметку времени UTC, но мне не удалось отформатировать оператор while, чтобы вставить запятую, как вы предложили. Можете ли вы предложить, как следует изменить оператор while, чтобы исправить это?   -  person tgraf2    schedule 22.02.2018
comment
@tgraf2 Хорошо. Не уходи. Исправим и эту хрень. Это много, чтобы прочитать, но я могу помочь вам в этом. Знаете ли вы, какой результат вы пытаетесь получить, чтобы заставить HighCharts работать должным образом, или вы не знаете, как должен выглядеть data?   -  person mickmackusa    schedule 23.02.2018


Ответы (1)


Вы пишете большой блок кода со многими повторяющимися компонентами. Я потратил время, чтобы высушить ваш метод. Лучше всего свести к минимуму обращения к базе данных, поэтому мне удалось объединить ваши запросы в один простой выбор.

Теоретически вам нужно будет изменить только $colnames_labels, чтобы изменить ваш HighChart. Я написал встроенные комментарии, чтобы помочь вам понять, что делает мой фрагмент. Я написал несколько основных проверок ошибок, чтобы помочь вам отладить, если что-то не работает.

Код: (не проверено)

$colnames_labels=[
    'Total_watts'=>'Total_watts',
    'Power_watts'=>'Neurio_watts',
    'Solar_watts'=>'Solar_watts'
];

$select_clause_ext='';                            // declare as empty string to allow concatenation
foreach($colnames_labels as $colname=>$label){
    $data[]=['name'=>$label];                     // pre-populate final array with name values
    // generates: [0=>['name'=>'Total_watts'],1=>['name'=>'Neurio_watts'],2=>['Solar_watts']]
    $select_clause_ext.=",$colname";
    // generates: ",Total_watts,Power_watts,Solar_watts"
}

$subarray_indexes=array_flip(array_keys($colnames_label));  // this will route resultset data to the correct subarray
// generates: ['Total_watts'=>0,'Power_watts'=>1,'Solar_watts'=>2]

if(!$result=mysqli_query($con,"SELECT UNIX_TIMESTAMP(Energy_Date) AS Stamp{$select_clause_ext} FROM combined_readings ORDER BY Energy_Date")){
    $data=[['name'=>'Syntax Error (query error)','data'=>[0,0]];  // overwrite data with error message & maintain expected format
}elseif(!mysqli_num_rows($result)){
    $data=[['name'=>'Logic Error (no rows)','data'=>[0,0]];
}else{
    while($row=mysqli_fetch_assoc($result)){
        foreach($subarray_indexes as $i=>$col){
            $data[$i]['data'][]=[$row['Stamp'],$row[$col]];  // store [stamp,watts] data in appropriate subarrays
        }
    }
}

echo json_encode($data,JSON_NUMERIC_CHECK);  // Convert to json (while encoding numeric strings as numbers) and print to screen
person mickmackusa    schedule 23.02.2018
comment
Спасибо за ваши усилия и предложения mickmackusa. Мой код теперь на 90% правильный. Перед заменой хочу настроить. - person tgraf2; 23.02.2018