【问题标题】:Highcharts xAxis doesn't get the right time formatHighcharts xAxis 没有正确的时间格式
【发布时间】:2014-01-13 13:19:55
【问题描述】:

我创建了一个结合日期选择器的图表。从 SQL 数据库中获取数据,其中包含所选日期的 datetime、open、high、low、close。

我测试了格式化 xAxis 的每一种方法,以便未缩放的刻度间隔为 1 小时,例如 7:00 8:00 9:00...

我希望能够放大,以便最小间隔为 1 分钟,如 7:00 7:01 7:02...

第一个问题是,每个点的格式总是看起来像 yyyy-mm-dd hh:mm:ss。更改 tickInvterval 后,它看起来更好但仍然错误,并且无法进行 1 分钟间隔的缩放功能。 将数据库拆分为单个日期和时间列后,我解决了日期问题,但显然 highchart 仍然没有意识到它是一个时间轴,因为 xAxis 设置如下所示:(应该显示 hh:mm 但图表显示 hh:mm: ss)

xAxis: {
type: 'datetime',
dateTimeLabelFormats: {
minute: '%H:%M'},
tickInterval: 60},

至少这不是拆分数据库的意图,因为应该有一种方法可以在查询过程中将 sql datetime 更改为 javatime 格式。 我现在搜索了几天,但没有找到正确的答案......也许是因为我对这些东西太陌生...... :)

这是生成图表的代码:

$(document).ready(function() {
Highcharts.setOptions({
    global: {
    useUTC: false
    }
});
options = {
chart:{
zoomType: 'x',
    renderTo: 'container'
},
title: {
    text: 'Charts',
    style: {
    fontFamily: 'Verdana',
    fontSize: '20px',
    fontWeight: 'bold'
    }
    },
subtitle: {
    text: 'Chart 1',
 style: {
    fontFamily: 'Verdana',
    fontSize: '15px',
    fontWeight: 'bold'
    }
    },
xAxis: {
    type: 'datetime',
dateTimeLabelFormats: {
    minute: '%H:%M',
       },
tickInterval: 60
 },  
 yAxis: [{ 
        labels: {
                format: '{value}',
                style: {
                color: '#eeeeee'
                }
            },
            title: {
                text: 'Realtime',
                style: {
                color: '#eeeeee'
                }
            }
        }, { 
            title: {
    enabled: false,
            text: 'Graph1',
            style: {
                    color: '#4572A7'
                    }
            },
            labels: {
    enabled: false,
            format: '',
            style: {
            color: '#4572A7'
                }
            },
            opposite: true
        },{ 
            title: {
    enabled: false,
            text: 'Graph2',
            style: {
            color: '#89A54E'
                }
            },
    reversed: true,
            labels: {
    enabled: false,
            format: '',
            style: {
            color: '#89A54E'
                }
            },
            opposite: true
        }],
        tooltip: {
        backgroundColor: {
            linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
            stops: [
                [0, 'rgba(96, 96, 96, .8)'],
                [1, 'rgba(16, 16, 16, .8)']
                ]
            },
        borderWidth: 1,
            borderColor: '#666666',
        crosshairs: true,        
        shared: true,
        useHTML: true,
        dateTimeLabelFormats: {
                minute: '%H:%M'},
            style: {
                padding: 10,
                fontWeight: 'bold'
            },
            formatter: function() {
                var s = '<b><span style="font-size: 12px; color: #cccccc">'+ this.x +'</span></b>';
                $.each(this.points, function(i, point) {
                s += '<br/><br/><span style="font-size: 16px; color: #cccccc">'+  point.series.name +': '+ point.y +'</span>';
            });
            return s;
        },
        shared: true
    },
  legend: 
  {
    enabled: true,
itemStyle: {
 color: '#eeeeee',
}
  },
  credits:
  {
  enabled: false
  },
  plotOptions: {
   spline: {
                lineWidth: 4,
                states: {
                    hover: {
                        lineWidth: 5
                    }
                },
                marker: {
                    enabled: false
                },

     },
       area: {
                fillColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1},
                    stops: [
                        [0, 'rgb(204, 204, 204)'],
                        [1, 'rgba(204, 204, 204,0)']
                    ]
                },
                lineWidth: 1,
                marker: {
                    enabled: false
                },
                shadow: false,
                states: {
                    hover: {
                        lineWidth: 1
                    }
                },
                threshold: null
            }
        },
        series: [{
       name: 'Realtime',
      type: 'area',
      color: '#cccccc',
       data: []
   }, {
       name: 'Graph1',
       type: 'spline',
       yAxis: 1,
       color: '#0077cc',
       enableMouseTracking: false,

       data: []
    }, {
       name: 'Graph2',
        type: 'spline',
       yAxis: 2,
        color: '#89A54E',
       enableMouseTracking: false,

       data: []
    }]
    }
    $.getJSON('data.php', function(json) {

    val1 = [];
    val2 = [];
    val3 = [];
    $.each(json, function(key,value) {
    val1.push([value[0], value[1]]);
val2.push([value[0], value[2]]);
    val3.push([value[0], value[3]]);
    });

    options.series[0].data = json['data1'];
    options.series[1].data = json['data2'];
    options.series[2].data = json['data3'];
    options.xAxis.categories = json['datetime'];
    chart = new Highcharts.Chart(options);
 });


});

$(function() {
    $( "#datepicker" ).datepicker({
       beforeShowDay: $.datepicker.noWeekends,
       dateFormat: "yy-mm-dd",
           onSelect: function(dateText, inst) { 
        $.getJSON("data.php?dateParam="+dateText, function(json){
    val1 = [];
    val2 = [];
val3 = [];
            $.each(json, function(key,value) {
             val1.push([value[0], value[1]]);
             val2.push([value[0], value[2]]);
             val3.push([value[0], value[3]]);

    });
    options.series[0].data = json['data1'];
    options.series[1].data = json['data2'];
    options.series[2].data = json['data3'];
    options.xAxis.categories = json['datetime'];

    chart = new Highcharts.Chart(options);
    });
      }
    });
});

这里是php:

<?php
session_start();
?>

<?php
define('DB_SERVER',"localhost");
define('DB_NAME',"db");
define('DB_USER',"");
define('DB_PASSWORD',"");


$con = mysql_connect(DB_SERVER, DB_USER, DB_PASSWORD);

if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db(DB_NAME, $con);

if (isset($_GET["dateParam"])) {
$sql = mysql_query("SELECT datetime, open, high, close FROM data WHERE datetime LIKE '".$_GET["dateParam"]."%'");
} else {
$sql = mysql_query("SELECT datetime, open, high, close FROM data WHERE DATE(datetime) = CURDATE()");
}

while($r = mysql_fetch_array($sql)) {

$result['datetime'][] = $r['datetime'];
$result['data1'][] = $r['open'];
$result['data2'][] = $r['close'];
$result['data3'][] = $r['high'];

}

print json_encode($result, JSON_NUMERIC_CHECK);

mysql_close($con);
?>

【问题讨论】:

    标签: php sql datetime highcharts format


    【解决方案1】:

    您可以使用 tickPositioner 来动态计算刻度 http://api.highcharts.com/highstock#xAxis.tickPositioner

    【讨论】:

      【解决方案2】:

      您的tickInterval 非常小。它设置为 60 毫秒。如果您希望 tickInterval 为一分钟,您需要将其设置为乘以 10k:

      tickInterval: 60 * 10000
      

      这应该可以解决它,因为即使您说使用'%H:%M',您的分辨率也要小得多。

      编辑: 所以,有几件事。请参阅此jsFiddle。 你需要设置一个开始时间(总是好的做法),如果你不提供数据{x, y},你需要告诉它数据点之间的时间。为此,您需要:

      series: [{
          pointStart: Date.UTC(2010, 0, 1),
          pointInterval: 60000, //every minute there is data.
          name: 'Realtime',
          type: 'area',
          data: [8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500, 8500]
      }]
      

      重要的部分是pointStartpointInterval。我还在chart: {} 选项中将最大缩放级别设置为一分钟:

      maxZoom: 60000
      

      【讨论】:

      • 我几乎尝试过这个设置,但这会导致 xaxis 只显示 7:00:00 而没有其他标签......这就是为什么我认为问题可能是对日期时间的错误解释跨度>
      • @muipo,你能用一些有代表性的数据和你的图表代码放一个 jsFiddle 吗?
      • jsfiddle.net/muipo/7QfVS 我试图从我的代码中创建一个小提琴,但不知何故它不起作用:/
      • @muipo,这是你的小提琴的干净版本:jsfiddle.net/43YNM/1。您没有包含 jquery,并且有一些语法错误。我删除了一堆不重要的东西。所以,只有一个系列和一个 xAxis。一会儿看看。
      • 啊,我明白了,对不起,我第一次设置小提琴......但无论如何,xaxis问题仍然存在
      【解决方案3】:

      非常感谢,终于搞定了大部分功能,问题是

      options.xAxis.categories = json['datetime'];
      

      但是... :) 我收到的市场数据每天都缺少一些分钟数据,例如7:00、7:01、7:03 等。并且使用 xAxis 日期时间格式,Highchart 没有意识到这一点,只计算时间,例如最后显示的刻度是 21:40 而不是 22:00,因为它应该是。 这就是我想从数据库日期时间接收 x 值的原因,这显然是我做不到的。 有人有想法吗?

      这是目前为止的代码,运行良好:

      $(document).ready(function() {
      Highcharts.setOptions({
      
      });
      
          options = {
            chart: 
        {
          backgroundColor: {
           linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
           stops: [
              [0, 'rgb(51, 51, 51)'],
              [1, 'rgb(16, 16, 16)']
           ]
        },
          borderColor: '#666666',
          borderWidth: 1,
          borderRadius: 0,
          zoomType: 'x',
          maxZoom: 60000,
          renderTo: 'container'
        },
      
        title: 
        {
          text: 'Realtime',
          margin: 50,
          style: {
              fontFamily: 'Verdana',
              fontSize: '20px',
              fontWeight: 'bold',
              color: '#cccccc'
              }
        },
              subtitle: 
        {
          text: 'Chart 1',
          style: {
              fontFamily: 'Verdana',
              fontSize: '15px',
              fontWeight: 'bold',
              color: '#CCCCCC'
              }
        },
      
               xAxis: {
              type: 'datetime',
              dateTimeLabelFormats: {
                  minute: '%H:%M'
              }
          },
              yAxis: [{ // first yAxis
                  labels: {
                      format: '{value}',
                      style: {
                          color: '#eeeeee'
                      }
                  },
                  title: {
                      text: 'Realtime',
                      style: {
                          color: '#eeeeee'
                      }
                  }
              }, { // Second yAxis
                  title: {
                      enabled: false,
                      text: 'Graph1',
                      style: {
                          color: '#4572A7'
                      }
                  },
                  labels: {
                      enabled: false,
                      format: '',
                      style: {
                          color: '#4572A7'
                      }
                  },
                  opposite: true
              },{ // Third yAxis
                  title: {
                      enabled: false,
                      text: 'Graph2',
                      style: {
                          color: '#89A54E'
                      }
                  },
                  reversed: true,
                  labels: {
                      enabled: false,
                      format: '',
                      style: {
                          color: '#89A54E'
                      }
                  },
                  opposite: true
              }],
              tooltip: {
              xDateFormat: '%H:%M',
              shared: true,
              backgroundColor: {
                      linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                      stops: [
                      [0, 'rgba(96, 96, 96, .8)'],
                      [1, 'rgba(16, 16, 16, .8)']
                      ]
                  },
                  borderWidth: 1,
                  borderColor: '#666666',
                  crosshairs: true,        
                  useHTML: true,
                  formatter: function() {
                  var s = '<b><span style="font-size: 12px; color: #cccccc">'+ Highcharts.dateFormat('%H:%M', this.x) +' Uhr</span></b>';
                  $.each(this.points, function(i, point) {
                      s += '<br/><span style="font-size: 16px; color: #cccccc">'+ point.series.name +': '+ point.y +'</span>';
                  });
      
                  return s;
              }
          },
      
        legend: 
        {
          enabled: true,
          itemStyle: {
              color: '#eeeeee',
              }
        },
        credits:
        {
          enabled: false
        },
        plotOptions: {
        spline: {
                      lineWidth: 4,
                      states: {
                          hover: {
                              lineWidth: 5
                          }
                      },
                      marker: {
                          enabled: false
                      },
      
                      },
                  area: {
                      fillColor: {
                          linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1},
                          stops: [
                              [0, 'rgb(204, 204, 204)'],
                              [1, 'rgba(204, 204, 204,0)']
                          ]
                      },
                      lineWidth: 1,
                      marker: {
                          enabled: false
                      },
                      shadow: false,
                      states: {
                          hover: {
                              lineWidth: 1
                          }
                      },
                      threshold: null
                  }
              },
              series: [{
             pointStart: Date.UTC(2010, 0, 1, 8),
             pointInterval: 60000,
             name: 'Realtime',
             type: 'area',
             color: '#cccccc',
             data: []
         }, {
             pointStart: Date.UTC(2010, 0, 1, 8),
             pointInterval: 60000,
             name: 'Graph1',
             type: 'spline',
             yAxis: 1,
             color: '#0077cc',
             enableMouseTracking: false,
      
             data: []
          }, {
             pointStart: Date.UTC(2010, 0, 1, 8),
             pointInterval: 60000,
             name: 'Graph2',
             type: 'spline',
             yAxis: 2,
             color: '#89A54E',
             enableMouseTracking: false,
      
             data: []
          }]
          }
          $.getJSON('data.php', function(json) {
      
          val1 = [];
          val2 = [];
          val3 = [];
          $.each(json, function(key,value) {
          val1.push([value[0], value[1]]);
          val2.push([value[0], value[2]]);
          val3.push([value[0], value[3]]);
         });
      
          options.series[0].data = json['data1'];
          options.series[1].data = json['data2'];
          options.series[2].data = json['data3'];
          chart = new Highcharts.Chart(options);
       });
      
      
      });
      
      $(function() {
          $( "#datepicker" ).datepicker({
            beforeShowDay: $.datepicker.noWeekends,
            dateFormat: "yy-mm-dd",
            onSelect: function(dateText, inst) { 
              $.getJSON("data.php?dateParam="+dateText, function(json){
                  val1 = [];
                  val2 = [];
                  val3 = [];
                  $.each(json, function(key,value) {
                  val1.push([value[0], value[1]]);
                  val2.push([value[0], value[2]]);
                  val3.push([value[0], value[3]]);
      
          });
          options.series[0].data = json['data1'];
          options.series[1].data = json['data2'];
          options.series[2].data = json['data3'];
      
          chart = new Highcharts.Chart(options);
              });
            }
          });
      });
      

      【讨论】: