本文详解如何将 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' }] });}
通过以上改造,图表不仅能正确渲染每日销售数据,还能精准对齐真实日期轴、响应式缩放,并天然支持“今日”作为最右端索引——真正实现动态、可靠、专业的时间序列可视化。