feat: 添加 hexagon的tooltip 以及 panel 初始锁定状态修改

This commit is contained in:
zhangyu
2021-12-29 11:50:24 +08:00
parent 3ca38c116c
commit 48071f0d41
5 changed files with 127 additions and 33 deletions

View File

@@ -494,3 +494,37 @@
transition: none transition: none
} }
} }
.chart-canvas-tooltip{
position: fixed;
min-width: 150px;
max-width: 600px;
display: block;
border-style: solid;
white-space: nowrap;
will-change: transform;
box-shadow: rgba(0,0,0,0.2) 1px 2px 10px;
transition: opacity 0.2s cubic-bezier(0.23, 1, 0.32, 1) 0s, visibility 0.2s cubic-bezier(0.23, 1, 0.32, 1) 0s, transform 0.4s cubic-bezier(0.23, 1, 0.32, 1) 0s;
border-width: 1px;
border-radius: 4px;
font: 14 px/ 21px "Microsoft YaHei";
padding: 10px;
z-index: 99999999;
pointer-events: none;
overflow: hidden;
background-color: #dde4ed !important;
border-color: #fff !important;
color: #666665 !important;
}
.chart-canvas-tooltip-title{
max-width: 500px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: 5px;
font-size: 14px;
}
.chart-canvas-tooltip-content{
font-size: 12px;
display: flex;
justify-content: space-between;
}

View File

@@ -108,6 +108,7 @@ export default {
} }
} }
chartOption.tooltip.formatter = this.formatterFunc chartOption.tooltip.formatter = this.formatterFunc
chartOption.tooltip.position = this.tooltipPosition
/* 使用setTimeout延迟渲染图表避免样式错乱 */ /* 使用setTimeout延迟渲染图表避免样式错乱 */
setTimeout(() => { setTimeout(() => {
const myChart = this.isInit ? echarts.init(document.getElementById(`chart-canvas-${this.chartId}`)) : getChart(this.chartId) const myChart = this.isInit ? echarts.init(document.getElementById(`chart-canvas-${this.chartId}`)) : getChart(this.chartId)

View File

@@ -1,6 +1,15 @@
<template> <template>
<div :ref="`chart-canvas-${chartId}`" style="height: 100%;width: 100%"> <div :ref="`chart-canvas-${chartId}`" style="height: 100%;width: 100%">
<div :id="`chart-canvas-${chartId}`" class="chart__canvas chart-svg"></div> <div :id="`chart-canvas-${chartId}`" class="chart__canvas chart-svg"></div>
<div :class="`chart-canvas-tooltip-${chartId}`" :id="`chart-canvas-tooltip-${chartId}`" class="chart-canvas-tooltip" :style="{left:tooltip.x+'px',top:tooltip.y+'px'}" v-if="tooltip.show">
<div class="chart-canvas-tooltip-title">
{{tooltip.title}}
</div>
<div class="chart-canvas-tooltip-content">
<div>value</div>
<div>{{tooltip.value}}</div>
</div>
</div>
</div> </div>
</template> </template>
@@ -23,31 +32,39 @@ export default {
HexagonData: [], HexagonData: [],
boxWidth: 0, boxWidth: 0,
boxHeight: 0, boxHeight: 0,
boxPadding: 5 boxPadding: 5,
tooltip: {
x: 0,
y: 0,
title: 0,
value: 0,
show: false
},
svgDom: null
} }
}, },
methods: { methods: {
hexbin, hexbin,
initChart () { initChart () {
if (this.timer) { this.clearCache().then(() => {
clearTimeout(this.timer) if (this.timer) {
this.timer = null clearTimeout(this.timer)
} this.timer = null
this.timer = setTimeout(() => { }
this.initHexagonData(this.chartInfo, this.chartData).then(() => { this.timer = setTimeout(() => {
this.getLayout().then(layout => { this.initHexagonData(this.chartInfo, this.chartData).then(() => {
console.log(layout, this.boxWidth, this.boxHeight) this.getLayout().then(layout => {
this.initHexagon(layout) this.initHexagon(layout)
})
}) })
}) }, 200)
}, 200) })
}, },
initHexagonData (chartInfo, originalDatas) { initHexagonData (chartInfo, originalDatas) {
this.HexagonData = [] this.HexagonData = []
this.isInit = false this.isInit = false
return new Promise(resolve => { return new Promise(resolve => {
let colorIndex = 0 let colorIndex = 0
console.log('init', 1)
originalDatas.forEach((originalData, expressionIndex) => { originalDatas.forEach((originalData, expressionIndex) => {
originalData.forEach((data, dataIndex) => { originalData.forEach((data, dataIndex) => {
this.isNoData = false this.isNoData = false
@@ -87,7 +104,6 @@ export default {
}, },
initHexagon (layout) { initHexagon (layout) {
this.isInit = false this.isInit = false
console.log(layout, this.HexagonData)
let rowIndex = 0 let rowIndex = 0
let colIndex = -1 let colIndex = -1
const data = this.HexagonData.map(item => { const data = this.HexagonData.map(item => {
@@ -121,6 +137,7 @@ export default {
} }
}, },
showHexagons (data, hexaRadiu = 60, row, col) { showHexagons (data, hexaRadiu = 60, row, col) {
// 清除资源 释放缓存
// Initial Geometrical Calculations // Initial Geometrical Calculations
const self = this const self = this
const hexaRadius = hexaRadiu const hexaRadius = hexaRadiu
@@ -139,34 +156,63 @@ export default {
.attr('id', 'svgHex' + this.chartId) .attr('id', 'svgHex' + this.chartId)
.attr('width', width) .attr('width', width)
.attr('height', height) .attr('height', height)
.on('mousemove', this.hexagonMove)
this.svgDom = 'svgHex' + this.chartId
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
const point = data[i] const point = data[i]
const col = point.x const col = point.x
const row = point.y const row = point.y
const color = point.mapping ? point.mapping.color.bac : this.colorList[i] const color = point.mapping ? point.mapping.color.bac : this.colorList[i]
console.log(color)
const vals = self.getCenter(hexaRadius, row, col) // Gets the Center coordinates with given row and column const vals = self.getCenter(hexaRadius, row, col) // Gets the Center coordinates with given row and column
const x = vals[0] const x = vals[0]
const y = vals[1] const y = vals[1]
const hexa = self.drawHexagon(svg, hexaRadius, spaceBetweenHexa, x, y, hexbin) // Draws hexagon const g = svg.append('g')
const hexa = self.drawHexagon(g, hexaRadius, spaceBetweenHexa, x, y, hexbin) // Draws hexagon
hexa.attr('fill', color) // Paints hexagon hexa.attr('fill', color) // Paints hexagon
hexa.on('mouseenter', self.hexagonOver.bind(self, hexa)) g.on('mouseenter', self.hexagonOver.bind(self, point))
hexa.on('mouseleave', self.hexagonOut.bind(self, hexa)) g.on('mouseleave', self.hexagonOut.bind(self, point))
self.drawText(svg, vals, point, color, hexaRadius) // 文本 self.drawText(svg, vals, point, color, hexaRadius, g) // 文本
data[i].fcolor = color data[i].fcolor = color
} }
return svg.node() return svg.node()
}, },
hexagonOver (that, e) { // 移入六边形 hexagonOver (that, e) { // 移入六边形
// console.log(that, e) // console.log(that, e)
this.tooltip.title = that.alias
this.tooltip.value = that.showValue
this.tooltip.show = true
this.setPosition(e)
}, },
hexagonMove (that, e) { // 六边形内移动 hexagonMove (e) { // 六边形内移动
// console.log(that, e) // console.log(e)
// this.$emit('assetMove',e) if (this.tooltip.show) {
this.setPosition(e)
}
}, },
hexagonOut (that) { hexagonOut (that) {
this.tooltip.show = false
},
setPosition (e) {
const windowWidth = window.innerWidth// 窗口宽度
const windowHeight = window.innerHeight// 窗口高度
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
if (box) {
const boxWidth = box.offsetWidth
const boxHeight = box.offsetHeight
if (e.pageX < (windowWidth / 2)) { // 说明鼠标在左边放不下提示框
this.tooltip.x = e.pageX + 15
} else {
this.tooltip.x = e.pageX - boxWidth - 15
}
if (e.pageY + 50 + boxHeight < windowHeight) { // 说明鼠标上面放不下提示框
this.tooltip.y = e.pageY + 15
} else {
this.tooltip.y = e.pageY - boxHeight - 10
}
} else {
this.tooltip.y = e.pageY + 15
this.tooltip.x = e.pageX + 15
}
}, },
formatStr (d) { formatStr (d) {
const self = this const self = this
@@ -182,7 +228,7 @@ export default {
.attr('transform', 'translate(' + x + ',' + y + ')') .attr('transform', 'translate(' + x + ',' + y + ')')
return hexagon return hexagon
}, },
drawText (svg, vals, point, color, hexbinRadius) { drawText (svg, vals, point, color, hexbinRadius, group) {
let str = '' let str = ''
let valueStr = '' let valueStr = ''
const self = this const self = this
@@ -202,12 +248,12 @@ export default {
str += '' str += ''
} }
if (str && valueStr) { if (str && valueStr) {
const fObj = svg.append('foreignObject') const fObj = group.append('foreignObject')
.attr('width', hexWidth || 60) .attr('width', hexWidth || 60)
.attr('height', 20) .attr('height', 24)
fObj fObj
.attr('x', vals[0] - hexWidth / 2) .attr('x', vals[0] - hexWidth / 2)
.attr('y', vals[1] - 16) .attr('y', vals[1] - 24)
// .text(str) // .text(str)
.attr('text-anchor', 'middle') .attr('text-anchor', 'middle')
.attr('alignment-baseline', 'central') .attr('alignment-baseline', 'central')
@@ -216,7 +262,7 @@ export default {
const scrollDiv = fObj.append('xhtml:div') const scrollDiv = fObj.append('xhtml:div')
scrollDiv scrollDiv
.html(`<div style="color:${textColor};width:${hexWidth}px;overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 16px;box-sizing: border-box;padding: 0 10px;text-align: center">${str}</div>`) .html(`<div style="color:${textColor};width:${hexWidth}px;overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 16px;box-sizing: border-box;padding: 0 10px;text-align: center">${str}</div>`)
svg.append('text') group.append('text')
.attr('x', vals[0]) .attr('x', vals[0])
.attr('y', vals[1] + 16) .attr('y', vals[1] + 16)
.text(valueStr) .text(valueStr)
@@ -227,9 +273,9 @@ export default {
return return
} }
if (str) { if (str) {
const fObj = svg.append('foreignObject') const fObj = group.append('foreignObject')
.attr('width', hexWidth || 60) .attr('width', hexWidth || 60)
.attr('height', 20) .attr('height', 24)
fObj fObj
.attr('x', vals[0] - hexWidth / 2) .attr('x', vals[0] - hexWidth / 2)
.attr('y', vals[1] - 10) .attr('y', vals[1] - 10)
@@ -244,7 +290,7 @@ export default {
return return
} }
if (valueStr) { if (valueStr) {
svg.append('text') group.append('text')
.attr('x', vals[0]) .attr('x', vals[0])
.attr('y', vals[1]) .attr('y', vals[1])
.text(valueStr) .text(valueStr)
@@ -315,6 +361,15 @@ export default {
} }
resolve({ col, row, radius: radius - 2 }) resolve({ col, row, radius: radius - 2 })
}) })
},
clearCache () {
return new Promise(resolve => {
// if (this.svgDom) {
// const dom = document.getElementById(this.svgDom)
// dom.off('mousemove', this.hexagonMove)
// }
resolve()
})
} }
}, },
created () { created () {
@@ -327,6 +382,9 @@ export default {
this.isStack = this.chartInfo.param.stack this.isStack = this.chartInfo.param.stack
} catch (e) {} } catch (e) {}
this.chartInfo.loaded && this.initChart(this.chartOption) this.chartInfo.loaded && this.initChart(this.chartOption)
},
beforeDestroy () {
this.clearCache()
} }
} }
</script> </script>

View File

@@ -85,6 +85,7 @@ export default {
} }
// chartOption.series.label.formatter = this.pieFormatterLabel // chartOption.series.label.formatter = this.pieFormatterLabel
chartOption.tooltip.formatter = this.formatterFunc chartOption.tooltip.formatter = this.formatterFunc
chartOption.tooltip.position = this.tooltipPosition
/* 使用setTimeout延迟渲染图表避免样式错乱 */ /* 使用setTimeout延迟渲染图表避免样式错乱 */
setTimeout(() => { setTimeout(() => {
const myChart = this.isInit ? echarts.init(document.getElementById(`chart-canvas-${this.chartId}`)) : getChart(this.chartId) const myChart = this.isInit ? echarts.init(document.getElementById(`chart-canvas-${this.chartId}`)) : getChart(this.chartId)

View File

@@ -170,7 +170,7 @@ export default {
panelTabLoading: false, panelTabLoading: false,
overScroll10: false, overScroll10: false,
isLoading: true, isLoading: true,
panelLock: false, panelLock: true,
showTopBtn: false, // top按钮 showTopBtn: false, // top按钮
visible: false, visible: false,
chartListLoading: true, chartListLoading: true,