Highcharts日期时间数据折线图正常,堆叠柱状图异常求助
解决Highcharts堆叠柱状图(datetime数据)显示异常的问题
嘿,我仔细看了你的配置和数据,一下子就发现问题出在哪了!你的堆叠柱状图之所以显示成100%平铺的异常状态,核心原因是y轴类型的选择错误,再加上数据含义的误解,咱们一步步来解决:
问题根源分析
- y轴类型不匹配:你把y轴设置成了
type: 'datetime',但datetime轴是用来展示时间点的,而堆叠柱状图需要的是可累加的数值型数据(比如时长、数量)。你传入的柱状图数据是大时间戳(比如1517018400000),这些是绝对时间点,堆叠起来会把超大的数值相加,导致图表轴范围被撑爆,柱子高度超出可视范围,看起来就像“平铺”了。 - 数据含义混淆:你的折线图
Checker数据是小数值(86、87等),看起来像是某种短时长或指标,但柱状图的Estimate和Process却是绝对时间戳,这两种数据的维度完全不匹配,根本没法在同一个datetime轴上合理堆叠。
具体解决方案
1. 调整数据:将绝对时间戳转为时长
首先要把柱状图的绝对时间戳转换成相对时长(毫秒数)。比如,如果这些时间戳是任务的结束时间,你需要计算它与起始时间的差值,得到实际耗时:
// 假设你的起始时间是某个固定值,替换成你的实际起始时间 const startTime = 1517000000000; // 处理Estimate数据,转成时长(毫秒) const estimateData = [1517018400000,1517014800000,...].map(timestamp => timestamp - startTime); // 处理Process数据同理 const processData = [1517018400000,1517013666000,...].map(timestamp => timestamp - startTime);
如果Checker的数据是秒数,记得也要转换成毫秒数(乘以1000),让它和柱状图数据的量级一致,不然折线会几乎看不到。
2. 修改y轴配置:改用数值轴(linear)
把y轴从datetime类型改成linear,然后通过labels.formatter把毫秒数格式化成时分秒:
yAxis: { title: { text: '处理时长' }, type: 'linear', // 关键:换成数值轴 labels: { formatter: function() { // 将毫秒数转成 HH:MM:SS 格式 const totalSeconds = Math.floor(this.value / 1000); const hours = Math.floor(totalSeconds / 3600); const minutes = Math.floor((totalSeconds % 3600) / 60); const seconds = totalSeconds % 60; return `${hours}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; } }, gridLineWidth: 0 }
3. 确保堆叠配置生效
虽然你已经设置了stacking: 'normal',可以再给柱状图系列明确指定stack属性,确保它们归到同一个堆叠组(避免潜在的分组问题):
plotOptions: { series: { pointPadding: 0.05, groupPadding: 0 }, column: { stacking: 'normal', stack: 'process-duration' // 明确指定堆叠组名称 }, line: { marker: { radius: 2, fillColor: '#ad050b' }, dashStyle: 'ShortDash', lineWidth: 1, } }
或者直接在每个柱状图系列里添加stack: 'process-duration'属性,效果是一样的。
修改后的核心配置示例
把上面的调整整合后,你的核心配置会变成这样:
var optionsProcessTime = { global: { useUTC: false }, title: { text: '', x: -20 }, subtitle: { text: '', x: -20 }, xAxis: { categories: [], labels:{ formatter: function(){ return '#'+this.value; } } }, yAxis: { title: { text: '处理时长' }, type: 'linear', labels: { formatter: function() { const totalSeconds = Math.floor(this.value / 1000); const hours = Math.floor(totalSeconds / 3600); const minutes = Math.floor((totalSeconds % 3600) / 60); const seconds = totalSeconds % 60; return `${hours}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; } }, gridLineWidth: 0 }, tooltip: { enabled: true, formatter: function(){ // 格式化tooltip里的时长 const totalSeconds = Math.floor(this.y / 1000); const hours = Math.floor(totalSeconds / 3600); const minutes = Math.floor((totalSeconds % 3600) / 60); const seconds = totalSeconds % 60; return `${this.series.name}: ${hours}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; } }, legend: { enabled : false }, plotOptions: { series: { pointPadding: 0.05, groupPadding: 0 }, column: { stacking: 'normal', stack: 'process-duration' }, line: { marker: { radius: 2, fillColor: '#ad050b' }, dashStyle: 'ShortDash', lineWidth: 1 } }, series: [ { "name":"Checker", "data":[86000,87000,91000,92000,93000,94000,99000,100000,101000]}, // 转成毫秒 { "name":"Estimate", "type":"column", "stack": "process-duration", "data":[18400000,14800000,...]}, // 已转成时长 { "name":"Process", "type":"column", "stack": "process-duration", "data":[18400000,13666000,...]} // 已转成时长 ] }
这样调整后,你的堆叠柱状图就能正常显示了,柱子会按时长累加,y轴也能正确展示时分秒格式的时长~
内容的提问来源于stack exchange,提问作者vincmeister
相关产品推荐
相关产品推荐

