需求:解决节点数据较小时,桑基图文字重叠问题。
由于echarts的dataZoom工具仅适用于直角坐标系,考虑通过改变画布大小与位置实现
效果:
1.缩放
this.chartBox:画布外层容器,box:画布DOM,chartData:桑基图数据,nodeGap:桑基图节点间距,画布放大不会扩大间距,只能手动调整。当鼠标在容器内部操作滚轮时进行画布缩放操作
//鼠标滚轮事件
window.onmousewheel = (event) => {
//容器位置,{ x, y } 为鼠标位置,{ top, bottom, left, right }容器边界位置
let { x, y } = event, { top, bottom, left, right } = this.chartBox.getClientRects()[0]
//画布DOM
let box = document.getElementsByClassName("box")[0]
if (x > left && x < right && y > top && y < bottom) { //判断鼠标滚动事件是否在容器内
if (event.deltaY < 0) {//小于0,向上滚动
box.style.height = box.clientHeight + 20 + 'px'//画布高度+20
charData.series[0].nodeGap += 2 //桑基图节点间距+2,默认为8
} else {
box.style.height = box.clientHeight - 20 + 'px'
charData.series[0].nodeGap = charData.series[0].nodeGap < 10 ? 8 : charData.series[0].nodeGap - 2
}
//画布高度小于容器高度后,节点间距不再缩小
if (box.style.height.split("px")[0] - this.chartBox.style.maxHeight.split("px")[0] <= 0) {
charData.series[0].nodeGap = 8
}
chart.setOption(charData)
chart.resize()
}
}
2.拖动
通过 dragging 判断鼠标移动时是否按下
let dragging = false
let position = null
box.addEventListener('mousedown', function (e) {
dragging = true
position = [e.clientX, e.clientY]
})
document.addEventListener('mousemove', function (e) {
if (dragging === false) return
const x = e.clientX
const y = e.clientY
const deltaX = x - position[0]
const deltaY = y - position[1]
const left = parseInt(box.style.left || 0)
const top = parseInt(box.style.top || 0)
box.style.left = left + deltaX + 'px'
box.style.top = top + deltaY + 'px'
position = [x, y]
})
document.addEventListener('mouseup', function (e) {
dragging = false
})
flex布局下,防止外层容器被撑开,DOM加载完成后为外层容器定高
mounted() {
this.chartBox = document.getElementsByClassName("chartBox")[0]
this.chartBox.style.maxHeight = this.chartBox.clientHeight + 'px'
}
移除滚轮事件,防止控制台报错
destroyed() {
window.onmousewheel = null
},
css 外层容器溢出隐藏
.chartBox {
overflow: hidden;
}