如何解决从CSV加载数据的Highcharts折线图注释时区匹配问题?
我的目标是从数据库获取图表数据与注释数据。CSV图表数据如下:
Timestamp,Flow,Temperature 2024-05-08 1:00:00,10,20 2024-05-08 2:00:00,12,15 2024-05-08 2:30:00,,16 2024-05-08 3:00:00,9,18 2024-05-08 4:00:00,7,19
我用下方的Highcharts示例可正确从CSV文件拉取并加载数据,图表显示符合预期,x轴为datetime类型,能正确展示数据点时间。但添加注释时发现,图表x轴使用的是CSV解析生成的GMT格式Unix时间戳,而本地创建对应时间的JavaScript Date对象并调用.getTime()得到的是本地时区的时间戳。例如,图表中"2024-05-08 2:00:00"数据点的x轴值为"1715133600000",但本地生成的对应时间戳为"1715153400000",二者相差5小时,导致无法用本地时间戳添加注释。
请问Highcharts是否有设置可让x轴使用本地时间而非GMT时间?或有什么解决办法?
代码示例:
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Highcharts Example</title> <script src="js/jquery-1.11.3.js"></script> <script src="js/highcharts11.js"></script> <script src="js/data11.js"></script> <script src="js/exporting11.js"></script> <script src="js/accessibility11.js"></script> <script src="js/annotations11.js"></script> <script src="js/export-data11.js"></script> </head> <body> <div id="container" style="height: 400px; min-width: 380px"></div> <script type="text/javascript"> $(function () { $.ajaxSetup({ cache: false }); }); //Build the chart var thisChart = Highcharts.chart('container', { chart: { type: 'line' }, title: { text: 'Live Data (CSV)' }, subtitle: { text: 'Data input from a remote CSV file' }, xAxis: { type: 'datetime', title: { text: 'x axis title'} }, plotOptions: { series: { connectNulls: true , point: { events: { click: function () { alert("this.series.name = " + this.series.name + "\nthis.x = " + this.x + "\nthis.y = " + this.y); } //click } //events } //point }// series }, data: { csvURL: 'http://localhost/tundra/zdata.csv', enablePolling: false } //data }); //thisChart // Try to add an annotation at 2:00:00 //var date = new Date("2024-05-08 2:00:00 "); var date = new Date("2024-05-07 21:00:00 "); alert(date.getTime()); //1715151600000 var a2 = { labels: [{ point: { //x: 1715133600000, // this works but it is GMT time x: date.getTime(), //1715151600000 --> GMT minus 5 hours y: 15, yAxis: 0, xAxis:0 }, text: 'basic annotation' }], labelOptions: { borderRadius: 5, backgroundColor: 'rgba(252, 255, 197, 0.7)', borderWidth: 1, borderColor: '#AAA' }, } thisChart.addAnnotation(a2); //alert('done'); </script> </body> </html>
方法一:配置Highcharts使用本地时区解析CSV数据
在data配置项中添加dateFormat和useUTC: false,强制Highcharts用本地时区解析时间字符串:
data: { csvURL: 'http://localhost/tundra/zdata.csv', enablePolling: false, dateFormat: '%Y-%m-%d %H:%M:%S', useUTC: false }
这样CSV中的时间会被解析为本地时区的时间戳,和你用new Date()生成的时间戳一致,直接用date.getTime()就能匹配到对应的图表点。
方法二:转换本地时间戳为GMT时间戳(不修改图表配置)
如果不想改动图表的时区配置,可以手动把本地时间转换为GMT对应的时间戳。通过创建Date对象后,计算时区偏移量来调整:
var localDate = new Date("2024-05-08 2:00:00"); // 计算本地时区与GMT的偏移分钟数,转换为毫秒 var offsetMs = localDate.getTimezoneOffset() * 60 * 1000; // 本地时间戳减去偏移量得到GMT时间戳 var gmtTimestamp = localDate.getTime() - offsetMs;
然后把gmtTimestamp赋值给注释的x属性即可。
方法三:直接使用日期字符串设置注释(推荐)
Highcharts的注释支持直接传入日期字符串,不需要手动转换时间戳,只要确保格式和CSV中的一致:
var a2 = { labels: [{ point: { x: "2024-05-08 2:00:00", y: 15, yAxis: 0, xAxis: 0 }, text: 'basic annotation' }], // 其他配置... }
这种方式不需要关心时区问题,Highcharts会自动用和解析CSV时相同的规则处理这个日期字符串。
内容的提问来源于stack exchange,提问作者ZordL

