echarts4R图表tooltip异常:Upper bound值固定不更新问题排查
echarts4R 预测区间 tooltip 显示异常问题
我用echarts4R创建了带预测区间的图表,但tooltip显示存在问题:“Upper bound”的数值固定不变,无法随鼠标悬停的位置动态变化。
可复现代码:
dat <- data.frame( time = as.Date(c("2015-09-01","2015-10-01","2015-11-01","2015-12-01","2016-01-01","2016-02-01", "2016-03-01","2016-04-01")), Profit = c(58307.99, 54626.44,58675.40,44361.57,NA,NA,NA,NA), Forecast = c(NA,NA,NA, 44361.57, 36500.09, 30506.53, 35241.72, 31922.28), Lower_CI = c(NA,NA,NA, 22159.93, 22159.93, 16166.36, 20901.56, 17582.11), Upper_CI = c(NA,NA,NA, 50840.26, 50840.26, 44846.69, 49581.89, 46262.44) ) dat |> e_charts(x = time) |> e_line(serie = Profit) |> e_line(serie = Forecast) |> e_band( min = Lower_CI, max = Upper_CI, stack = "confidence-band", name = c("Lower bound", "Upper bound")) |> e_tooltip(formatter = e_tooltip_pointer_formatter("currency")) |> e_legend(show=FALSE) |> e_x_axis(time, axisPointer = list(show = TRUE))
问题现象:
- 鼠标悬停在不同日期时,tooltip中的“Upper bound”始终显示同一个数值,无法对应到当前日期的实际上限值。
问题原因
e_band本质是通过两个堆叠的面积图实现置信区间(Lower bound作为底层面积,Upper bound作为上层堆叠面积),而e_tooltip_pointer_formatter的默认逻辑会错误计算堆叠后的累计值,而非对应x点的原始上限值。- 数据中
Upper_CI的前两个非NA值相同(均为50840.26),进一步放大了这个问题,导致看起来数值完全固定。
解决方法
放弃e_tooltip_pointer_formatter,改用自定义tooltip格式化函数,手动提取每个系列对应x轴位置的原始数值,避免堆叠逻辑干扰。修改后的代码如下:
dat <- data.frame( time = as.Date(c("2015-09-01","2015-10-01","2015-11-01","2015-12-01","2016-01-01","2016-02-01", "2016-03-01","2016-04-01")), Profit = c(58307.99, 54626.44,58675.40,44361.57,NA,NA,NA,NA), Forecast = c(NA,NA,NA, 44361.57, 36500.09, 30506.53, 35241.72, 31922.28), Lower_CI = c(NA,NA,NA, 22159.93, 22159.93, 16166.36, 20901.56, 17582.11), Upper_CI = c(NA,NA,NA, 50840.26, 50840.26, 44846.69, 49581.89, 46262.44) ) dat |> e_charts(x = time) |> e_line(serie = Profit) |> e_line(serie = Forecast) |> e_band( min = Lower_CI, max = Upper_CI, stack = "confidence-band", name = c("Lower bound", "Upper bound")) |> # 自定义tooltip格式化函数 e_tooltip( formatter = htmlwidgets::JS(" function(params) { let result = '<div>' + params[0].axisValue + '</div>'; params.forEach(item => { if (item.value != null) { // 格式化货币格式 let formattedVal = '$' + item.value.toFixed(2).replace(/\\B(?=(\\d{3})+(?!\\d))/g, ','); result += '<div>' + item.seriesName + ': ' + formattedVal + '</div>'; } }); return result; } "), trigger = 'axis' ) |> e_legend(show=FALSE) |> e_x_axis(time, axisPointer = list(show = TRUE))
说明
- 自定义JS格式化函数会遍历每个系列参数,直接调用
item.value获取原始数据值,而非堆叠后的累计值,确保区间值与当前悬停日期正确对应。 - 手动实现了货币格式化逻辑,和原
e_tooltip_pointer_formatter("currency")效果一致。
内容的提问来源于stack exchange,提问作者Dieu94
相关产品推荐
相关产品推荐

