
本文介绍如何在 Kendo ui Line Chart 中实现「仅在鼠标悬停到数据点时显示对应误差线(Error bars),其余时间完全隐藏」的交互效果,通过 seriesOver/seriesLeave 事件结合底层绘图 API 精准控制单个点的误差线渲染。
本文介绍如何在 kendo ui line chart 中实现「仅在鼠标悬停到数据点时显示对应误差线(error bars),其余时间完全隐藏」的交互效果,通过 `seriesover`/`seriesleave` 事件结合底层绘图 api 精准控制单个点的误差线渲染。
在 Kendo UI 的原生配置中,errorBars.visible 是全局开关,无法按数据点粒度动态控制;而 highlight 事件也不支持单独启用误差线高亮。因此,需绕过内置误差线渲染机制,采用手动绘制 + 事件驱动的方式实现精准交互。
核心思路
- 禁用默认误差线:将 seriesDefaults.errorBars.visible 设为 false,避免与自定义绘制冲突;
- 监听悬停事件:利用 seriesOver 捕获鼠标进入数据点(
元素)的时刻; - 坐标转换与绘制:根据当前数据点的 low/high 值,调用 axis.slot(low, high) 获取 Y 轴像素范围,并以点的 X 坐标为中心绘制垂直误差线及两端横杠(end caps);
- 智能清理:使用唯一 opacity 值(如 0.9999998)标记所有自定义误差线元素,便于批量移除;seriesLeave 中设置延时清理,防止快速进出导致视觉残留。
完整实现代码
$("#chart").kendoChart({ // ... 其他配置保持不变 seriesDefaults: { type: "line", errorLowField: "low", errorHighField: "high", errorBars: { visible: false // ✅ 关键:禁用默认误差线 } }, series: [/* 同原示例 */], // ... categoryAxis, valueAxis 等配置 seriesOver: function(e) { // 清除上一次绘制的误差线 clearTimeout(this._errorBarTimeout); $('[opacity="0.9999998"]').remove(); // 仅对 marker 圆点触发(排除线条、标签等) if (e.element && e.element.tagName === "circle") { const chart = e.sender; const yAxis = chart.getAxis("value"); const dataItem = e.dataItem; // 获取误差区间在 Y 轴上的像素位置 const valSlot = yAxis.slot(dataItem.low, dataItem.high); const x = e.element.cx.baseVal.value; // 数据点 X 坐标 const yTop = valSlot.origin.y; const yBottom = yTop + valSlot.size.height; const strokeColor = "#535D5D"; const strokeWidth = 2; const uniqueOpacity = 0.9999998; // 绘制主误差线(垂直线) const mainLine = new kendo.drawing.Path({ stroke: { color: strokeColor, width: strokeWidth } }) .moveTo(x, yTop) .lineTo(x, yBottom) .opacity(uniqueOpacity); // 绘制上端横杠(end cap) const capTop = new kendo.drawing.Path({ stroke: { color: strokeColor, width: strokeWidth } }) .moveTo(x - 4, yTop) .lineTo(x + 4, yTop) .opacity(uniqueOpacity); // 绘制下端横杠(end cap) const capBottom = new kendo.drawing.Path({ stroke: { color: strokeColor, width: strokeWidth } }) .moveTo(x - 4, yBottom) .lineTo(x + 4, yBottom) .opacity(uniqueOpacity); // 渲染到图表画布 chart.surface.draw(mainLine); chart.surface.draw(capTop); chart.surface.draw(capBottom); } }, seriesLeave: function(e) { // 延迟 5 秒清理,避免悬停抖动导致频繁重绘 this._errorBarTimeout = setTimeout(() => { $('[opacity="0.9999998"]').remove(); }, 5000); } });
注意事项与最佳实践
- ✅ 性能考量:seriesOver 频繁触发,应避免在其中执行复杂计算或 dom 查询。本方案直接操作 SVG 元素,轻量高效;
- ✅ 坐标鲁棒性:务必通过 e.element.cx.baseVal.value 获取真实 X 坐标(而非 e.visual.x),因 visual 可能未就绪或受动画影响;
- ✅ 多系列兼容:若图表含多个 series,e.dataItem 自动关联当前悬停系列的数据,无需额外判断;
- ⚠️ 移动端适配:seriesOver 在触摸设备上可能不触发,建议补充 touchstart 或 click 事件作为降级方案;
- ? 样式定制:可自由调整 strokeColor、strokeWidth、横杠长度(±4px)及 opacity 值,实现品牌化视觉。
通过该方案,你将获得完全可控的误差线交互体验——既规避了 Kendo 内置 API 的粒度限制,又保持了专业级图表的响应精度与视觉一致性。