Plotly.kt Kotlin/JS应用中监听hover事件实现自定义悬浮内容
在Kotlin/JS中用Plotly.kt监听Hover事件实现自定义悬浮内容
1. 禁用默认悬浮提示
先通过hoverinfo = "none"关闭默认提示,Plotly.kt中的实现示例:
val trace = Scatter { x = listOf(1, 2, 3) y = listOf(4, 5, 6) hoverinfo = "none" // 禁用默认悬浮提示 }
2. 监听Plotly Hover事件
Plotly.js原生支持hover事件,在Kotlin/JS中可以通过两种方式监听:
方式一:使用Plotly.kt封装的事件API
创建图表实例后,直接调用on方法绑定hover事件:
val plotDiv = document.getElementById("plot") as HTMLElement val plot = Plotly.newPlot(plotDiv, listOf(trace), Layout()) plot.on("hover") { event -> val points = event.points as Array<dynamic> if (points.isNotEmpty()) { val targetPoint = points[0] // 根据数据点信息加载自定义内容 renderCustomTooltip(targetPoint) } }
方式二:直接绑定DOM事件(备用)
如果Plotly.kt的封装不够灵活,可直接给图表DOM元素绑定plotly_hover事件:
plotDiv.addEventListener("plotly_hover", { event -> val eventDetail = (event as dynamic).detail val points = eventDetail.points if (points.isNotEmpty()) { renderCustomTooltip(points[0]) } })
3. 实现自定义悬浮内容
编写renderCustomTooltip函数,生成包含图片、视频、子图表的自定义提示框,并定位到对应位置:
fun renderCustomTooltip(point: dynamic) { // 移除已存在的提示框 document.getElementById("custom-tooltip")?.remove() // 创建提示容器 val tooltip = document.createElement("div").apply { id = "custom-tooltip" style.position = "absolute" style.backgroundColor = "#fff" style.border = "1px solid #ddd" style.padding = "10px" style.borderRadius = "4px" style.boxShadow = "0 2px 6px rgba(0,0,0,0.15)" style.zIndex = "9999" } // 添加图片(根据数据点动态设置路径) val img = document.createElement("img").apply { src = point.customdata?.imgPath ?: "default-img.jpg" style.width = "120px" style.marginBottom = "8px" } tooltip.appendChild(img) // 添加视频 val video = document.createElement("video").apply { src = point.customdata?.videoPath ?: "default-video.mp4" controls = true style.width = "200px" style.marginBottom = "8px" } tooltip.appendChild(video) // 添加子图表 val subPlotDiv = document.createElement("div").apply { style.width = "200px" style.height = "160px" } tooltip.appendChild(subPlotDiv) val subTrace = Bar { x = listOf("指标1", "指标2") y = listOf(point.y * 0.5, point.y * 0.8) } Plotly.newPlot(subPlotDiv, listOf(subTrace), Layout(title = "关联指标")) // 定位提示框到数据点附近 val plotRect = (document.getElementById("plot") as HTMLElement).getBoundingClientRect() tooltip.style.left = "${plotRect.left + point.xPixel + 15}px" tooltip.style.top = "${plotRect.top + point.yPixel - 20}px" document.body.appendChild(tooltip) } // 监听mouseleave事件移除提示框 plot.on("mouseleave") { document.getElementById("custom-tooltip")?.remove() }
4. 关联数据点与自定义资源
可以在trace的customdata字段中存储每个数据点对应的资源路径,方便hover时调用:
val trace = Scatter { x = listOf(1, 2, 3) y = listOf(4, 5, 6) hoverinfo = "none" // 存储每个点的自定义资源信息 customdata = arrayOf( js("{imgPath: 'data-point-1.jpg', videoPath: 'point-1.mp4'}"), js("{imgPath: 'data-point-2.jpg', videoPath: 'point-2.mp4'}"), js("{imgPath: 'data-point-3.jpg', videoPath: 'point-3.mp4'}") ) }
内容的提问来源于stack exchange,提问作者Joseph Hui
相关产品推荐
相关产品推荐

