
本文详解如何将 Highcharts 普通图表升级为 Highcharts Stock 图表,重点解决日期轴(xAxis)不支持 categories、需改用时间戳格式、以及自动同步显示当前日期的问题。
本文详解如何将 highcharts 普通图表升级为 highcharts stock 图表,重点解决日期轴(xaxis)不支持 `categories`、需改用时间戳格式、以及自动同步显示当前日期的问题。
Highcharts Stock 与基础 Highcharts 在数据结构和坐标轴处理上有本质区别:Stock 图表专为时间序列设计,其 xAxis 默认启用时间轴(datetime type),不接受 categories 数组,而要求数据点必须为 [timestamp, value] 格式的时间戳数组。若沿用原 Highcharts 的字符串日期分类(如 ["2024-06-01", "2024-06-02"]),会导致 xAxis 渲染异常、日期错位、甚至无法显示当前日期标签。
✅ 正确做法:统一使用毫秒级时间戳
首先,在后端返回数据时,需将 fecha_actualizacion 字段转换为 JavaScript 可识别的毫秒时间戳(UTC 时间)。推荐在 PHP 模型中进行标准化处理:
// 在 model_venta->montos() 方法中调整:
public function montos(){
$this->db->select("DATE(fecha_actualizacion) as fecha, SUM(total) as monto");
$this->db->from("venta");
$this->db->where("pago_id", "2");
$this->db->where("estado", "1");
$this->db->group_by('DATE(fecha_actualizacion)');
$this->db->order_by('fecha_actualizacion');
$resultados = $this->db->get()->result();
// 转换为 UTC 时间戳(毫秒),确保时区一致性
foreach ($resultados as &$row) {
$date = new DateTime($row->fecha, new DateTimeZone('America/Bogota'));
$date->setTimezone(new DateTimeZone('UTC'));
$row->timestamp = $date->getTimestamp() * 1000; // 转为毫秒
}
return $resultados;
}
前端 AJAX 成功回调中,构造符合 Stock 要求的二维数组:
function datagrafico(base_url){
$.ajax({
url: base_url + "index.php/Admin/getDataDias",
type: "POST",
dataType: "json",
success: function(data){
const seriesData = data.map(item => [
item.timestamp, // x: 毫秒时间戳(必需)
Number(item.monto) // y: 数值
]);
graficar(seriesData);
}
});
}
function graficar(seriesData){
Highcharts.stockChart('grafico', {
chart: {
type: 'column',
height: 400
},
title: {
text: 'Monto acumulado por ventas diarias'
},
xAxis: {
type: 'datetime',
labels: {
formatter: function () {
return Highcharts.dateFormat('%Y-%m-%d', this.value);
}
},
// 自动包含最新日期(即“当前日期”)——无需手动添加,Stock 会根据数据范围智能渲染
},
yAxis: {
min: 0,
title: {
text: 'Monto Acumulado (Colombiano)'
}
},
tooltip: {
pointFormat: '<b>{point.y:,.0f} Colombiano</b><br>Fecha: {point.x:%Y-%m-%d}',
dateTimeLabelFormats: {
day: '%Y-%m-%d'
}
},
plotOptions: {
column: {
pointPadding: 0,
borderWidth: 0,
dataLabels: {
enabled: true,
format: '{y:,.0f}'
}
}
},
rangeSelector: {
buttons: [{
type: 'day',
count: 7,
text: '7d'
}, {
type: 'month',
count: 1,
text: '1m'
}, {
type: 'all',
text: 'Todo'
}],
selected: 2 // 默认显示全部范围
},
series: [{
name: 'Ventas diarias',
data: seriesData,
color: '#4a75c2'
}]
});
}
⚠️ 关键注意事项
- 禁止使用 xAxis.categories:Highcharts Stock 的 xAxis 不识别该配置,强行设置将导致图表空白或报错;
- 时间戳必须为毫秒(非秒):JavaScript Date.getTime() 返回的是毫秒,务必乘以 1000;
- 时区一致性至关重要:数据库中 fecha_actualizacion 若为本地时间(如 Colombia),需显式转换为 UTC 时间戳,避免因浏览器时区差异导致日期偏移;
- 当前日期自动呈现:只要数据中包含最新日期对应的时间戳,Stock 图表会自动将其纳入 xAxis 范围并正确标注——无需额外逻辑“插入今日”;
- 建议启用 rangeSelector:便于用户快速切换时间范围,提升交互体验。
通过以上改造,图表不仅能正确渲染每日销售数据,还能精准对齐真实日期轴、响应式缩放,并天然支持“今日”作为最右端索引——真正实现动态、可靠、专业的时间序列可视化。











