Flot 0.8.3时间序列图高亮环与数据点偏移问题求助
解决Flot 0.8.3时间序列折线图高亮环偏移问题
我之前也碰到过Flot旧版本时间轴图表的高亮偏移问题,大概率是时间轴的坐标映射逻辑和鼠标检测范围不匹配导致的,咱们一步步来解决:
核心原因分析
Flot处理mode: "time"类型的x轴时,会把时间戳转换成画布像素坐标,但timezone: "browser"的设置可能会让本地时区偏移干扰坐标计算,再加上默认的数据点检测范围太小,就出现了鼠标得移到点左侧才能触发高亮的情况。
具体解决方案
方案1:扩大数据点的检测范围(最快捷)
给series的points配置添加hitDetectionRadius参数,让鼠标在更大范围内都能触发高亮,同时能修正偏移带来的触发困难:
var options = { // ... 保留你原有其他配置 series: { points: { show: true, hitDetectionRadius: 5 // 默认是2,增大检测半径 } }, // ... 保留你原有其他配置 };
这个方法不需要改动核心逻辑,大部分场景下能直接解决问题。
方案2:校准时间轴时区设置
如果你的数据是UTC标准时间,把xaxis.timezone改成"utc",避免本地时区偏移影响坐标计算:
xaxis: { // ... 保留你原有其他配置 timezone: "utc" }
如果数据本身就是本地时间,可保留"browser",但结合方案1的检测半径调整,效果会更稳定。
方案3:自定义hover事件修正定位(进阶)
如果前两个方案还没解决问题,可以手动监听hover事件,自己计算正确的点位置来触发高亮:
// 先把autoHighlight设为false,关闭默认高亮逻辑 var options = { // ... 其他配置 grid: { hoverable: true, autoHighlight: false, borderWidth: 0 } }; // 绑定自定义hover事件 $("#lateness-intervals").bind("plothover", function (event, pos, item) { var plot = $.plot("#lateness-intervals")[0]; // 先清除之前的高亮 plot.unhighlight(); if (item) { // 可以根据实际偏移情况微调x坐标,比如+2修正偏移 var adjustedX = pos.x + 2; // 重新计算匹配的数据点 var nearestPoint = plot.findNearbyItem({x: adjustedX, y: pos.y}); if (nearestPoint) { plot.highlight(nearestPoint.series, nearestPoint.datapoint); // 这里可以添加自定义tooltip逻辑 } } });
修改后的完整配置示例
把方案1整合到你的代码里,最终代码如下:
function gd(year, month, day) { return new Date(year, month - 1, day).getTime(); } var hours_contractual = [ [gd(2017, 1, 1), 7], [gd(2017, 1, 2), 6], [gd(2017, 1, 3), 4], [gd(2017, 1, 4), 8], [gd(2017, 1, 5), 9], [gd(2017, 1, 6), 7], [gd(2017, 1, 7), 5], [gd(2017, 1, 8), 4], [gd(2017, 1, 9), 7], [gd(2017, 1, 10), 8], [gd(2017, 1, 11), 9], [gd(2017, 1, 12), 6], [gd(2017, 1, 13), 4], [gd(2017, 1, 14), 5], [gd(2017, 1, 15), 11], [gd(2017, 1, 16), 8], [gd(2017, 1, 17), 8], [gd(2017, 1, 18), 11], [gd(2017, 1, 19), 11], [gd(2017, 1, 20), 6], [gd(2017, 1, 21), 6], [gd(2017, 1, 22), 8], [gd(2017, 1, 23), 11], [gd(2017, 1, 24), 13], [gd(2017, 1, 25), 7], [gd(2017, 1, 26), 9], [gd(2017, 1, 27), 9], [gd(2017, 1, 28), 8], [gd(2017, 1, 29), 5], [gd(2017, 1, 30), 8], [gd(2017, 1, 31), 15] ]; var hours_worked = [ [gd(2017, 1, 1), 8], [gd(2017, 1, 2), 5], [gd(2017, 1, 3), 6], [gd(2017, 1, 4), 7], [gd(2017, 1, 5), 5], [gd(2017, 1, 6), 4], [gd(2017, 1, 7), 8], [gd(2017, 1, 8), 5], [gd(2017, 1, 9), 4], [gd(2017, 1, 10), 8], [gd(2017, 1, 11), 6], [gd(2017, 1, 12), 7], [gd(2017, 1, 13), 5], [gd(2017, 1, 14), 6], [gd(2017, 1, 15), 7], [gd(2017, 1, 16), 7], [gd(2017, 1, 17), 3], [gd(2017, 1, 18), 8], [gd(2017, 1, 19), 8], [gd(2017, 1, 20), 8], [gd(2017, 1, 21), 9], [gd(2017, 1, 22), 4], [gd(2017, 1, 23), 9], [gd(2017, 1, 24), 5], [gd(2017, 1, 25), 7], [gd(2017, 1, 26), 6], [gd(2017, 1, 27), 8], [gd(2017, 1, 28), 9], [gd(2017, 1, 29), 1], [gd(2017, 1, 30), 5], [gd(2017, 1, 31), 9] ]; var dataset = [ { label: "Contractual", data: hours_contractual, color: "#A00", lines: { lineWidth: 1, show: true, fill: false, fillColor: { colors: [{ opacity: 0.2 }, { opacity: 0.4 }] } }, splines: { show: false, tension: 0.6, lineWidth: 1, fill: 0.1 }, }, { label: "Total Hours", data: hours_worked, yaxis: 2, color: "blue", lines: { lineWidth: 1, show: true, fill: false, }, splines: { show: false, tension: 0.6, lineWidth: 1, fill: 0.1 }, } ]; var options = { xaxis: { mode: "time", tickSize: [7, "day"], tickLength: 6, axisLabel: "Date", axisLabelUseCanvas: true, axisLabelFontSizePixels: 12, axisLabelFontFamily: "Arial", axisLabelPadding: 10, color: "#d5d5d5", timeformat: "%e %b", timezone: "browser" }, yaxes: [{ position: "left", max: 50, color: "#d5d5d5", axisLabelUseCanvas: true, axisLabelFontSizePixels: 12, axisLabelFontFamily: "Arial", axisLabelPadding: 4 }, { position: "right", max: 50, color: "#d5d5d5", axisLabelUseCanvas: true, axisLabelFontSizePixels: 12, axisLabelFontFamily: "Arial", axisLabelPadding: 80 } ], legend: { noColumns: 1, labelBoxBorderColor: "#000000", container: "#lateness-intervals-legend", position: "nw" }, series: {points: {show: true, hitDetectionRadius:5}}, grid: { hoverable: true, autoHighlight: true, borderWidth: 0 } }; $.plot("#lateness-intervals", dataset, options);
先试试方案1,应该能快速解决你的问题,如果还有偏移再尝试方案2或3。
内容的提问来源于stack exchange,提问作者SteB
相关产品推荐
相关产品推荐

