NEZ-2835 feat:Data link页面开发
This commit is contained in:
@@ -704,7 +704,7 @@ textarea {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.message-zindex{
|
.message-zindex{
|
||||||
z-index: 5000 !important;
|
z-index: 9999999999 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-ellipsis{
|
.text-ellipsis{
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 0;
|
// z-index: 0;
|
||||||
}
|
}
|
||||||
.main-container {
|
.main-container {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
|
|||||||
@@ -221,6 +221,7 @@
|
|||||||
.panel-chart.panel-chart--fullscreen {
|
.panel-chart.panel-chart--fullscreen {
|
||||||
border: none;
|
border: none;
|
||||||
.nz-chart__component {
|
.nz-chart__component {
|
||||||
|
position: relative;
|
||||||
&.nz-chart__component--bottom {
|
&.nz-chart__component--bottom {
|
||||||
.legend-container {
|
.legend-container {
|
||||||
max-height: 135px;
|
max-height: 135px;
|
||||||
@@ -462,12 +463,11 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-width: 150px;
|
min-width: 150px;
|
||||||
max-width: 600px;
|
max-width: 500px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|
||||||
.row__label {
|
.row__label {
|
||||||
max-width: 500px;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
@@ -623,8 +623,6 @@
|
|||||||
}
|
}
|
||||||
.chart-canvas-tooltip{
|
.chart-canvas-tooltip{
|
||||||
position: fixed;
|
position: fixed;
|
||||||
min-width: 150px;
|
|
||||||
max-width: 600px;
|
|
||||||
display: block;
|
display: block;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -633,13 +631,14 @@
|
|||||||
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;
|
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-width: 1px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font: 14 px/ 21px "Microsoft YaHei";
|
font: 14px / 21px "Microsoft YaHei";
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
z-index: 99999999;
|
z-index: 99999999;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.chart-canvas-tooltip-title{
|
.chart-canvas-tooltip-title{
|
||||||
|
min-width: 150px;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -648,65 +647,40 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
.chart-canvas-tooltip-content{
|
.chart-canvas-tooltip-content{
|
||||||
font-size: 12px;
|
max-width: 500px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
font-size: 12px;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart-dataLink-tooltip{
|
.chart-dataLink-tooltip{
|
||||||
position: fixed;
|
padding-bottom: 2px;
|
||||||
min-width: 150px;
|
z-index: 999999999;
|
||||||
max-width: 600px;
|
pointer-events: auto;
|
||||||
display: block;
|
|
||||||
white-space: nowrap;
|
|
||||||
will-change: transform;
|
|
||||||
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-radius: 4px;
|
|
||||||
font: 14 px/ 21px "Microsoft YaHei";
|
|
||||||
padding-top: 10px;
|
|
||||||
z-index: 9999999999;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: $--tooltip-background-color !important;
|
|
||||||
border: 2px solid $--tooltip-border-color !important;
|
|
||||||
border-color: $--tooltip-border-color !important;
|
|
||||||
color: $--color-text-regular !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
.chart-dataLink-title{
|
|
||||||
margin-bottom: 5px;
|
|
||||||
padding: 0 10px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
max-width: 500px;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
font-size: 14px;
|
|
||||||
color: $--color-text-primary !important;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
.chart-dataLink-content{
|
|
||||||
padding: 0 10px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: 12px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.chart-dataLink-list{
|
.chart-dataLink-list{
|
||||||
|
width: calc(100% + 20px);
|
||||||
|
margin-left: -10px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
border-top: 1px solid $--border-color-light;
|
border-top: 1px solid $--border-color-light;
|
||||||
.chart-dataLink-item{
|
.chart-dataLink-item{
|
||||||
|
min-width: 120px;
|
||||||
|
max-width: 500px;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
&:hover{
|
&:hover{
|
||||||
background: $--background-color-base;
|
background: $--background-color-base;
|
||||||
color: $--color-primary !important;
|
color: $--color-primary !important;
|
||||||
}
|
}
|
||||||
.nz-icon{
|
.nz-icon{
|
||||||
margin-right: 2px;
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -808,3 +782,20 @@
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chart-cursor-default{
|
||||||
|
cursor: default !important;
|
||||||
|
*{
|
||||||
|
cursor: default !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-cursor-pointer{
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabel-chart{
|
||||||
|
.chart-canvas-tooltip{
|
||||||
|
height: auto !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -286,7 +286,7 @@ import chartTopology from './chart/chartTopology'
|
|||||||
import chartBubble from './chart/chartBubble'
|
import chartBubble from './chart/chartBubble'
|
||||||
import chartRank from './chart/chartRank'
|
import chartRank from './chart/chartRank'
|
||||||
import chartSankey from './chart/chartSankey'
|
import chartSankey from './chart/chartSankey'
|
||||||
import chartFunnel from './chart/chartFunnelNew'
|
import chartFunnel from './chart/chartFunnel'
|
||||||
import { getOption, isTimeSeries, isHexagon, isUrl, isText, isChartPie, isDoughnut, isRose, isChartBar, isTreemap, isLog, isStat, isDiagram, isGroup, isAutotopology, isMap, isAssetInfo, isEndpointInfo, isTable, isGauge, isClock, isTopology, isChartBubble, isChartRank, isSankey, isFunnel } from './chart/tools'
|
import { getOption, isTimeSeries, isHexagon, isUrl, isText, isChartPie, isDoughnut, isRose, isChartBar, isTreemap, isLog, isStat, isDiagram, isGroup, isAutotopology, isMap, isAssetInfo, isEndpointInfo, isTable, isGauge, isClock, isTopology, isChartBubble, isChartRank, isSankey, isFunnel } from './chart/tools'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
class="nz-chart__component nz-chart__component--time-series" @mouseenter="mouseEnterChart"
|
class="nz-chart__component nz-chart__component--time-series" @mouseenter="mouseEnterChart"
|
||||||
@mouseleave="mouseLeaveChart"
|
@mouseleave="mouseLeaveChart"
|
||||||
>
|
>
|
||||||
<div :id="`chart-canvas-${chartId}`" class="chart__canvas"></div>
|
<div :id="`chart-canvas-${chartId}`" class="chart__canvas" :class="{'chart-cursor-default':!dataLink.length}"></div>
|
||||||
<chart-legend
|
<chart-legend
|
||||||
v-if="hasLegend"
|
v-if="hasLegend"
|
||||||
:chart-data="chartData"
|
:chart-data="chartData"
|
||||||
@@ -14,6 +14,26 @@
|
|||||||
:series="series"
|
:series="series"
|
||||||
:is-fullscreen="isFullscreen"
|
:is-fullscreen="isFullscreen"
|
||||||
></chart-legend>
|
></chart-legend>
|
||||||
|
|
||||||
|
<div :id="`chart-canvas-tooltip-${chartId}`" class="chart-canvas-tooltip no-style-class" :class="{'chart-dataLink-tooltip':tooltip.dataLinkShow}" :style="{left:tooltip.x+'px',top:tooltip.y+'px'}" v-if="tooltip.show" v-clickoutside="clickout">
|
||||||
|
<div class="chart-canvas-tooltip-title tooltip-title">{{tooltip.title}}</div>
|
||||||
|
<div class="chart-canvas-tooltip-content">
|
||||||
|
<div>value</div>
|
||||||
|
<div>
|
||||||
|
<div v-if="tooltip.mapping && tooltip.mapping.icon" style="display: inline-block">
|
||||||
|
<i :class="tooltip.mapping.icon" :style="{color: tooltip.mapping.color.icon}"></i>
|
||||||
|
</div>
|
||||||
|
<div style="display: inline-block">{{tooltip.value}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- dataLink -->
|
||||||
|
<div class="chart-dataLink-list" v-if="tooltip.dataLinkShow">
|
||||||
|
<div class="chart-dataLink-item" v-for="(item,index) in dataLink" :key="index" @click="linkClick(item)">
|
||||||
|
<i class="nz-icon nz-icon-link"></i>
|
||||||
|
<span>{{item.title}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -28,7 +48,6 @@ import { formatScientificNotation, getMetricTypeValue } from '@/components/commo
|
|||||||
import chartDataFormat from '@/components/chart/chartDataFormat'
|
import chartDataFormat from '@/components/chart/chartDataFormat'
|
||||||
import { initColor } from '@/components/chart/chart/tools'
|
import { initColor } from '@/components/chart/chart/tools'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import bus from '@/libs/bus'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'chart-bar',
|
name: 'chart-bar',
|
||||||
@@ -45,7 +64,7 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
hasLegend () {
|
hasLegend () {
|
||||||
try {
|
try {
|
||||||
return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1
|
return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1 && this.chartInfo.param.enable.legend
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -75,11 +94,21 @@ export default {
|
|||||||
active: '#53a3cb',
|
active: '#53a3cb',
|
||||||
inactive: '#7e7e7e'
|
inactive: '#7e7e7e'
|
||||||
},
|
},
|
||||||
chartId: ''
|
chartId: '',
|
||||||
|
tooltip: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
title: 0,
|
||||||
|
value: 0,
|
||||||
|
mapping: {},
|
||||||
|
show: false,
|
||||||
|
dataLinkShow: ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initChart (chartOption = this.chartOption) {
|
initChart (chartOption = this.chartOption) {
|
||||||
|
this.setDataLink()
|
||||||
const self = this
|
const self = this
|
||||||
this.legends = []
|
this.legends = []
|
||||||
this.series = chartOption.series = this.initBarData(this.chartInfo, chartOption.series[0], this.chartData) // 生成series和legends
|
this.series = chartOption.series = this.initBarData(this.chartInfo, chartOption.series[0], this.chartData) // 生成series和legends
|
||||||
@@ -132,6 +161,15 @@ export default {
|
|||||||
}
|
}
|
||||||
myChart.setOption(chartOption)
|
myChart.setOption(chartOption)
|
||||||
this.isInit && setChart(this.chartId, myChart) // 缓存;不使用vue的data是为避免整个chart被监听导致卡顿
|
this.isInit && setChart(this.chartId, myChart) // 缓存;不使用vue的data是为避免整个chart被监听导致卡顿
|
||||||
|
if (this.isInit && this.dataLink.length) {
|
||||||
|
myChart.on('click', this.chartClick)
|
||||||
|
myChart.on('mousedown', (params) => {
|
||||||
|
if (this.tooltip.show) {
|
||||||
|
const e = params.event.event
|
||||||
|
e.stopPropagation()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
this.isInit = false
|
this.isInit = false
|
||||||
}, 200)
|
}, 200)
|
||||||
},
|
},
|
||||||
@@ -183,10 +221,8 @@ export default {
|
|||||||
formatterFunc (params, ticket, callback) {
|
formatterFunc (params, ticket, callback) {
|
||||||
const self = this
|
const self = this
|
||||||
return `
|
return `
|
||||||
<div>
|
<div class="chart-canvas-tooltip-title tooltip-title">${params.data.alias}</div>
|
||||||
<div style="white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis; min-width: 150px; max-width: 600px; line-height: 18px; font-size: 14px;">
|
<div class="chart-canvas-tooltip-content">
|
||||||
<div class="tooltip-title" style="max-width: 500px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom: 5px">${params.data.alias}</div>
|
|
||||||
<div style="font-size:12px;display:flex;justify-content: space-between;">
|
|
||||||
<div>value</div>
|
<div>value</div>
|
||||||
<div>
|
<div>
|
||||||
<div style="display: ${params.data.mapping && params.data.mapping.icon ? 'inline-block' : 'none'}">
|
<div style="display: ${params.data.mapping && params.data.mapping.icon ? 'inline-block' : 'none'}">
|
||||||
@@ -196,9 +232,58 @@ export default {
|
|||||||
<div style="display: ${params.data.mapping && params.data.mapping.display ? 'inline-block' : 'none'}">${self.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.showValue })}</div>
|
<div style="display: ${params.data.mapping && params.data.mapping.display ? 'inline-block' : 'none'}">${self.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.showValue })}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
`
|
||||||
|
},
|
||||||
|
setPosition (e) {
|
||||||
|
const windowWidth = window.innerWidth// 窗口宽度
|
||||||
|
const windowHeight = window.innerHeight// 窗口高度
|
||||||
|
this.$nextTick(() => {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
chartClick (params) {
|
||||||
|
const option = {
|
||||||
|
tooltip: {
|
||||||
|
extraCssText: 'z-index:99999999;visibility:hidden;transition:none;'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getChart(this.chartId).setOption(option)
|
||||||
|
this.tooltip.title = params.data.alias
|
||||||
|
this.tooltip.value = params.data.mapping && params.data.mapping.display ? this.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.showValue }) : params.data.showValue
|
||||||
|
this.tooltip.mapping = params.data.mapping
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.tooltip.dataLinkShow = true
|
||||||
|
const e = params.event.event
|
||||||
|
this.setPosition(e)
|
||||||
|
},
|
||||||
|
clickout () {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.show = false
|
||||||
|
this.tooltip.dataLinkShow = false
|
||||||
|
const option = {
|
||||||
|
tooltip: {
|
||||||
|
extraCssText: 'z-index:99999999;visibility:visible;'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getChart(this.chartId).setOption(option)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
ref="bubble-chart-box"
|
ref="bubble-chart-box"
|
||||||
class="nz-chart__component"
|
class="nz-chart__component"
|
||||||
>
|
>
|
||||||
<div :id="`chart-canvas-${chartId}`" class="chart__canvas">
|
<div :id="`chart-canvas-${chartId}`" class="chart__canvas" :class="{'chart-cursor-default':!dataLink.length}">
|
||||||
<svg :id="`bubble-svg-${chartId}`" width="100%" height="100%"></svg>
|
<svg :id="`bubble-svg-${chartId}`" width="100%" height="100%"></svg>
|
||||||
</div>
|
</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 :id="`chart-canvas-tooltip-${chartId}`" class="chart-canvas-tooltip no-style-class" :class="{'chart-dataLink-tooltip':tooltip.dataLinkShow}" :style="{left:tooltip.x+'px',top:tooltip.y+'px'}" v-if="tooltip.show" v-clickoutside="clickout">
|
||||||
<div class="chart-canvas-tooltip-title tooltip-title">
|
<div class="chart-canvas-tooltip-title tooltip-title">
|
||||||
{{tooltip.title}}
|
{{tooltip.title}}
|
||||||
</div>
|
</div>
|
||||||
@@ -19,6 +19,13 @@
|
|||||||
<div style="display: inline-block">{{tooltip.value}}</div>
|
<div style="display: inline-block">{{tooltip.value}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- dataLink -->
|
||||||
|
<div class="chart-dataLink-list" v-if="tooltip.dataLinkShow">
|
||||||
|
<div class="chart-dataLink-item" v-for="(item,index) in dataLink" :key="index" @click="linkClick(item)">
|
||||||
|
<i class="nz-icon nz-icon-link"></i>
|
||||||
|
<span>{{item.title}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -57,13 +64,15 @@ export default {
|
|||||||
title: 0,
|
title: 0,
|
||||||
value: 0,
|
value: 0,
|
||||||
mapping: {},
|
mapping: {},
|
||||||
show: false
|
show: false,
|
||||||
|
dataLinkShow: ''
|
||||||
},
|
},
|
||||||
svg: null
|
svg: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initChart () {
|
initChart () {
|
||||||
|
this.setDataLink()
|
||||||
this.legends = []
|
this.legends = []
|
||||||
this.initBubbleData(this.chartInfo, this.chartData)
|
this.initBubbleData(this.chartInfo, this.chartData)
|
||||||
if (this.isNoData) {
|
if (this.isNoData) {
|
||||||
@@ -180,12 +189,14 @@ export default {
|
|||||||
return fontSize
|
return fontSize
|
||||||
})
|
})
|
||||||
.style('border-radius', '50%')
|
.style('border-radius', '50%')
|
||||||
|
.style('cursor', 'pointer')
|
||||||
.html((d) => {
|
.html((d) => {
|
||||||
return this.bubbleFormatterLabel(d)
|
return this.bubbleFormatterLabel(d)
|
||||||
})
|
})
|
||||||
bubbles.on('mouseenter', this.bubbleEnter)
|
bubbles.on('mouseenter', this.bubbleEnter)
|
||||||
bubbles.on('mousemove', this.bubbleMove)
|
bubbles.on('mousemove', this.bubbleMove)
|
||||||
bubbles.on('mouseleave', this.bubbleLeave)
|
bubbles.on('mouseleave', this.bubbleLeave)
|
||||||
|
bubbles.on('click', this.chartClick)
|
||||||
},
|
},
|
||||||
// 处理label
|
// 处理label
|
||||||
bubbleFormatterLabel (node) {
|
bubbleFormatterLabel (node) {
|
||||||
@@ -206,7 +217,7 @@ export default {
|
|||||||
}
|
}
|
||||||
if (str && valueStr) {
|
if (str && valueStr) {
|
||||||
return `
|
return `
|
||||||
<div style="width:100%;height: 100%;display: flex;align-items: center;justify-content: center;flex-direction: column;cursor: pointer;color:#000000">
|
<div style="width:100%;height: 100%;display: flex;align-items: center;justify-content: center;flex-direction: column;color:#000000">
|
||||||
<p style="width: 80%;text-overflow: ellipsis;white-space: nowrap;overflow:hidden;text-align:center;color: ${node.data.mapping && node.data.mapping.color && node.data.mapping.color.text};">
|
<p style="width: 80%;text-overflow: ellipsis;white-space: nowrap;overflow:hidden;text-align:center;color: ${node.data.mapping && node.data.mapping.color && node.data.mapping.color.text};">
|
||||||
<span>${str}</span>
|
<span>${str}</span>
|
||||||
</p>
|
</p>
|
||||||
@@ -218,7 +229,7 @@ export default {
|
|||||||
`
|
`
|
||||||
} else if (str) {
|
} else if (str) {
|
||||||
return `
|
return `
|
||||||
<div style="width:100%;height: 100%;display: flex;align-items: center;justify-content: center;flex-direction: column;cursor: pointer;color:#000000">
|
<div style="width:100%;height: 100%;display: flex;align-items: center;justify-content: center;flex-direction: column;color:#000000">
|
||||||
<p style="width: 80%;text-overflow: ellipsis;white-space: nowrap;overflow:hidden;text-align:center;color: ${node.data.mapping && node.data.mapping.color && node.data.mapping.color.text};">
|
<p style="width: 80%;text-overflow: ellipsis;white-space: nowrap;overflow:hidden;text-align:center;color: ${node.data.mapping && node.data.mapping.color && node.data.mapping.color.text};">
|
||||||
<i class="${node.data.mapping && node.data.mapping.icon}" style="color: ${node.data.mapping && node.data.mapping.color && node.data.mapping.color.icon};font-size:1em;"></i>
|
<i class="${node.data.mapping && node.data.mapping.icon}" style="color: ${node.data.mapping && node.data.mapping.color && node.data.mapping.color.icon};font-size:1em;"></i>
|
||||||
<span>${str}</span>
|
<span>${str}</span>
|
||||||
@@ -227,7 +238,7 @@ export default {
|
|||||||
`
|
`
|
||||||
} else if (valueStr) {
|
} else if (valueStr) {
|
||||||
return `
|
return `
|
||||||
<div style="width:100%;height: 100%;display: flex;align-items: center;justify-content: center;flex-direction: column;cursor: pointer;color:#000000">
|
<div style="width:100%;height: 100%;display: flex;align-items: center;justify-content: center;flex-direction: column;color:#000000">
|
||||||
<p style="width: 80%;text-overflow: ellipsis;white-space: nowrap;overflow:hidden;text-align:center;color: ${node.data.mapping && node.data.mapping.color && node.data.mapping.color.text};">
|
<p style="width: 80%;text-overflow: ellipsis;white-space: nowrap;overflow:hidden;text-align:center;color: ${node.data.mapping && node.data.mapping.color && node.data.mapping.color.text};">
|
||||||
<i class="${node.data.mapping && node.data.mapping.icon}" style="color: ${node.data.mapping && node.data.mapping.color && node.data.mapping.color.icon};font-size:1em;"></i>
|
<i class="${node.data.mapping && node.data.mapping.icon}" style="color: ${node.data.mapping && node.data.mapping.color && node.data.mapping.color.icon};font-size:1em;"></i>
|
||||||
<span>${valueStr}</span>
|
<span>${valueStr}</span>
|
||||||
@@ -237,23 +248,26 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
bubbleEnter (e, node) { // 移入气泡
|
bubbleEnter (e, node) { // 移入气泡
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
this.tooltip.title = node.data.alias
|
this.tooltip.title = node.data.alias
|
||||||
this.tooltip.value = node.data.showValue
|
this.tooltip.value = node.data.mapping && node.data.mapping.display ? this.handleDisplay(node.data.mapping.display, { ...node.data.labels, value: node.data.showValue }) : node.data.showValue
|
||||||
this.tooltip.mapping = node.data.mapping
|
this.tooltip.mapping = node.data.mapping
|
||||||
this.tooltip.show = true
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
},
|
},
|
||||||
bubbleMove (e) { // 气泡内移动
|
bubbleMove (e) { // 气泡内移动
|
||||||
if (this.tooltip.show) {
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
}
|
|
||||||
},
|
},
|
||||||
bubbleLeave () { // 移出气泡
|
bubbleLeave () { // 移出气泡
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
this.tooltip.show = false
|
this.tooltip.show = false
|
||||||
},
|
},
|
||||||
setPosition (e) {
|
setPosition (e) {
|
||||||
const windowWidth = window.innerWidth// 窗口宽度
|
const windowWidth = window.innerWidth// 窗口宽度
|
||||||
const windowHeight = window.innerHeight// 窗口高度
|
const windowHeight = window.innerHeight// 窗口高度
|
||||||
|
this.$nextTick(() => {
|
||||||
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
||||||
if (box) {
|
if (box) {
|
||||||
const boxWidth = box.offsetWidth
|
const boxWidth = box.offsetWidth
|
||||||
@@ -272,6 +286,7 @@ export default {
|
|||||||
this.tooltip.y = e.pageY + 15
|
this.tooltip.y = e.pageY + 15
|
||||||
this.tooltip.x = e.pageX + 15
|
this.tooltip.x = e.pageX + 15
|
||||||
}
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
resize () {
|
resize () {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -283,9 +298,26 @@ export default {
|
|||||||
this.svg.selectAll('.bubble').on('mouseenter', null)
|
this.svg.selectAll('.bubble').on('mouseenter', null)
|
||||||
this.svg.selectAll('.bubble').on('mousemove', null)
|
this.svg.selectAll('.bubble').on('mousemove', null)
|
||||||
this.svg.selectAll('.bubble').on('mouseleave', null)
|
this.svg.selectAll('.bubble').on('mouseleave', null)
|
||||||
|
this.svg.selectAll('.bubble').on('click', null)
|
||||||
this.svg.selectAll('g').remove()
|
this.svg.selectAll('g').remove()
|
||||||
this.svg = null
|
this.svg = null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
chartClick (e, data) {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.title = data.data.alias
|
||||||
|
this.tooltip.value = data.data.mapping && data.data.mapping.display ? this.handleDisplay(data.data.mapping.display, { ...data.data.labels, value: data.data.showValue }) : data.data.showValue
|
||||||
|
this.tooltip.mapping = data.data.mapping
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.tooltip.dataLinkShow = true
|
||||||
|
this.setPosition(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clickout () {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.show = false
|
||||||
|
this.tooltip.dataLinkShow = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
hasLegend () {
|
hasLegend () {
|
||||||
try {
|
try {
|
||||||
return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1
|
return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1 && this.chartInfo.param.enable.legend
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
ref="doughnut-chart-box"
|
ref="doughnut-chart-box"
|
||||||
class="nz-chart__component"
|
class="nz-chart__component"
|
||||||
>
|
>
|
||||||
<div :id="`chart-canvas-${chartId}`" class="chart__canvas" style="overflow: hidden;"></div>
|
<div :id="`chart-canvas-${chartId}`" class="chart__canvas" :class="{'chart-cursor-default':!dataLink.length}" style="overflow: hidden;"></div>
|
||||||
|
|
||||||
<chart-legend
|
<chart-legend
|
||||||
v-if="hasLegend"
|
v-if="hasLegend"
|
||||||
:chart-data="chartData"
|
:chart-data="chartData"
|
||||||
@@ -13,7 +14,8 @@
|
|||||||
:is-fullscreen="isFullscreen"
|
:is-fullscreen="isFullscreen"
|
||||||
@clickLegendD3="clickLegendD3"
|
@clickLegendD3="clickLegendD3"
|
||||||
></chart-legend>
|
></chart-legend>
|
||||||
<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 :id="`chart-canvas-tooltip-${chartId}`" class="chart-canvas-tooltip no-style-class" :class="{'chart-dataLink-tooltip':tooltip.dataLinkShow}" :style="{left:tooltip.x+'px',top:tooltip.y+'px'}" v-if="tooltip.show" v-clickoutside="clickout">
|
||||||
<div class="chart-canvas-tooltip-title tooltip-title">
|
<div class="chart-canvas-tooltip-title tooltip-title">
|
||||||
{{tooltip.title}}
|
{{tooltip.title}}
|
||||||
</div>
|
</div>
|
||||||
@@ -30,6 +32,13 @@
|
|||||||
<div>percent</div>
|
<div>percent</div>
|
||||||
<div>{{tooltip.percent}}%</div>
|
<div>{{tooltip.percent}}%</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- dataLink -->
|
||||||
|
<div class="chart-dataLink-list" v-if="tooltip.dataLinkShow">
|
||||||
|
<div class="chart-dataLink-item" v-for="(item,index) in dataLink" :key="index" @click="linkClick(item)">
|
||||||
|
<i class="nz-icon nz-icon-link"></i>
|
||||||
|
<span>{{item.title}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -59,7 +68,7 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
hasLegend () {
|
hasLegend () {
|
||||||
try {
|
try {
|
||||||
return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1
|
return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1 && this.chartInfo.param.enable.legend
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -91,15 +100,16 @@ export default {
|
|||||||
y: 0,
|
y: 0,
|
||||||
title: 0,
|
title: 0,
|
||||||
value: 0,
|
value: 0,
|
||||||
percent: 0,
|
|
||||||
mapping: {},
|
mapping: {},
|
||||||
show: false
|
show: false,
|
||||||
|
dataLinkShow: ''
|
||||||
},
|
},
|
||||||
svg: null
|
svg: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initChart (animate) {
|
initChart (animate) {
|
||||||
|
this.setDataLink()
|
||||||
this.legends = []
|
this.legends = []
|
||||||
this.initDoughnutData(this.chartInfo, this.chartData)
|
this.initDoughnutData(this.chartInfo, this.chartData)
|
||||||
this.selectData = this.$loadsh.cloneDeep(this.doughnutData)
|
this.selectData = this.$loadsh.cloneDeep(this.doughnutData)
|
||||||
@@ -223,6 +233,7 @@ export default {
|
|||||||
.on('mouseenter', this.doughnutEnter)
|
.on('mouseenter', this.doughnutEnter)
|
||||||
.on('mousemove', this.doughnutMove)
|
.on('mousemove', this.doughnutMove)
|
||||||
.on('mouseleave', this.doughnutLeave)
|
.on('mouseleave', this.doughnutLeave)
|
||||||
|
.on('click', this.chartClick)
|
||||||
.transition().duration(animate === true ? 600 : 0)
|
.transition().duration(animate === true ? 600 : 0)
|
||||||
.attrTween('d', function (d) {
|
.attrTween('d', function (d) {
|
||||||
const i = d3.interpolate({ startAngle: 0, endAngle: 0 }, d)
|
const i = d3.interpolate({ startAngle: 0, endAngle: 0 }, d)
|
||||||
@@ -247,6 +258,7 @@ export default {
|
|||||||
.on('mouseenter', this.doughnutEnter)
|
.on('mouseenter', this.doughnutEnter)
|
||||||
.on('mousemove', this.doughnutMove)
|
.on('mousemove', this.doughnutMove)
|
||||||
.on('mouseleave', this.doughnutLeave)
|
.on('mouseleave', this.doughnutLeave)
|
||||||
|
.on('click', this.chartClick)
|
||||||
.style('opacity', 0)
|
.style('opacity', 0)
|
||||||
.html((d) => {
|
.html((d) => {
|
||||||
return d.endAngle - d.startAngle > 0.25 ? this.formatterLabel(d) : ''
|
return d.endAngle - d.startAngle > 0.25 ? this.formatterLabel(d) : ''
|
||||||
@@ -305,26 +317,28 @@ export default {
|
|||||||
`
|
`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
doughnutEnter (e, node) { // 移入气泡
|
doughnutEnter (e, node) {
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
this.tooltip.title = node.data.alias
|
this.tooltip.title = node.data.alias
|
||||||
this.tooltip.value = node.data.showValue
|
this.tooltip.value = node.data.mapping && node.data.mapping.display ? this.handleDisplay(node.data.mapping.display, { ...node.data.labels, value: node.data.showValue }) : node.data.showValue
|
||||||
this.tooltip.percent = node.percent
|
this.tooltip.percent = node.percent
|
||||||
this.tooltip.mapping = node.data.mapping
|
this.tooltip.mapping = node.data.mapping
|
||||||
this.tooltip.show = true
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
},
|
},
|
||||||
doughnutMove (e) { // 气泡内移动
|
doughnutMove (e) {
|
||||||
if (this.tooltip.show) {
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
this.tooltip.show = true
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
}
|
|
||||||
},
|
},
|
||||||
doughnutLeave () { // 移出气泡
|
doughnutLeave () {
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
this.tooltip.show = false
|
this.tooltip.show = false
|
||||||
},
|
},
|
||||||
setPosition (e) {
|
setPosition (e) {
|
||||||
const windowWidth = window.innerWidth// 窗口宽度
|
const windowWidth = window.innerWidth// 窗口宽度
|
||||||
const windowHeight = window.innerHeight// 窗口高度
|
const windowHeight = window.innerHeight// 窗口高度
|
||||||
|
this.$nextTick(() => {
|
||||||
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
||||||
if (box) {
|
if (box) {
|
||||||
const boxWidth = box.offsetWidth
|
const boxWidth = box.offsetWidth
|
||||||
@@ -343,6 +357,7 @@ export default {
|
|||||||
this.tooltip.y = e.pageY + 15
|
this.tooltip.y = e.pageY + 15
|
||||||
this.tooltip.x = e.pageX + 15
|
this.tooltip.x = e.pageX + 15
|
||||||
}
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
clickLegendD3 (isGrey) {
|
clickLegendD3 (isGrey) {
|
||||||
const data = this.doughnutData.filter((item, i) => !isGrey[i])
|
const data = this.doughnutData.filter((item, i) => !isGrey[i])
|
||||||
@@ -361,14 +376,32 @@ export default {
|
|||||||
this.svg.selectAll('path').on('mouseenter', null)
|
this.svg.selectAll('path').on('mouseenter', null)
|
||||||
this.svg.selectAll('path').on('mousemove', null)
|
this.svg.selectAll('path').on('mousemove', null)
|
||||||
this.svg.selectAll('path').on('mouseleave', null)
|
this.svg.selectAll('path').on('mouseleave', null)
|
||||||
|
this.svg.selectAll('path').on('click', null)
|
||||||
this.svg.selectAll('foreignObject').on('mouseover', null)
|
this.svg.selectAll('foreignObject').on('mouseover', null)
|
||||||
this.svg.selectAll('foreignObject').on('mouseout', null)
|
this.svg.selectAll('foreignObject').on('mouseout', null)
|
||||||
this.svg.selectAll('foreignObject').on('mouseenter', null)
|
this.svg.selectAll('foreignObject').on('mouseenter', null)
|
||||||
this.svg.selectAll('foreignObject').on('mousemove', null)
|
this.svg.selectAll('foreignObject').on('mousemove', null)
|
||||||
this.svg.selectAll('foreignObject').on('mouseleave', null)
|
this.svg.selectAll('foreignObject').on('mouseleave', null)
|
||||||
|
this.svg.selectAll('foreignObject').on('click', null)
|
||||||
this.svg.remove()
|
this.svg.remove()
|
||||||
this.svg = null
|
this.svg = null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
chartClick (e, data) {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.title = data.data.alias
|
||||||
|
this.tooltip.value = data.data.mapping && data.data.mapping.display ? this.handleDisplay(data.data.mapping.display, { ...data.data.labels, value: data.data.showValue }) : data.data.showValue
|
||||||
|
this.tooltip.mapping = data.data.mapping
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.tooltip.dataLinkShow = true
|
||||||
|
this.setPosition(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clickout () {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.show = false
|
||||||
|
this.tooltip.dataLinkShow = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|||||||
@@ -3,8 +3,11 @@
|
|||||||
ref="funnel-chart-box"
|
ref="funnel-chart-box"
|
||||||
class="nz-chart__component"
|
class="nz-chart__component"
|
||||||
>
|
>
|
||||||
<div :id="`chart-canvas-${chartId}`" class="chart__canvas" style="display:flex;justify-content: center;align-items: center;"></div>
|
<div :id="`chart-canvas-${chartId}`" class="chart__canvas" :class="{'chart-cursor-default':!dataLink.length}">
|
||||||
<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">
|
<svg :id="`funnel-svg-${chartId}`" width="100%" height="100%"></svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div :id="`chart-canvas-tooltip-${chartId}`" class="chart-canvas-tooltip no-style-class" :class="{'chart-dataLink-tooltip':tooltip.dataLinkShow}" :style="{left:tooltip.x+'px',top:tooltip.y+'px'}" v-if="tooltip.show" v-clickoutside="clickout">
|
||||||
<div class="chart-canvas-tooltip-title tooltip-title">
|
<div class="chart-canvas-tooltip-title tooltip-title">
|
||||||
{{tooltip.title}}
|
{{tooltip.title}}
|
||||||
</div>
|
</div>
|
||||||
@@ -17,18 +20,24 @@
|
|||||||
<div style="display: inline-block">{{tooltip.value}}</div>
|
<div style="display: inline-block">{{tooltip.value}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- dataLink -->
|
||||||
|
<div class="chart-dataLink-list" v-if="tooltip.dataLinkShow">
|
||||||
|
<div class="chart-dataLink-item" v-for="(item,index) in dataLink" :key="index" @click="linkClick(item)">
|
||||||
|
<i class="nz-icon nz-icon-link"></i>
|
||||||
|
<span>{{item.title}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import D3Funnel from './d3-funnel/index.js'
|
import * as d3 from 'd3'
|
||||||
import chartMixin from '@/components/chart/chartMixin'
|
import chartMixin from '@/components/chart/chartMixin'
|
||||||
import chartFormat from '@/components/chart/chartFormat'
|
import chartFormat from '@/components/chart/chartFormat'
|
||||||
import { getMetricTypeValue } from '@/components/common/js/tools'
|
import { getMetricTypeValue } from '@/components/common/js/tools'
|
||||||
import chartDataFormat from '@/components/chart/chartDataFormat'
|
import chartDataFormat from '@/components/chart/chartDataFormat'
|
||||||
import { initColor } from '@/components/chart/chart/tools'
|
import { initColor } from '@/components/chart/chart/tools'
|
||||||
import { getChart, setChart } from '@/components/common/js/common'
|
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -56,12 +65,15 @@ export default {
|
|||||||
title: 0,
|
title: 0,
|
||||||
value: 0,
|
value: 0,
|
||||||
mapping: {},
|
mapping: {},
|
||||||
show: false
|
show: false,
|
||||||
}
|
dataLinkShow: ''
|
||||||
|
},
|
||||||
|
svg: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initChart (customAnimate) {
|
initChart (animate) {
|
||||||
|
this.setDataLink()
|
||||||
this.legends = []
|
this.legends = []
|
||||||
this.initData(this.chartInfo, this.chartData)
|
this.initData(this.chartInfo, this.chartData)
|
||||||
if (this.isNoData) {
|
if (this.isNoData) {
|
||||||
@@ -69,7 +81,7 @@ export default {
|
|||||||
}
|
}
|
||||||
/* 使用setTimeout延迟渲染图表,避免样式错乱 */
|
/* 使用setTimeout延迟渲染图表,避免样式错乱 */
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.drawChart(customAnimate)
|
this.drawChart(animate)
|
||||||
}, 200)
|
}, 200)
|
||||||
},
|
},
|
||||||
initData (chartInfo, originalDatas) {
|
initData (chartInfo, originalDatas) {
|
||||||
@@ -97,7 +109,7 @@ export default {
|
|||||||
seriesIndex: expressionIndex,
|
seriesIndex: expressionIndex,
|
||||||
dataIndex: dataIndex,
|
dataIndex: dataIndex,
|
||||||
mapping: mapping,
|
mapping: mapping,
|
||||||
backgroundColor: mapping ? mapping.color.bac.substr(0, 7) : this.colorList[colorIndex], // 仅限十六进制
|
background: mapping ? mapping.color.bac.substr(0, 7) : this.colorList[colorIndex], // 仅限十六进制
|
||||||
label: legend.alias
|
label: legend.alias
|
||||||
})
|
})
|
||||||
colorIndex++
|
colorIndex++
|
||||||
@@ -106,7 +118,7 @@ export default {
|
|||||||
this.funnelData.sort((a, b) => b.value - a.value)
|
this.funnelData.sort((a, b) => b.value - a.value)
|
||||||
this.$emit('chartIsNoData', this.isNoData)
|
this.$emit('chartIsNoData', this.isNoData)
|
||||||
},
|
},
|
||||||
drawChart (customAnimate) {
|
drawChart (animate) {
|
||||||
let funnelData = lodash.cloneDeep(this.funnelData)
|
let funnelData = lodash.cloneDeep(this.funnelData)
|
||||||
const everyZeor = funnelData.every(item => item.value == 0)
|
const everyZeor = funnelData.every(item => item.value == 0)
|
||||||
// 判断值是否全部为0
|
// 判断值是否全部为0
|
||||||
@@ -120,42 +132,120 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
funnelData = funnelData.filter(item => item.value !== 0)
|
funnelData = funnelData.filter(item => item.value !== 0)
|
||||||
}
|
}
|
||||||
this.$nextTick(() => {
|
this.dispose()
|
||||||
const options = {
|
// 获取svg宽高 初始化画布
|
||||||
chart: {
|
const svgDom = document.getElementById(`funnel-svg-${this.chartId}`)
|
||||||
width: '85%',
|
if (!svgDom) {
|
||||||
height: '85%',
|
return false
|
||||||
bottomPinch: funnelData.length > 1 ? 1 : 0,
|
|
||||||
customAnimate: customAnimate === true || this.isInit
|
|
||||||
},
|
|
||||||
block: {
|
|
||||||
dynamicHeight: false,
|
|
||||||
highlight: true
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
format: this.formatterLabel
|
|
||||||
},
|
|
||||||
events: {
|
|
||||||
mouseenter: {
|
|
||||||
block: this.chartEnter
|
|
||||||
},
|
|
||||||
mousemove: {
|
|
||||||
block: this.chartMove
|
|
||||||
},
|
|
||||||
mouseleave: {
|
|
||||||
block: this.chartLeave
|
|
||||||
}
|
}
|
||||||
|
const width = svgDom.getBoundingClientRect().width
|
||||||
|
const height = svgDom.getBoundingClientRect().height
|
||||||
|
const margin = 20
|
||||||
|
const chartWidth = width - margin * 2
|
||||||
|
const chartHeight = height - margin * 2
|
||||||
|
|
||||||
|
// 每个块的高度
|
||||||
|
const trapezoidPadding = 2
|
||||||
|
const trapezoidsHeight = (chartHeight - trapezoidPadding * (funnelData.length - 1)) / funnelData.length
|
||||||
|
|
||||||
|
const scale = d3.scaleLinear()
|
||||||
|
.domain([0, d3.max(funnelData, (d) => d.value)])
|
||||||
|
.range([0, chartWidth * 0.8])
|
||||||
|
|
||||||
|
// 数据处理
|
||||||
|
funnelData = funnelData.map((d, i, array) => {
|
||||||
|
d.index = i
|
||||||
|
if (i !== array.length - 1) {
|
||||||
|
d.nextValue = array[i + 1].value
|
||||||
|
} else {
|
||||||
|
d.nextValue = 0
|
||||||
}
|
}
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
)
|
||||||
|
this.svg = d3.select(`#funnel-svg-${this.chartId}`)
|
||||||
|
const chart = this.svg.append('g').attr('width', chartWidth).attr('height', chartHeight).attr('transform', `translate(${margin}, ${margin})`)
|
||||||
|
|
||||||
|
// 渲染梯形
|
||||||
|
const trapezoids = chart
|
||||||
|
.append('g')
|
||||||
|
.attr('class', 'traps')
|
||||||
|
.attr('transform', 'translate(' + chartWidth / 2 + ',0)')
|
||||||
|
.selectAll('.trap')
|
||||||
|
.data(funnelData)
|
||||||
|
trapezoids.enter()
|
||||||
|
.append('polygon')
|
||||||
|
.attr('class', (d) => 'trap trap-' + d.index)
|
||||||
|
.merge(trapezoids)
|
||||||
|
.attr('points', (d) => getPoints(scale(d.value), scale(d.nextValue), trapezoidsHeight))
|
||||||
|
.attr('transform', (d, i) => 'translate(0,' + i * (trapezoidPadding + trapezoidsHeight) + ')')
|
||||||
|
.attr('fill', (d) => d.background)
|
||||||
|
.style('opacity', 0)
|
||||||
|
.transition('opacity').duration(animate === true ? 600 : 0)
|
||||||
|
.style('opacity', 1)
|
||||||
|
.style('cursor', 'pointer')
|
||||||
|
trapezoids.exit()
|
||||||
|
.remove()
|
||||||
|
|
||||||
|
// 绑定交互事件
|
||||||
|
chart.selectAll('.trap')
|
||||||
|
.on('mouseover', (e, d) => {
|
||||||
|
// 划过变色
|
||||||
|
d3.select(e.target).transition('fill').attr('fill', this.shade(d.background, 0.2))
|
||||||
|
this.chartEnter(e, d)
|
||||||
|
})
|
||||||
|
.on('mousemove', this.chartMove)
|
||||||
|
.on('mouseleave', (e, d) => {
|
||||||
|
d3.select(e.target).transition('fill').attr('fill', d.background)
|
||||||
|
this.chartLeave()
|
||||||
|
})
|
||||||
|
.on('click', this.chartClick)
|
||||||
|
|
||||||
|
function getPoints (topWidth, bottomWidth, height) {
|
||||||
|
const points = []
|
||||||
|
points.push(-topWidth / 2 + ',' + 0)
|
||||||
|
points.push(topWidth / 2 + ',' + 0)
|
||||||
|
if (bottomWidth === 0) {
|
||||||
|
points.push(0 + ',' + height)
|
||||||
|
} else {
|
||||||
|
points.push(bottomWidth / 2 + ',' + height)
|
||||||
|
points.push(-bottomWidth / 2 + ',' + height)
|
||||||
|
}
|
||||||
|
return points.join(' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
const myChart = new D3Funnel(document.getElementById(`chart-canvas-${this.chartId}`))
|
// 渲染文本标签
|
||||||
myChart.draw(funnelData, options)
|
const texts = chart.select('.traps')
|
||||||
setChart(this.chartId, myChart)
|
.selectAll('.foreign')
|
||||||
this.isInit = false
|
.data(funnelData)
|
||||||
|
texts.enter()
|
||||||
|
.append('foreignObject')
|
||||||
|
.attr('class', 'foreign')
|
||||||
|
.merge(texts)
|
||||||
|
.html((d) => this.formatterLabel(d, trapezoidsHeight))
|
||||||
|
.attr('x', 0)
|
||||||
|
.attr('y', (d, i) => i * (trapezoidPadding + trapezoidsHeight) + trapezoidsHeight / 2)
|
||||||
|
// 绑定交互事件
|
||||||
|
.on('mouseover', (e, d) => {
|
||||||
|
chart.select('.trap-' + d.index).transition('fill').attr('fill', this.shade(d.background, 0.2))
|
||||||
|
this.chartEnter(e, d)
|
||||||
})
|
})
|
||||||
|
.on('mousemove', this.chartMove)
|
||||||
|
.on('mouseleave', (e, d) => {
|
||||||
|
chart.select('.trap-' + d.index).transition('fill').attr('fill', d.background)
|
||||||
|
this.chartLeave()
|
||||||
|
})
|
||||||
|
.on('click', this.chartClick)
|
||||||
|
.style('opacity', 0)
|
||||||
|
.transition('opacity').duration(animate === true ? 600 : 0)
|
||||||
|
.style('opacity', 1)
|
||||||
|
texts.exit()
|
||||||
|
.remove()
|
||||||
|
|
||||||
|
this.isInit = false
|
||||||
},
|
},
|
||||||
// 处理label
|
// 处理label
|
||||||
formatterLabel (label, value, e, data) {
|
formatterLabel (data, height) {
|
||||||
let str = ''
|
let str = ''
|
||||||
let valueStr = ''
|
let valueStr = ''
|
||||||
if (this.chartInfo.param.text === 'all') {
|
if (this.chartInfo.param.text === 'all') {
|
||||||
@@ -172,27 +262,36 @@ export default {
|
|||||||
str += ''
|
str += ''
|
||||||
}
|
}
|
||||||
if (str && valueStr) {
|
if (str && valueStr) {
|
||||||
return `<div style="width:100%;height: 100%;display: flex;align-items: center;justify-content: center;flex-direction: column;cursor: pointer;color:#000000">
|
if (height < 32) {
|
||||||
<p class='text-ellipsis' style="width: 80%;text-align:center;color: ${data.mapping && data.mapping.color && data.mapping.color.text};">
|
return ''
|
||||||
|
}
|
||||||
|
return `<div class="foreign-label-wrap">
|
||||||
|
<p class="funnel-label" style="color: ${data.mapping && data.mapping.color && data.mapping.color.text};">
|
||||||
<span>${str}</span>
|
<span>${str}</span>
|
||||||
</p>
|
</p>
|
||||||
<p class='text-ellipsis' style="width: 80%;text-align:center;color: ${data.mapping && data.mapping.color && data.mapping.color.text};">
|
<p class="funnel-label" style="color: ${data.mapping && data.mapping.color && data.mapping.color.text};">
|
||||||
<i class="${data.mapping && data.mapping.icon}" style="color: ${data.mapping && data.mapping.color && data.mapping.color.icon};font-size:1em;"></i>
|
<i class="${data.mapping && data.mapping.icon}" style="color: ${data.mapping && data.mapping.color && data.mapping.color.icon};font-size:1em;"></i>
|
||||||
<span>${valueStr}</span>
|
<span>${valueStr}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
} else if (str) {
|
} else if (str) {
|
||||||
return `<div style="width:100%;height: 100%;display: flex;align-items: center;justify-content: center;flex-direction: column;cursor: pointer;color:#000000">
|
if (height < 16) {
|
||||||
<p class='text-ellipsis' style="width: 80%;text-align:center;color: ${data.mapping && data.mapping.color && data.mapping.color.text};">
|
return ''
|
||||||
|
}
|
||||||
|
return `<div class="foreign-label-wrap">
|
||||||
|
<p class="funnel-label" style="color: ${data.mapping && data.mapping.color && data.mapping.color.text};">
|
||||||
<i class="${data.mapping && data.mapping.icon}" style="color: ${data.mapping && data.mapping.color && data.mapping.color.icon};font-size:1em;"></i>
|
<i class="${data.mapping && data.mapping.icon}" style="color: ${data.mapping && data.mapping.color && data.mapping.color.icon};font-size:1em;"></i>
|
||||||
<span>${str}</span>
|
<span>${str}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
} else if (valueStr) {
|
} else if (valueStr) {
|
||||||
return `<div style="width:100%;height: 100%;display: flex;align-items: center;justify-content: center;flex-direction: column;cursor: pointer;color:#000000">
|
if (height < 16) {
|
||||||
<p class='text-ellipsis' style="width: 80%;text-align:center;color: ${data.mapping && data.mapping.color && data.mapping.color.text};">
|
return ''
|
||||||
|
}
|
||||||
|
return `<div class="foreign-label-wrap">
|
||||||
|
<p class="funnel-label" style="color: ${data.mapping && data.mapping.color && data.mapping.color.text};">
|
||||||
<i class="${data.mapping && data.mapping.icon}" style="color: ${data.mapping && data.mapping.color && data.mapping.color.icon};font-size:1em;"></i>
|
<i class="${data.mapping && data.mapping.icon}" style="color: ${data.mapping && data.mapping.color && data.mapping.color.icon};font-size:1em;"></i>
|
||||||
<span>${valueStr}</span>
|
<span>${valueStr}</span>
|
||||||
</p>
|
</p>
|
||||||
@@ -200,28 +299,27 @@ export default {
|
|||||||
`
|
`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
resize () {
|
chartEnter (e, data) {
|
||||||
setTimeout(() => {
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
this.drawChart()
|
this.tooltip.title = data.alias
|
||||||
}, 50)
|
this.tooltip.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.labels, value: data.showValue }) : data.showValue
|
||||||
},
|
this.tooltip.mapping = data.mapping
|
||||||
chartEnter (e, node) {
|
|
||||||
this.tooltip.title = node.data.alias
|
|
||||||
this.tooltip.value = node.data.showValue
|
|
||||||
this.tooltip.mapping = node.data.mapping
|
|
||||||
this.tooltip.show = true
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
},
|
},
|
||||||
chartMove (e) {
|
chartMove (e) {
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
this.tooltip.show = true
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
},
|
},
|
||||||
chartLeave () {
|
chartLeave () {
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
this.tooltip.show = false
|
this.tooltip.show = false
|
||||||
},
|
},
|
||||||
setPosition (e) {
|
setPosition (e) {
|
||||||
const windowWidth = window.innerWidth// 窗口宽度
|
const windowWidth = window.innerWidth// 窗口宽度
|
||||||
const windowHeight = window.innerHeight// 窗口高度
|
const windowHeight = window.innerHeight// 窗口高度
|
||||||
|
this.$nextTick(() => {
|
||||||
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
||||||
if (box) {
|
if (box) {
|
||||||
const boxWidth = box.offsetWidth
|
const boxWidth = box.offsetWidth
|
||||||
@@ -240,6 +338,80 @@ export default {
|
|||||||
this.tooltip.y = e.pageY + 15
|
this.tooltip.y = e.pageY + 15
|
||||||
this.tooltip.x = e.pageX + 15
|
this.tooltip.x = e.pageX + 15
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Convert a hex color to an RGB object.
|
||||||
|
*
|
||||||
|
* @param {string} color
|
||||||
|
*
|
||||||
|
* @returns {{R: Number, G: number, B: number}}
|
||||||
|
*/
|
||||||
|
hexToRgb (color) {
|
||||||
|
let hex = color.slice(1)
|
||||||
|
if (hex.length === 3) {
|
||||||
|
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]
|
||||||
|
}
|
||||||
|
const f = parseInt(hex, 16)
|
||||||
|
const R = f >> 16
|
||||||
|
const G = (f >> 8) & 0x00FF
|
||||||
|
const B = f & 0x0000FF
|
||||||
|
return { R, G, B }
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Shade a color to the given percentage.
|
||||||
|
*
|
||||||
|
* @param {string} color A hex color.
|
||||||
|
* @param {number} shade The shade adjustment. Can be positive or negative.
|
||||||
|
*
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
shade (color, shade) {
|
||||||
|
const { R, G, B } = this.hexToRgb(color)
|
||||||
|
const t = shade < 0 ? 0 : 255
|
||||||
|
const p = shade < 0 ? shade * -1 : shade
|
||||||
|
|
||||||
|
const converted = 0x1000000 +
|
||||||
|
((Math.round((t - R) * p) + R) * 0x10000) +
|
||||||
|
((Math.round((t - G) * p) + G) * 0x100) +
|
||||||
|
(Math.round((t - B) * p) + B)
|
||||||
|
|
||||||
|
return `#${converted.toString(16).slice(1)}`
|
||||||
|
},
|
||||||
|
resize () {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.drawChart()
|
||||||
|
}, 50)
|
||||||
|
},
|
||||||
|
dispose () {
|
||||||
|
if (this.svg) {
|
||||||
|
this.svg.selectAll('.trap').on('mouseover', null)
|
||||||
|
this.svg.selectAll('.trap').on('mousemove', null)
|
||||||
|
this.svg.selectAll('.trap').on('mouseleave', null)
|
||||||
|
this.svg.selectAll('.trap').on('click', null)
|
||||||
|
this.svg.selectAll('foreignObject').on('mouseover', null)
|
||||||
|
this.svg.selectAll('foreignObject').on('mousemove', null)
|
||||||
|
this.svg.selectAll('foreignObject').on('mouseleave', null)
|
||||||
|
this.svg.selectAll('foreignObject').on('click', null)
|
||||||
|
this.svg.selectAll('g').remove()
|
||||||
|
this.svg = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
chartClick (e, data) {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.title = data.alias
|
||||||
|
this.tooltip.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.labels, value: data.showValue }) : data.showValue
|
||||||
|
this.tooltip.mapping = data.mapping
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.tooltip.dataLinkShow = true
|
||||||
|
this.setPosition(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clickout () {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.show = false
|
||||||
|
this.tooltip.dataLinkShow = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
@@ -247,7 +419,7 @@ export default {
|
|||||||
this.chartInfo.loaded && this.initChart(true)
|
this.chartInfo.loaded && this.initChart(true)
|
||||||
},
|
},
|
||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
getChart(this.chartId) && getChart(this.chartId).destroy()
|
this.dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,389 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
ref="funnel-chart-box"
|
|
||||||
class="nz-chart__component"
|
|
||||||
>
|
|
||||||
<div :id="`chart-canvas-${chartId}`" class="chart__canvas">
|
|
||||||
<svg :id="`funnel-svg-${chartId}`" width="100%" height="100%"></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">
|
|
||||||
{{tooltip.title}}
|
|
||||||
</div>
|
|
||||||
<div class="chart-canvas-tooltip-content">
|
|
||||||
<div>value</div>
|
|
||||||
<div>
|
|
||||||
<div v-if="tooltip.mapping && tooltip.mapping.icon" style="display: inline-block">
|
|
||||||
<i :class="tooltip.mapping.icon" :style="{color: tooltip.mapping.color.icon}"></i>
|
|
||||||
</div>
|
|
||||||
<div style="display: inline-block">{{tooltip.value}}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import * as d3 from 'd3'
|
|
||||||
import chartMixin from '@/components/chart/chartMixin'
|
|
||||||
import chartFormat from '@/components/chart/chartFormat'
|
|
||||||
import { getMetricTypeValue } from '@/components/common/js/tools'
|
|
||||||
import chartDataFormat from '@/components/chart/chartDataFormat'
|
|
||||||
import { initColor } from '@/components/chart/chart/tools'
|
|
||||||
import lodash from 'lodash'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'chart-funnel',
|
|
||||||
components: {
|
|
||||||
},
|
|
||||||
mixins: [chartMixin, chartFormat],
|
|
||||||
props: {
|
|
||||||
chartInfo: Object,
|
|
||||||
chartData: Array,
|
|
||||||
chartOption: Object,
|
|
||||||
isFullscreen: Boolean
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
},
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
colorList: [],
|
|
||||||
isInit: true, // 是否是初始化,初始化时为true,图表初始化结束后设为false
|
|
||||||
chartId: '',
|
|
||||||
funnelData: [],
|
|
||||||
tooltip: {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
title: 0,
|
|
||||||
value: 0,
|
|
||||||
mapping: {},
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
svg: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initChart (animate) {
|
|
||||||
this.legends = []
|
|
||||||
this.initData(this.chartInfo, this.chartData)
|
|
||||||
if (this.isNoData) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
/* 使用setTimeout延迟渲染图表,避免样式错乱 */
|
|
||||||
setTimeout(() => {
|
|
||||||
this.drawChart(animate)
|
|
||||||
}, 200)
|
|
||||||
},
|
|
||||||
initData (chartInfo, originalDatas) {
|
|
||||||
this.funnelData = []
|
|
||||||
let colorIndex = 0
|
|
||||||
const decimals = this.chartInfo.param.decimals || 2
|
|
||||||
this.isNoData = true
|
|
||||||
originalDatas.forEach((originalData, expressionIndex) => {
|
|
||||||
originalData.forEach((data, dataIndex) => {
|
|
||||||
this.isNoData = false
|
|
||||||
const value = getMetricTypeValue(data.values, chartInfo.param.statistics)
|
|
||||||
const showValue = chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(value, null, -1, decimals)
|
|
||||||
const mapping = this.selectMapping(value, chartInfo.param.valueMapping, chartInfo.param.enable && this.chartInfo.param.enable.valueMapping)
|
|
||||||
const legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex)
|
|
||||||
this.funnelData.push({
|
|
||||||
value: Number(value),
|
|
||||||
realValue: value,
|
|
||||||
showValue: showValue,
|
|
||||||
name: legend.name,
|
|
||||||
alias: legend.alias,
|
|
||||||
labels: {
|
|
||||||
...data.metric,
|
|
||||||
legend: legend.alias
|
|
||||||
},
|
|
||||||
seriesIndex: expressionIndex,
|
|
||||||
dataIndex: dataIndex,
|
|
||||||
mapping: mapping,
|
|
||||||
background: mapping ? mapping.color.bac.substr(0, 7) : this.colorList[colorIndex], // 仅限十六进制
|
|
||||||
label: legend.alias
|
|
||||||
})
|
|
||||||
colorIndex++
|
|
||||||
})
|
|
||||||
})
|
|
||||||
this.funnelData.sort((a, b) => b.value - a.value)
|
|
||||||
this.$emit('chartIsNoData', this.isNoData)
|
|
||||||
},
|
|
||||||
drawChart (animate) {
|
|
||||||
let funnelData = lodash.cloneDeep(this.funnelData)
|
|
||||||
const everyZeor = funnelData.every(item => item.value == 0)
|
|
||||||
// 判断值是否全部为0
|
|
||||||
if (everyZeor) {
|
|
||||||
funnelData = funnelData.map(item => {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
value: 100
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
funnelData = funnelData.filter(item => item.value !== 0)
|
|
||||||
}
|
|
||||||
this.dispose()
|
|
||||||
// 获取svg宽高 初始化画布
|
|
||||||
const svgDom = document.getElementById(`funnel-svg-${this.chartId}`)
|
|
||||||
if (!svgDom) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
const width = svgDom.getBoundingClientRect().width
|
|
||||||
const height = svgDom.getBoundingClientRect().height
|
|
||||||
const margin = 20
|
|
||||||
const chartWidth = width - margin * 2
|
|
||||||
const chartHeight = height - margin * 2
|
|
||||||
|
|
||||||
// 每个块的高度
|
|
||||||
const trapezoidPadding = 2
|
|
||||||
const trapezoidsHeight = (chartHeight - trapezoidPadding * (funnelData.length - 1)) / funnelData.length
|
|
||||||
|
|
||||||
const scale = d3.scaleLinear()
|
|
||||||
.domain([0, d3.max(funnelData, (d) => d.value)])
|
|
||||||
.range([0, chartWidth * 0.8])
|
|
||||||
|
|
||||||
// 数据处理
|
|
||||||
funnelData = funnelData.map((d, i, array) => {
|
|
||||||
d.index = i
|
|
||||||
if (i !== array.length - 1) {
|
|
||||||
d.nextValue = array[i + 1].value
|
|
||||||
} else {
|
|
||||||
d.nextValue = 0
|
|
||||||
}
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
)
|
|
||||||
this.svg = d3.select(`#funnel-svg-${this.chartId}`)
|
|
||||||
const chart = this.svg.append('g').attr('width', chartWidth).attr('height', chartHeight).attr('transform', `translate(${margin}, ${margin})`)
|
|
||||||
|
|
||||||
// 渲染梯形
|
|
||||||
const trapezoids = chart
|
|
||||||
.append('g')
|
|
||||||
.attr('class', 'traps')
|
|
||||||
.attr('transform', 'translate(' + chartWidth / 2 + ',0)')
|
|
||||||
.selectAll('.trap')
|
|
||||||
.data(funnelData)
|
|
||||||
trapezoids.enter()
|
|
||||||
.append('polygon')
|
|
||||||
.attr('class', (d) => 'trap trap-' + d.index)
|
|
||||||
.merge(trapezoids)
|
|
||||||
.attr('points', (d) => getPoints(scale(d.value), scale(d.nextValue), trapezoidsHeight))
|
|
||||||
.attr('transform', (d, i) => 'translate(0,' + i * (trapezoidPadding + trapezoidsHeight) + ')')
|
|
||||||
.attr('fill', (d) => d.background)
|
|
||||||
.style('opacity', 0)
|
|
||||||
.transition('opacity').duration(animate === true ? 600 : 0)
|
|
||||||
.style('opacity', 1)
|
|
||||||
.style('cursor', 'pointer')
|
|
||||||
trapezoids.exit()
|
|
||||||
.remove()
|
|
||||||
|
|
||||||
// 绑定交互事件
|
|
||||||
chart.selectAll('.trap')
|
|
||||||
.on('mouseover', (e, d) => {
|
|
||||||
// 划过变色
|
|
||||||
d3.select(e.target).transition('fill').attr('fill', this.shade(d.background, 0.2))
|
|
||||||
this.chartEnter(e, d)
|
|
||||||
})
|
|
||||||
.on('mousemove', this.chartMove)
|
|
||||||
.on('mouseleave', (e, d) => {
|
|
||||||
d3.select(e.target).transition('fill').attr('fill', d.background)
|
|
||||||
this.chartLeave()
|
|
||||||
})
|
|
||||||
|
|
||||||
function getPoints (topWidth, bottomWidth, height) {
|
|
||||||
const points = []
|
|
||||||
points.push(-topWidth / 2 + ',' + 0)
|
|
||||||
points.push(topWidth / 2 + ',' + 0)
|
|
||||||
if (bottomWidth === 0) {
|
|
||||||
points.push(0 + ',' + height)
|
|
||||||
} else {
|
|
||||||
points.push(bottomWidth / 2 + ',' + height)
|
|
||||||
points.push(-bottomWidth / 2 + ',' + height)
|
|
||||||
}
|
|
||||||
return points.join(' ')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 渲染文本标签
|
|
||||||
const texts = chart.select('.traps')
|
|
||||||
.selectAll('.foreign')
|
|
||||||
.data(funnelData)
|
|
||||||
texts.enter()
|
|
||||||
.append('foreignObject')
|
|
||||||
.attr('class', 'foreign')
|
|
||||||
.merge(texts)
|
|
||||||
.html((d) => this.formatterLabel(d, trapezoidsHeight))
|
|
||||||
.attr('x', 0)
|
|
||||||
.attr('y', (d, i) => i * (trapezoidPadding + trapezoidsHeight) + trapezoidsHeight / 2)
|
|
||||||
// 绑定交互事件
|
|
||||||
.on('mouseover', (e, d) => {
|
|
||||||
chart.select('.trap-' + d.index).transition('fill').attr('fill', this.shade(d.background, 0.2))
|
|
||||||
this.chartEnter(e, d)
|
|
||||||
})
|
|
||||||
.on('mousemove', this.chartMove)
|
|
||||||
.on('mouseleave', (e, d) => {
|
|
||||||
chart.select('.trap-' + d.index).transition('fill').attr('fill', d.background)
|
|
||||||
this.chartLeave()
|
|
||||||
})
|
|
||||||
.style('opacity', 0)
|
|
||||||
.transition('opacity').duration(animate === true ? 600 : 0)
|
|
||||||
.style('opacity', 1)
|
|
||||||
texts.exit()
|
|
||||||
.remove()
|
|
||||||
|
|
||||||
this.isInit = false
|
|
||||||
},
|
|
||||||
// 处理label
|
|
||||||
formatterLabel (data, height) {
|
|
||||||
let str = ''
|
|
||||||
let valueStr = ''
|
|
||||||
if (this.chartInfo.param.text === 'all') {
|
|
||||||
str += data.alias
|
|
||||||
valueStr = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.labels, value: data.showValue }) : data.showValue
|
|
||||||
}
|
|
||||||
if (this.chartInfo.param.text === 'value' || !this.chartInfo.param.text) {
|
|
||||||
valueStr = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.labels, value: data.showValue }) : data.showValue
|
|
||||||
}
|
|
||||||
if (this.chartInfo.param.text === 'legend') {
|
|
||||||
str += data.alias
|
|
||||||
}
|
|
||||||
if (this.chartInfo.param.text === 'none') {
|
|
||||||
str += ''
|
|
||||||
}
|
|
||||||
if (str && valueStr) {
|
|
||||||
if (height < 32) {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
return `<div class="foreign-label-wrap">
|
|
||||||
<p class="funnel-label" style="color: ${data.mapping && data.mapping.color && data.mapping.color.text};">
|
|
||||||
<span>${str}</span>
|
|
||||||
</p>
|
|
||||||
<p class="funnel-label" style="color: ${data.mapping && data.mapping.color && data.mapping.color.text};">
|
|
||||||
<i class="${data.mapping && data.mapping.icon}" style="color: ${data.mapping && data.mapping.color && data.mapping.color.icon};font-size:1em;"></i>
|
|
||||||
<span>${valueStr}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
} else if (str) {
|
|
||||||
if (height < 16) {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
return `<div class="foreign-label-wrap">
|
|
||||||
<p class="funnel-label" style="color: ${data.mapping && data.mapping.color && data.mapping.color.text};">
|
|
||||||
<i class="${data.mapping && data.mapping.icon}" style="color: ${data.mapping && data.mapping.color && data.mapping.color.icon};font-size:1em;"></i>
|
|
||||||
<span>${str}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
} else if (valueStr) {
|
|
||||||
if (height < 16) {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
return `<div class="foreign-label-wrap">
|
|
||||||
<p class="funnel-label" style="color: ${data.mapping && data.mapping.color && data.mapping.color.text};">
|
|
||||||
<i class="${data.mapping && data.mapping.icon}" style="color: ${data.mapping && data.mapping.color && data.mapping.color.icon};font-size:1em;"></i>
|
|
||||||
<span>${valueStr}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
chartEnter (e, data) {
|
|
||||||
this.tooltip.title = data.alias
|
|
||||||
this.tooltip.value = data.showValue
|
|
||||||
this.tooltip.mapping = data.mapping
|
|
||||||
this.tooltip.show = true
|
|
||||||
this.setPosition(e)
|
|
||||||
},
|
|
||||||
chartMove (e) {
|
|
||||||
this.setPosition(e)
|
|
||||||
},
|
|
||||||
chartLeave () {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Convert a hex color to an RGB object.
|
|
||||||
*
|
|
||||||
* @param {string} color
|
|
||||||
*
|
|
||||||
* @returns {{R: Number, G: number, B: number}}
|
|
||||||
*/
|
|
||||||
hexToRgb (color) {
|
|
||||||
let hex = color.slice(1)
|
|
||||||
if (hex.length === 3) {
|
|
||||||
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]
|
|
||||||
}
|
|
||||||
const f = parseInt(hex, 16)
|
|
||||||
const R = f >> 16
|
|
||||||
const G = (f >> 8) & 0x00FF
|
|
||||||
const B = f & 0x0000FF
|
|
||||||
return { R, G, B }
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Shade a color to the given percentage.
|
|
||||||
*
|
|
||||||
* @param {string} color A hex color.
|
|
||||||
* @param {number} shade The shade adjustment. Can be positive or negative.
|
|
||||||
*
|
|
||||||
* @return {string}
|
|
||||||
*/
|
|
||||||
shade (color, shade) {
|
|
||||||
const { R, G, B } = this.hexToRgb(color)
|
|
||||||
const t = shade < 0 ? 0 : 255
|
|
||||||
const p = shade < 0 ? shade * -1 : shade
|
|
||||||
|
|
||||||
const converted = 0x1000000 +
|
|
||||||
((Math.round((t - R) * p) + R) * 0x10000) +
|
|
||||||
((Math.round((t - G) * p) + G) * 0x100) +
|
|
||||||
(Math.round((t - B) * p) + B)
|
|
||||||
|
|
||||||
return `#${converted.toString(16).slice(1)}`
|
|
||||||
},
|
|
||||||
resize () {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.drawChart()
|
|
||||||
}, 50)
|
|
||||||
},
|
|
||||||
dispose () {
|
|
||||||
if (this.svg) {
|
|
||||||
this.svg.selectAll('.trap').on('mouseover', null)
|
|
||||||
this.svg.selectAll('.trap').on('mousemove', null)
|
|
||||||
this.svg.selectAll('.trap').on('mouseleave', null)
|
|
||||||
this.svg.selectAll('foreignObject').on('mouseover', null)
|
|
||||||
this.svg.selectAll('foreignObject').on('mousemove', null)
|
|
||||||
this.svg.selectAll('foreignObject').on('mouseleave', null)
|
|
||||||
this.svg.selectAll('g').remove()
|
|
||||||
this.svg = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted () {
|
|
||||||
this.colorList = initColor(20)
|
|
||||||
this.chartInfo.loaded && this.initChart(true)
|
|
||||||
},
|
|
||||||
beforeDestroy () {
|
|
||||||
this.dispose()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
<div
|
<div
|
||||||
:id="isFullscreen?('chart-gauge-screen-' + chartInfo.id + '-' + index):('chart-gauge-' + chartInfo.id + '-' + index)"
|
:id="isFullscreen?('chart-gauge-screen-' + chartInfo.id + '-' + index):('chart-gauge-' + chartInfo.id + '-' + index)"
|
||||||
class="chart-gauge-content"
|
class="chart-gauge-content"
|
||||||
|
:class="{'chart-cursor-default':!dataLink.length}"
|
||||||
></div>
|
></div>
|
||||||
<div
|
<div
|
||||||
v-if="item.height > 48 && chartInfo.param &&( chartInfo.param.text === 'legend' || chartInfo.param.text === 'all' )"
|
v-if="item.height > 48 && chartInfo.param &&( chartInfo.param.text === 'legend' || chartInfo.param.text === 'all' )"
|
||||||
@@ -16,6 +17,25 @@
|
|||||||
{{item.alias}}
|
{{item.alias}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div :id="`chart-canvas-tooltip-${chartId}`" class="chart-canvas-tooltip no-style-class" :class="{'chart-dataLink-tooltip':tooltip.dataLinkShow}" :style="{left:tooltip.x+'px',top:tooltip.y+'px'}" v-if="tooltip.show" v-clickoutside="clickout">
|
||||||
|
<div class="chart-canvas-tooltip-title tooltip-title">{{tooltip.title}}</div>
|
||||||
|
<div class="chart-canvas-tooltip-content">
|
||||||
|
<div>value</div>
|
||||||
|
<div>
|
||||||
|
<div v-if="tooltip.mapping && tooltip.mapping.icon" style="display: inline-block">
|
||||||
|
<i :class="tooltip.mapping.icon" :style="{color: tooltip.mapping.color.icon}"></i>
|
||||||
|
</div>
|
||||||
|
<div style="display: inline-block">{{tooltip.value}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- dataLink -->
|
||||||
|
<div class="chart-dataLink-list" v-if="tooltip.dataLinkShow">
|
||||||
|
<div class="chart-dataLink-item" v-for="(item,index) in dataLink" :key="index" @click="linkClick(item)">
|
||||||
|
<i class="nz-icon nz-icon-link"></i>
|
||||||
|
<span>{{item.title}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -39,11 +59,21 @@ export default {
|
|||||||
boxHeight: 0,
|
boxHeight: 0,
|
||||||
boxPadding: 5,
|
boxPadding: 5,
|
||||||
chartInstances: [],
|
chartInstances: [],
|
||||||
timer: null
|
timer: null,
|
||||||
|
tooltip: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
title: 0,
|
||||||
|
value: 0,
|
||||||
|
mapping: {},
|
||||||
|
show: false,
|
||||||
|
dataLinkShow: ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initChart () {
|
initChart () {
|
||||||
|
this.setDataLink()
|
||||||
if (this.timer) {
|
if (this.timer) {
|
||||||
clearTimeout(this.timer)
|
clearTimeout(this.timer)
|
||||||
this.timer = null
|
this.timer = null
|
||||||
@@ -157,6 +187,8 @@ export default {
|
|||||||
gaugeChartInit () {
|
gaugeChartInit () {
|
||||||
this.chartInstances.forEach(item => {
|
this.chartInstances.forEach(item => {
|
||||||
if (item) {
|
if (item) {
|
||||||
|
item.off('click')
|
||||||
|
item.off('mousedown')
|
||||||
item.dispose()
|
item.dispose()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -200,6 +232,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
option.tooltip.formatter = this.formatterFunc
|
option.tooltip.formatter = this.formatterFunc
|
||||||
|
option.tooltip.position = this.tooltipPosition
|
||||||
if (navigator.userAgent.match(/Mobi/i) ||
|
if (navigator.userAgent.match(/Mobi/i) ||
|
||||||
navigator.userAgent.match(/Android/i) ||
|
navigator.userAgent.match(/Android/i) ||
|
||||||
navigator.userAgent.match(/iPhone/i)) {
|
navigator.userAgent.match(/iPhone/i)) {
|
||||||
@@ -210,6 +243,15 @@ export default {
|
|||||||
// option.tooltip.position = this.formatterFunc
|
// option.tooltip.position = this.formatterFunc
|
||||||
option.series[0].min = item.max == item.min ? 0 : item.min
|
option.series[0].min = item.max == item.min ? 0 : item.min
|
||||||
myChart.setOption(option)
|
myChart.setOption(option)
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
myChart.on('click', this.chartClick)
|
||||||
|
myChart.on('mousedown', (params) => {
|
||||||
|
if (this.tooltip.show) {
|
||||||
|
const e = params.event.event
|
||||||
|
e.stopPropagation()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
this.chartInstances.push(myChart)
|
this.chartInstances.push(myChart)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -231,10 +273,9 @@ export default {
|
|||||||
},
|
},
|
||||||
formatterFunc: function (params, ticket, callback) {
|
formatterFunc: function (params, ticket, callback) {
|
||||||
const self = this
|
const self = this
|
||||||
return `<div>
|
return `
|
||||||
<div style="white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis; min-width: 150px; max-width: 600px; line-height: 18px; font-size: 14px;">
|
<div class="chart-canvas-tooltip-title tooltip-title">${params.data.alias}</div>
|
||||||
<div class="tooltip-title" style="max-width: 500px;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis;margin-bottom: 5px">${params.data.alias}</div>
|
<div class="chart-canvas-tooltip-content">
|
||||||
<div style="font-size:12px;display:flex;justify-content: space-between;">
|
|
||||||
<div>value</div>
|
<div>value</div>
|
||||||
<div>
|
<div>
|
||||||
<div style="display: ${params.data.mapping && params.data.mapping.icon ? 'inline-block' : 'none'}">
|
<div style="display: ${params.data.mapping && params.data.mapping.icon ? 'inline-block' : 'none'}">
|
||||||
@@ -244,9 +285,62 @@ export default {
|
|||||||
<div style="display: ${params.data.mapping && params.data.mapping.display ? 'inline-block' : 'none'}">${self.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.showValue })}</div>
|
<div style="display: ${params.data.mapping && params.data.mapping.display ? 'inline-block' : 'none'}">${self.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.showValue })}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
`
|
||||||
|
},
|
||||||
|
setPosition (e) {
|
||||||
|
const windowWidth = window.innerWidth// 窗口宽度
|
||||||
|
const windowHeight = window.innerHeight// 窗口高度
|
||||||
|
this.$nextTick(() => {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
chartClick (params) {
|
||||||
|
const option = {
|
||||||
|
tooltip: {
|
||||||
|
extraCssText: 'z-index:99999999;visibility:hidden;transition:none;'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.chartInstances.forEach(item => {
|
||||||
|
item.setOption(option)
|
||||||
|
})
|
||||||
|
this.tooltip.title = params.data.alias
|
||||||
|
this.tooltip.value = params.data.mapping && params.data.mapping.display ? this.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.showValue }) : params.data.showValue
|
||||||
|
this.tooltip.mapping = params.data.mapping
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.tooltip.dataLinkShow = true
|
||||||
|
const e = params.event.event
|
||||||
|
this.setPosition(e)
|
||||||
|
},
|
||||||
|
clickout () {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.show = false
|
||||||
|
this.tooltip.dataLinkShow = false
|
||||||
|
const option = {
|
||||||
|
tooltip: {
|
||||||
|
extraCssText: 'z-index:99999999;visibility:visible;'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.chartInstances.forEach(item => {
|
||||||
|
item.setOption(option)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
@@ -257,6 +351,8 @@ export default {
|
|||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
this.chartInstances.forEach(item => {
|
this.chartInstances.forEach(item => {
|
||||||
if (item && item.dispose) {
|
if (item && item.dispose) {
|
||||||
|
item.off('click')
|
||||||
|
item.off('mousedown')
|
||||||
item.dispose()
|
item.dispose()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<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 :id="`chart-canvas-tooltip-${chartId}`" class="chart-canvas-tooltip no-style-class" :class="{'chart-dataLink-tooltip':tooltip.dataLinkShow}" :style="{left:tooltip.x+'px',top:tooltip.y+'px'}" v-if="tooltip.show" v-clickoutside="clickout">
|
||||||
<div class="chart-canvas-tooltip-title tooltip-title">
|
<div class="chart-canvas-tooltip-title tooltip-title">
|
||||||
{{tooltip.title}}
|
{{tooltip.title}}
|
||||||
</div>
|
</div>
|
||||||
@@ -14,6 +14,13 @@
|
|||||||
<div style="display: inline-block">{{tooltip.value}}</div>
|
<div style="display: inline-block">{{tooltip.value}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- dataLink -->
|
||||||
|
<div class="chart-dataLink-list" v-if="tooltip.dataLinkShow">
|
||||||
|
<div class="chart-dataLink-item" v-for="(item,index) in dataLink" :key="index" @click="linkClick(item)">
|
||||||
|
<i class="nz-icon nz-icon-link"></i>
|
||||||
|
<span>{{item.title}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -43,7 +50,8 @@ export default {
|
|||||||
title: 0,
|
title: 0,
|
||||||
value: 0,
|
value: 0,
|
||||||
mapping: {},
|
mapping: {},
|
||||||
show: false
|
show: false,
|
||||||
|
dataLinkShow: ''
|
||||||
},
|
},
|
||||||
svg: null,
|
svg: null,
|
||||||
spaceBetweenHexa: 3,
|
spaceBetweenHexa: 3,
|
||||||
@@ -53,6 +61,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
hexbin,
|
hexbin,
|
||||||
initChart () {
|
initChart () {
|
||||||
|
this.setDataLink()
|
||||||
if (this.timer) {
|
if (this.timer) {
|
||||||
clearTimeout(this.timer)
|
clearTimeout(this.timer)
|
||||||
this.timer = null
|
this.timer = null
|
||||||
@@ -181,29 +190,33 @@ export default {
|
|||||||
hexa.attr('fill', color) // Paints hexagon
|
hexa.attr('fill', color) // Paints hexagon
|
||||||
g.on('mouseenter', self.hexagonOver.bind(self, point))
|
g.on('mouseenter', self.hexagonOver.bind(self, point))
|
||||||
g.on('mouseleave', self.hexagonOut.bind(self, point))
|
g.on('mouseleave', self.hexagonOut.bind(self, point))
|
||||||
|
g.on('click', self.chartClick.bind(self, point))
|
||||||
self.drawText(this.svg, vals, point, color, hexaRadius, g) // 文本
|
self.drawText(this.svg, vals, point, color, hexaRadius, g) // 文本
|
||||||
data[i].fcolor = color
|
data[i].fcolor = color
|
||||||
}
|
}
|
||||||
return this.svg.node()
|
return this.svg.node()
|
||||||
},
|
},
|
||||||
hexagonOver (that, e) { // 移入六边形
|
hexagonOver (that, e) { // 移入六边形
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
this.tooltip.title = that.alias
|
this.tooltip.title = that.alias
|
||||||
this.tooltip.value = that.showValue
|
this.tooltip.value = that.mapping && that.mapping.display ? this.handleDisplay(that.mapping.display, { ...that.metrics, legend: that.alias, value: that.showValue }) : that.showValue
|
||||||
this.tooltip.mapping = that.mapping
|
this.tooltip.mapping = that.mapping
|
||||||
this.tooltip.show = true
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
},
|
},
|
||||||
hexagonMove (e) { // 六边形内移动
|
hexagonMove (e) { // 六边形内移动
|
||||||
if (this.tooltip.show) {
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
}
|
|
||||||
},
|
},
|
||||||
hexagonOut (that) {
|
hexagonOut () {
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
this.tooltip.show = false
|
this.tooltip.show = false
|
||||||
},
|
},
|
||||||
setPosition (e) {
|
setPosition (e) {
|
||||||
const windowWidth = window.innerWidth// 窗口宽度
|
const windowWidth = window.innerWidth// 窗口宽度
|
||||||
const windowHeight = window.innerHeight// 窗口高度
|
const windowHeight = window.innerHeight// 窗口高度
|
||||||
|
this.$nextTick(() => {
|
||||||
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
||||||
if (box) {
|
if (box) {
|
||||||
const boxWidth = box.offsetWidth
|
const boxWidth = box.offsetWidth
|
||||||
@@ -222,6 +235,7 @@ export default {
|
|||||||
this.tooltip.y = e.pageY + 15
|
this.tooltip.y = e.pageY + 15
|
||||||
this.tooltip.x = e.pageX + 15
|
this.tooltip.x = e.pageX + 15
|
||||||
}
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
formatStr (d) {
|
formatStr (d) {
|
||||||
const self = this
|
const self = this
|
||||||
@@ -238,6 +252,7 @@ export default {
|
|||||||
.attr('stroke-linejoin', 'round')
|
.attr('stroke-linejoin', 'round')
|
||||||
.attr('stroke-width', 1)
|
.attr('stroke-width', 1)
|
||||||
.attr('transform', 'translate(' + x + ',' + y + ')')
|
.attr('transform', 'translate(' + x + ',' + y + ')')
|
||||||
|
.style('cursor', this.dataLink.length ? 'pointer' : 'default')
|
||||||
return hexagon
|
return hexagon
|
||||||
},
|
},
|
||||||
drawText (svg, vals, point, color, hexbinRadius, group) {
|
drawText (svg, vals, point, color, hexbinRadius, group) {
|
||||||
@@ -273,6 +288,7 @@ export default {
|
|||||||
.attr('alignment-baseline', 'central')
|
.attr('alignment-baseline', 'central')
|
||||||
.style('font-size', fontSize)
|
.style('font-size', fontSize)
|
||||||
.style('fill', textColor)
|
.style('fill', textColor)
|
||||||
|
.style('pointer-events', 'none')
|
||||||
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>`)
|
||||||
@@ -295,6 +311,7 @@ export default {
|
|||||||
.attr('alignment-baseline', 'central')
|
.attr('alignment-baseline', 'central')
|
||||||
.style('font-size', fontSize)
|
.style('font-size', fontSize)
|
||||||
.style('fill', textColor)
|
.style('fill', textColor)
|
||||||
|
.style('pointer-events', 'none')
|
||||||
const scrollDiv2 = fObj2.append('xhtml:div')
|
const scrollDiv2 = fObj2.append('xhtml:div')
|
||||||
scrollDiv2
|
scrollDiv2
|
||||||
.html(
|
.html(
|
||||||
@@ -315,6 +332,7 @@ export default {
|
|||||||
.attr('alignment-baseline', 'central')
|
.attr('alignment-baseline', 'central')
|
||||||
.style('font-size', fontSize)
|
.style('font-size', fontSize)
|
||||||
.style('fill', textColor)
|
.style('fill', textColor)
|
||||||
|
.style('pointer-events', 'none')
|
||||||
const scrollDiv = fObj.append('xhtml:div')
|
const scrollDiv = fObj.append('xhtml:div')
|
||||||
scrollDiv
|
scrollDiv
|
||||||
.html(
|
.html(
|
||||||
@@ -342,6 +360,7 @@ export default {
|
|||||||
.attr('alignment-baseline', 'central')
|
.attr('alignment-baseline', 'central')
|
||||||
.style('font-size', fontSize)
|
.style('font-size', fontSize)
|
||||||
.style('fill', textColor)
|
.style('fill', textColor)
|
||||||
|
.style('pointer-events', 'none')
|
||||||
const scrollDiv = fObj.append('xhtml:div')
|
const scrollDiv = fObj.append('xhtml:div')
|
||||||
scrollDiv
|
scrollDiv
|
||||||
.html(
|
.html(
|
||||||
@@ -415,6 +434,7 @@ export default {
|
|||||||
this.svg.on('mousemove', null)
|
this.svg.on('mousemove', null)
|
||||||
this.svg.selectAll('g').on('mouseenter', null)
|
this.svg.selectAll('g').on('mouseenter', null)
|
||||||
this.svg.selectAll('g').on('mouseleave', null)
|
this.svg.selectAll('g').on('mouseleave', null)
|
||||||
|
this.svg.selectAll('g').on('click', null)
|
||||||
this.svg.remove()
|
this.svg.remove()
|
||||||
this.svg = null
|
this.svg = null
|
||||||
}
|
}
|
||||||
@@ -431,6 +451,22 @@ export default {
|
|||||||
|
|
||||||
})
|
})
|
||||||
}, 50)
|
}, 50)
|
||||||
|
},
|
||||||
|
chartClick (data, e) {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.title = data.alias
|
||||||
|
this.tooltip.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.metrics, legend: data.alias, value: data.showValue }) : data.showValue
|
||||||
|
this.tooltip.mapping = data.mapping
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.tooltip.dataLinkShow = true
|
||||||
|
this.setPosition(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clickout () {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.show = false
|
||||||
|
this.tooltip.dataLinkShow = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
hasLegend () {
|
hasLegend () {
|
||||||
try {
|
try {
|
||||||
return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1
|
return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1 && this.chartInfo.param.enable.legend
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
ref="rank-chart-box"
|
ref="rank-chart-box"
|
||||||
class="nz-chart__component"
|
class="nz-chart__component"
|
||||||
>
|
>
|
||||||
<div :id="`chart-canvas-${chartId}`" class="chart__canvas" style="overflow-y:auto;">
|
<div :id="`chart-canvas-${chartId}`" class="chart__canvas" :class="{'chart-cursor-default':!dataLink.length}" style="overflow-y:auto;">
|
||||||
<svg :id="`rank-svg-${chartId}`" width="100%" style="vertical-align: top;"></svg>
|
<svg :id="`rank-svg-${chartId}`" width="100%" style="vertical-align: top;"></svg>
|
||||||
</div>
|
</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 :id="`chart-canvas-tooltip-${chartId}`" class="chart-canvas-tooltip no-style-class" :class="{'chart-dataLink-tooltip':tooltip.dataLinkShow}" :style="{left:tooltip.x+'px',top:tooltip.y+'px'}" v-if="tooltip.show" v-clickoutside="clickout">
|
||||||
<div class="chart-canvas-tooltip-title tooltip-title">
|
<div class="chart-canvas-tooltip-title tooltip-title">
|
||||||
{{tooltip.title}}
|
{{tooltip.title}}
|
||||||
</div>
|
</div>
|
||||||
@@ -19,11 +20,17 @@
|
|||||||
<div style="display: inline-block">{{tooltip.value}}</div>
|
<div style="display: inline-block">{{tooltip.value}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="chart-canvas-tooltip-content">
|
<div class="chart-canvas-tooltip-content">
|
||||||
<div>rank</div>
|
<div>rank</div>
|
||||||
<div>{{tooltip.rank+1}}</div>
|
<div>{{tooltip.rank+1}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- dataLink -->
|
||||||
|
<div class="chart-dataLink-list" v-if="tooltip.dataLinkShow">
|
||||||
|
<div class="chart-dataLink-item" v-for="(item,index) in dataLink" :key="index" @click="linkClick(item)">
|
||||||
|
<i class="nz-icon nz-icon-link"></i>
|
||||||
|
<span>{{item.title}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -63,13 +70,15 @@ export default {
|
|||||||
value: 0,
|
value: 0,
|
||||||
mapping: {},
|
mapping: {},
|
||||||
rank: 0,
|
rank: 0,
|
||||||
show: false
|
show: false,
|
||||||
|
dataLinkShow: ''
|
||||||
},
|
},
|
||||||
svg: null
|
svg: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initChart () {
|
initChart () {
|
||||||
|
this.setDataLink()
|
||||||
this.legends = []
|
this.legends = []
|
||||||
this.initRankData(this.chartInfo, this.chartData)
|
this.initRankData(this.chartInfo, this.chartData)
|
||||||
this.isNoData = !this.rankData.length
|
this.isNoData = !this.rankData.length
|
||||||
@@ -171,6 +180,7 @@ export default {
|
|||||||
.on('mouseenter', this.rankEnter)
|
.on('mouseenter', this.rankEnter)
|
||||||
.on('mousemove', this.rankMove)
|
.on('mousemove', this.rankMove)
|
||||||
.on('mouseleave', this.rankLeave)
|
.on('mouseleave', this.rankLeave)
|
||||||
|
.on('click', this.chartClick)
|
||||||
bars.exit().remove()
|
bars.exit().remove()
|
||||||
|
|
||||||
// 文本标签
|
// 文本标签
|
||||||
@@ -183,6 +193,7 @@ export default {
|
|||||||
.on('mouseenter', this.rankEnter)
|
.on('mouseenter', this.rankEnter)
|
||||||
.on('mousemove', this.rankMove)
|
.on('mousemove', this.rankMove)
|
||||||
.on('mouseleave', this.rankLeave)
|
.on('mouseleave', this.rankLeave)
|
||||||
|
.on('click', this.chartClick)
|
||||||
.html((d) => {
|
.html((d) => {
|
||||||
return this.rankFormatterLabel(d)
|
return this.rankFormatterLabel(d)
|
||||||
})
|
})
|
||||||
@@ -243,26 +254,28 @@ export default {
|
|||||||
`
|
`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
rankEnter (e, data) { // 移入
|
rankEnter (e, data) { // 移入
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
this.tooltip.title = data.alias
|
this.tooltip.title = data.alias
|
||||||
this.tooltip.value = data.showValue
|
this.tooltip.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.labels, value: data.showValue }) : data.showValue
|
||||||
this.tooltip.mapping = data.mapping
|
this.tooltip.mapping = data.mapping
|
||||||
this.tooltip.rank = data.rank
|
this.tooltip.rank = data.rank
|
||||||
this.tooltip.show = true
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
},
|
},
|
||||||
rankMove (e) { // 移动
|
rankMove (e) { // 移动
|
||||||
if (this.tooltip.show) {
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
}
|
|
||||||
},
|
},
|
||||||
rankLeave () { // 移出
|
rankLeave () { // 移出
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
this.tooltip.show = false
|
this.tooltip.show = false
|
||||||
},
|
},
|
||||||
setPosition (e) {
|
setPosition (e) {
|
||||||
const windowWidth = window.innerWidth// 窗口宽度
|
const windowWidth = window.innerWidth// 窗口宽度
|
||||||
const windowHeight = window.innerHeight// 窗口高度
|
const windowHeight = window.innerHeight// 窗口高度
|
||||||
|
this.$nextTick(() => {
|
||||||
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
||||||
if (box) {
|
if (box) {
|
||||||
const boxWidth = box.offsetWidth
|
const boxWidth = box.offsetWidth
|
||||||
@@ -281,6 +294,7 @@ export default {
|
|||||||
this.tooltip.y = e.pageY + 15
|
this.tooltip.y = e.pageY + 15
|
||||||
this.tooltip.x = e.pageX + 15
|
this.tooltip.x = e.pageX + 15
|
||||||
}
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
resize () {
|
resize () {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -292,14 +306,31 @@ export default {
|
|||||||
this.svg.selectAll('rect').on('mouseenter', null)
|
this.svg.selectAll('rect').on('mouseenter', null)
|
||||||
this.svg.selectAll('rect').on('mousemove', null)
|
this.svg.selectAll('rect').on('mousemove', null)
|
||||||
this.svg.selectAll('rect').on('mouseleave', null)
|
this.svg.selectAll('rect').on('mouseleave', null)
|
||||||
|
this.svg.selectAll('rect').on('click', null)
|
||||||
this.svg.selectAll('foreignObject').on('mouseenter', null)
|
this.svg.selectAll('foreignObject').on('mouseenter', null)
|
||||||
this.svg.selectAll('foreignObject').on('mousemove', null)
|
this.svg.selectAll('foreignObject').on('mousemove', null)
|
||||||
this.svg.selectAll('foreignObject').on('mouseleave', null)
|
this.svg.selectAll('foreignObject').on('mouseleave', null)
|
||||||
|
this.svg.selectAll('foreignObject').on('click', null)
|
||||||
this.svg.selectAll('g').remove()
|
this.svg.selectAll('g').remove()
|
||||||
this.svg = null
|
this.svg = null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
chartClick (e, data) {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.title = data.alias
|
||||||
|
this.tooltip.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.labels, value: data.showValue }) : data.showValue
|
||||||
|
this.tooltip.mapping = data.mapping
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.tooltip.dataLinkShow = true
|
||||||
|
this.setPosition(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clickout () {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.show = false
|
||||||
|
this.tooltip.dataLinkShow = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
this.colorList = initColor(20)
|
this.colorList = initColor(20)
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
ref="rose-chart-box"
|
ref="rose-chart-box"
|
||||||
class="nz-chart__component"
|
class="nz-chart__component"
|
||||||
>
|
>
|
||||||
<div :id="`chart-canvas-${chartId}`" class="chart__canvas" style="overflow: hidden;"></div>
|
<div :id="`chart-canvas-${chartId}`" class="chart__canvas" :class="{'chart-cursor-default':!dataLink.length}" style="overflow: hidden;"></div>
|
||||||
|
|
||||||
<chart-legend
|
<chart-legend
|
||||||
v-if="hasLegend"
|
v-if="hasLegend"
|
||||||
:chart-data="chartData"
|
:chart-data="chartData"
|
||||||
@@ -13,7 +14,8 @@
|
|||||||
:is-fullscreen="isFullscreen"
|
:is-fullscreen="isFullscreen"
|
||||||
@clickLegendD3="clickLegendD3"
|
@clickLegendD3="clickLegendD3"
|
||||||
></chart-legend>
|
></chart-legend>
|
||||||
<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 :id="`chart-canvas-tooltip-${chartId}`" class="chart-canvas-tooltip no-style-class" :class="{'chart-dataLink-tooltip':tooltip.dataLinkShow}" :style="{left:tooltip.x+'px',top:tooltip.y+'px'}" v-if="tooltip.show" v-clickoutside="clickout">
|
||||||
<div class="chart-canvas-tooltip-title tooltip-title">
|
<div class="chart-canvas-tooltip-title tooltip-title">
|
||||||
{{tooltip.title}}
|
{{tooltip.title}}
|
||||||
</div>
|
</div>
|
||||||
@@ -30,6 +32,13 @@
|
|||||||
<div>percent</div>
|
<div>percent</div>
|
||||||
<div>{{tooltip.percent}}%</div>
|
<div>{{tooltip.percent}}%</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- dataLink -->
|
||||||
|
<div class="chart-dataLink-list" v-if="tooltip.dataLinkShow">
|
||||||
|
<div class="chart-dataLink-item" v-for="(item,index) in dataLink" :key="index" @click="linkClick(item)">
|
||||||
|
<i class="nz-icon nz-icon-link"></i>
|
||||||
|
<span>{{item.title}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -59,7 +68,7 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
hasLegend () {
|
hasLegend () {
|
||||||
try {
|
try {
|
||||||
return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1
|
return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1 && this.chartInfo.param.enable.legend
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -93,13 +102,15 @@ export default {
|
|||||||
value: 0,
|
value: 0,
|
||||||
percent: 0,
|
percent: 0,
|
||||||
mapping: {},
|
mapping: {},
|
||||||
show: false
|
show: false,
|
||||||
|
dataLinkShow: false
|
||||||
},
|
},
|
||||||
svg: null
|
svg: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initChart (animate) {
|
initChart (animate) {
|
||||||
|
this.setDataLink()
|
||||||
this.legends = []
|
this.legends = []
|
||||||
this.initRoseData(this.chartInfo, this.chartData)
|
this.initRoseData(this.chartInfo, this.chartData)
|
||||||
this.selectData = this.$loadsh.cloneDeep(this.roseData)
|
this.selectData = this.$loadsh.cloneDeep(this.roseData)
|
||||||
@@ -238,6 +249,7 @@ export default {
|
|||||||
.on('mouseenter', this.roseEnter)
|
.on('mouseenter', this.roseEnter)
|
||||||
.on('mousemove', this.roseMove)
|
.on('mousemove', this.roseMove)
|
||||||
.on('mouseleave', this.roseLeave)
|
.on('mouseleave', this.roseLeave)
|
||||||
|
.on('click', this.chartClick)
|
||||||
.transition().duration(animate === true ? 600 : 0)
|
.transition().duration(animate === true ? 600 : 0)
|
||||||
.attrTween('d', function (d) {
|
.attrTween('d', function (d) {
|
||||||
const i = d3.interpolate({ startAngle: 0, endAngle: 0 }, d)
|
const i = d3.interpolate({ startAngle: 0, endAngle: 0 }, d)
|
||||||
@@ -262,6 +274,7 @@ export default {
|
|||||||
.on('mouseenter', this.roseEnter)
|
.on('mouseenter', this.roseEnter)
|
||||||
.on('mousemove', this.roseMove)
|
.on('mousemove', this.roseMove)
|
||||||
.on('mouseleave', this.roseLeave)
|
.on('mouseleave', this.roseLeave)
|
||||||
|
.on('click', this.chartClick)
|
||||||
.style('opacity', 0)
|
.style('opacity', 0)
|
||||||
.html((d) => {
|
.html((d) => {
|
||||||
return d.endAngle - d.startAngle > 0.25 ? this.formatterLabel(d) : ''
|
return d.endAngle - d.startAngle > 0.25 ? this.formatterLabel(d) : ''
|
||||||
@@ -321,25 +334,27 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
roseEnter (e, node) { // 移入气泡
|
roseEnter (e, node) { // 移入气泡
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
this.tooltip.title = node.data.alias
|
this.tooltip.title = node.data.alias
|
||||||
this.tooltip.value = node.data.showValue
|
this.tooltip.value = node.data.mapping && node.data.mapping.display ? this.handleDisplay(node.data.mapping.display, { ...node.data.labels, value: node.data.showValue }) : node.data.showValue
|
||||||
this.tooltip.percent = node.percent
|
this.tooltip.percent = node.percent
|
||||||
this.tooltip.mapping = node.data.mapping
|
this.tooltip.mapping = node.data.mapping
|
||||||
this.tooltip.show = true
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
},
|
},
|
||||||
roseMove (e) { // 气泡内移动
|
roseMove (e) { // 气泡内移动
|
||||||
if (this.tooltip.show) {
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
this.tooltip.show = true
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
}
|
|
||||||
},
|
},
|
||||||
roseLeave () { // 移出气泡
|
roseLeave () { // 移出气泡
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
this.tooltip.show = false
|
this.tooltip.show = false
|
||||||
},
|
},
|
||||||
setPosition (e) {
|
setPosition (e) {
|
||||||
const windowWidth = window.innerWidth// 窗口宽度
|
const windowWidth = window.innerWidth// 窗口宽度
|
||||||
const windowHeight = window.innerHeight// 窗口高度
|
const windowHeight = window.innerHeight// 窗口高度
|
||||||
|
this.$nextTick(() => {
|
||||||
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
||||||
if (box) {
|
if (box) {
|
||||||
const boxWidth = box.offsetWidth
|
const boxWidth = box.offsetWidth
|
||||||
@@ -358,6 +373,7 @@ export default {
|
|||||||
this.tooltip.y = e.pageY + 15
|
this.tooltip.y = e.pageY + 15
|
||||||
this.tooltip.x = e.pageX + 15
|
this.tooltip.x = e.pageX + 15
|
||||||
}
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
clickLegendD3 (isGrey) {
|
clickLegendD3 (isGrey) {
|
||||||
const data = this.roseData.filter((item, i) => !isGrey[i])
|
const data = this.roseData.filter((item, i) => !isGrey[i])
|
||||||
@@ -376,14 +392,32 @@ export default {
|
|||||||
this.svg.selectAll('path').on('mouseenter', null)
|
this.svg.selectAll('path').on('mouseenter', null)
|
||||||
this.svg.selectAll('path').on('mousemove', null)
|
this.svg.selectAll('path').on('mousemove', null)
|
||||||
this.svg.selectAll('path').on('mouseleave', null)
|
this.svg.selectAll('path').on('mouseleave', null)
|
||||||
|
this.svg.selectAll('path').on('click', null)
|
||||||
this.svg.selectAll('foreignObject').on('mouseover', null)
|
this.svg.selectAll('foreignObject').on('mouseover', null)
|
||||||
this.svg.selectAll('foreignObject').on('mouseout', null)
|
this.svg.selectAll('foreignObject').on('mouseout', null)
|
||||||
this.svg.selectAll('foreignObject').on('mouseenter', null)
|
this.svg.selectAll('foreignObject').on('mouseenter', null)
|
||||||
this.svg.selectAll('foreignObject').on('mousemove', null)
|
this.svg.selectAll('foreignObject').on('mousemove', null)
|
||||||
this.svg.selectAll('foreignObject').on('mouseleave', null)
|
this.svg.selectAll('foreignObject').on('mouseleave', null)
|
||||||
|
this.svg.selectAll('foreignObject').on('click', null)
|
||||||
this.svg.remove()
|
this.svg.remove()
|
||||||
this.svg = null
|
this.svg = null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
chartClick (e, data) {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.title = data.data.alias
|
||||||
|
this.tooltip.value = data.data.mapping && data.data.mapping.display ? this.handleDisplay(data.data.mapping.display, { ...data.data.labels, value: data.data.showValue }) : data.data.showValue
|
||||||
|
this.tooltip.mapping = data.data.mapping
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.tooltip.dataLinkShow = true
|
||||||
|
this.setPosition(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clickout () {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.show = false
|
||||||
|
this.tooltip.dataLinkShow = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|||||||
@@ -5,10 +5,11 @@
|
|||||||
@mouseleave="mouseLeaveChart"
|
@mouseleave="mouseLeaveChart"
|
||||||
index="300"
|
index="300"
|
||||||
>
|
>
|
||||||
<div :id="`chart-canvas-${chartId}`" class="chart__canvas">
|
<div :id="`chart-canvas-${chartId}`" class="chart__canvas" :class="{'chart-cursor-default':!dataLink.length}">
|
||||||
<svg :id="`sankey-svg-${chartId}`" width="100%" height="100%"></svg>
|
<svg :id="`sankey-svg-${chartId}`" width="100%" height="100%"></svg>
|
||||||
</div>
|
</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 :id="`chart-canvas-tooltip-${chartId}`" class="chart-canvas-tooltip no-style-class" :class="{'chart-dataLink-tooltip':tooltip.dataLinkShow}" :style="{left:tooltip.x+'px',top:tooltip.y+'px'}" v-if="tooltip.show" v-clickoutside="clickout">
|
||||||
<div class="chart-canvas-tooltip-title tooltip-title">
|
<div class="chart-canvas-tooltip-title tooltip-title">
|
||||||
{{tooltip.title}}
|
{{tooltip.title}}
|
||||||
</div>
|
</div>
|
||||||
@@ -21,6 +22,13 @@
|
|||||||
<div style="display: inline-block">{{tooltip.value}}</div>
|
<div style="display: inline-block">{{tooltip.value}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- dataLink -->
|
||||||
|
<div class="chart-dataLink-list" v-if="tooltip.dataLinkShow">
|
||||||
|
<div class="chart-dataLink-item" v-for="(item,index) in dataLink" :key="index" @click="linkClick(item)">
|
||||||
|
<i class="nz-icon nz-icon-link"></i>
|
||||||
|
<span>{{item.title}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -58,13 +66,15 @@ export default {
|
|||||||
title: 0,
|
title: 0,
|
||||||
value: 0,
|
value: 0,
|
||||||
mapping: {},
|
mapping: {},
|
||||||
show: false
|
show: false,
|
||||||
|
dataLinkShow: ''
|
||||||
},
|
},
|
||||||
svg: null
|
svg: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initChart () {
|
initChart () {
|
||||||
|
this.setDataLink()
|
||||||
this.linksData = this.initsankeyData(this.chartInfo, this.chartData) // 生成links
|
this.linksData = this.initsankeyData(this.chartInfo, this.chartData) // 生成links
|
||||||
this.isNoData = !this.linksData.length
|
this.isNoData = !this.linksData.length
|
||||||
this.$emit('chartIsNoData', this.isNoData)
|
this.$emit('chartIsNoData', this.isNoData)
|
||||||
@@ -73,8 +83,8 @@ export default {
|
|||||||
}
|
}
|
||||||
// 根据link获取node
|
// 根据link获取node
|
||||||
this.linksData.forEach(item => {
|
this.linksData.forEach(item => {
|
||||||
this.nodesData.push({ node: item.source })
|
this.nodesData.push({ node: item.source, labels: item.labels })
|
||||||
this.nodesData.push({ node: item.target })
|
this.nodesData.push({ node: item.target, labels: item.labels })
|
||||||
})
|
})
|
||||||
// 去重相同的node
|
// 去重相同的node
|
||||||
for (let i = 0; i < this.nodesData.length; i++) {
|
for (let i = 0; i < this.nodesData.length; i++) {
|
||||||
@@ -98,13 +108,12 @@ export default {
|
|||||||
const decimals = this.chartInfo.param.decimals || 2
|
const decimals = this.chartInfo.param.decimals || 2
|
||||||
this.isNoData = true
|
this.isNoData = true
|
||||||
originalDatas.forEach((originalData) => {
|
originalDatas.forEach((originalData) => {
|
||||||
originalData.forEach((data, dataIndex) => {
|
originalData.forEach((data) => {
|
||||||
const value = getMetricTypeValue(data.values, chartInfo.param.statistics)
|
const value = getMetricTypeValue(data.values, chartInfo.param.statistics)
|
||||||
const obj = {
|
const obj = {
|
||||||
value: value,
|
value: value,
|
||||||
realValue: value,
|
realValue: value,
|
||||||
labels: data.metric,
|
labels: data.metric
|
||||||
dataIndex: dataIndex
|
|
||||||
}
|
}
|
||||||
if (data.metric[chartInfo.param.sourceLabel] && data.metric[chartInfo.param.targetLabel]) {
|
if (data.metric[chartInfo.param.sourceLabel] && data.metric[chartInfo.param.targetLabel]) {
|
||||||
obj.source = data.metric[chartInfo.param.sourceLabel]
|
obj.source = data.metric[chartInfo.param.sourceLabel]
|
||||||
@@ -163,7 +172,7 @@ export default {
|
|||||||
let allZero = false
|
let allZero = false
|
||||||
if (linksData.every(item => item.value == 0)) {
|
if (linksData.every(item => item.value == 0)) {
|
||||||
linksData.forEach(item => {
|
linksData.forEach(item => {
|
||||||
item.value = 100 // 目的是显示图表 与值大小无关
|
item.value = 100
|
||||||
})
|
})
|
||||||
allZero = true
|
allZero = true
|
||||||
}
|
}
|
||||||
@@ -255,13 +264,14 @@ export default {
|
|||||||
|
|
||||||
// 划过连线
|
// 划过连线
|
||||||
chart.selectAll('path')
|
chart.selectAll('path')
|
||||||
.on('mouseover', (e, d) => {
|
.on('mouseenter', (e, d) => {
|
||||||
chart.selectAll('.node, path').style('fill-opacity', '0.1').style('stroke-opacity', '0.1')
|
chart.selectAll('.node, path').style('fill-opacity', '0.1').style('stroke-opacity', '0.1')
|
||||||
chart.selectAll('.node').selectAll('foreignObject').style('opacity', '0.1')
|
chart.selectAll('.node').selectAll('foreignObject').style('opacity', '0.1')
|
||||||
const hoverNodes = d3.select(e.target).style('stroke-opacity', '0.8').attr('linkNodes').split(' ')
|
const hoverNodes = d3.select(e.target).style('stroke-opacity', '0.8').attr('linkNodes').split(' ')
|
||||||
hoverNodes.forEach((index) => {
|
hoverNodes.forEach((index) => {
|
||||||
chart.selectAll('[index=' + index + ']').style('fill-opacity', '1').selectAll('foreignObject').style('opacity', '1')
|
chart.selectAll('[index=' + index + ']').style('fill-opacity', '1').selectAll('foreignObject').style('opacity', '1')
|
||||||
})
|
})
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
// 显示悬浮框
|
// 显示悬浮框
|
||||||
this.tooltip.title = d.source.node + ' ——> ' + d.target.node
|
this.tooltip.title = d.source.node + ' ——> ' + d.target.node
|
||||||
this.tooltip.value = d.showValue
|
this.tooltip.value = d.showValue
|
||||||
@@ -270,20 +280,22 @@ export default {
|
|||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
})
|
})
|
||||||
.on('mousemove', (e) => {
|
.on('mousemove', (e) => {
|
||||||
if (this.tooltip.show) {
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.on('mouseleave', () => {
|
.on('mouseleave', () => {
|
||||||
chart.selectAll('.node, path').style('fill-opacity', '1').style('stroke-opacity', '0.5')
|
chart.selectAll('.node, path').style('fill-opacity', '1').style('stroke-opacity', '0.5')
|
||||||
chart.selectAll('.node').selectAll('foreignObject').style('opacity', '1')
|
chart.selectAll('.node').selectAll('foreignObject').style('opacity', '1')
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
// 隐藏悬浮框
|
// 隐藏悬浮框
|
||||||
this.tooltip.show = false
|
this.tooltip.show = false
|
||||||
})
|
})
|
||||||
|
.on('click', this.chartClick)
|
||||||
|
|
||||||
// 划过节点
|
// 划过节点
|
||||||
chart.selectAll('.node')
|
chart.selectAll('.node')
|
||||||
.on('mouseover', (e, d) => {
|
.on('mouseenter', (e, d) => {
|
||||||
chart.selectAll('.node, path').style('fill-opacity', '0.1').style('stroke-opacity', '0.1')
|
chart.selectAll('.node, path').style('fill-opacity', '0.1').style('stroke-opacity', '0.1')
|
||||||
chart.selectAll('.node').selectAll('foreignObject').style('opacity', '0.1')
|
chart.selectAll('.node').selectAll('foreignObject').style('opacity', '0.1')
|
||||||
chart.selectAll('[linkNodes~=' + 'i-' + d.index + ']')
|
chart.selectAll('[linkNodes~=' + 'i-' + d.index + ']')
|
||||||
@@ -291,29 +303,32 @@ export default {
|
|||||||
.style('stroke-opacity', '0.8')
|
.style('stroke-opacity', '0.8')
|
||||||
.selectAll('foreignObject')
|
.selectAll('foreignObject')
|
||||||
.style('opacity', '1')
|
.style('opacity', '1')
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
// 显示悬浮框
|
// 显示悬浮框
|
||||||
this.tooltip.title = d.node
|
this.tooltip.title = d.node
|
||||||
this.tooltip.value = d.showValue
|
this.tooltip.value = d.mapping && d.mapping.display ? this.handleDisplay(d.mapping.display, { ...d.labels, value: d.showValue }) : d.showValue
|
||||||
this.tooltip.mapping = d.mapping
|
this.tooltip.mapping = d.mapping
|
||||||
this.tooltip.show = true
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
})
|
})
|
||||||
.on('mousemove', (e) => {
|
.on('mousemove', (e) => {
|
||||||
if (this.tooltip.show) {
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.on('mouseleave', () => {
|
.on('mouseleave', () => {
|
||||||
chart.selectAll('.node, path').style('fill-opacity', '1').style('stroke-opacity', '0.5')
|
chart.selectAll('.node, path').style('fill-opacity', '1').style('stroke-opacity', '0.5')
|
||||||
chart.selectAll('.node').selectAll('foreignObject').style('opacity', '1')
|
chart.selectAll('.node').selectAll('foreignObject').style('opacity', '1')
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
// 隐藏悬浮框
|
// 隐藏悬浮框
|
||||||
this.tooltip.show = false
|
this.tooltip.show = false
|
||||||
})
|
})
|
||||||
|
.on('click', this.chartClick)
|
||||||
},
|
},
|
||||||
|
|
||||||
setPosition (e) {
|
setPosition (e) {
|
||||||
const windowWidth = window.innerWidth// 窗口宽度
|
const windowWidth = window.innerWidth// 窗口宽度
|
||||||
const windowHeight = window.innerHeight// 窗口高度
|
const windowHeight = window.innerHeight// 窗口高度
|
||||||
|
this.$nextTick(() => {
|
||||||
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
||||||
if (box) {
|
if (box) {
|
||||||
const boxWidth = box.offsetWidth
|
const boxWidth = box.offsetWidth
|
||||||
@@ -332,18 +347,18 @@ export default {
|
|||||||
this.tooltip.y = e.pageY + 15
|
this.tooltip.y = e.pageY + 15
|
||||||
this.tooltip.x = e.pageX + 15
|
this.tooltip.x = e.pageX + 15
|
||||||
}
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理label
|
// 处理label
|
||||||
sankeyFormatterLabel (data) {
|
sankeyFormatterLabel (data) {
|
||||||
let str = ''
|
let str = ''
|
||||||
let valueStr = ''
|
let valueStr = ''
|
||||||
if (this.chartInfo.param.text === 'all') {
|
if (this.chartInfo.param.text === 'all') {
|
||||||
str += data.node
|
str += data.node
|
||||||
valueStr = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { value: data.showValue }) : data.showValue
|
valueStr = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.labels, value: data.showValue }) : data.showValue
|
||||||
}
|
}
|
||||||
if (this.chartInfo.param.text === 'value' || !this.chartInfo.param.text) {
|
if (this.chartInfo.param.text === 'value' || !this.chartInfo.param.text) {
|
||||||
valueStr = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { value: data.showValue }) : data.showValue
|
valueStr = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.labels, value: data.showValue }) : data.showValue
|
||||||
}
|
}
|
||||||
if (this.chartInfo.param.text === 'legend') {
|
if (this.chartInfo.param.text === 'legend') {
|
||||||
str += data.node
|
str += data.node
|
||||||
@@ -390,15 +405,33 @@ export default {
|
|||||||
},
|
},
|
||||||
dispose () {
|
dispose () {
|
||||||
if (this.svg) {
|
if (this.svg) {
|
||||||
this.svg.selectAll('path').on('mouseover', null)
|
this.svg.selectAll('path').on('mouseenter', null)
|
||||||
this.svg.selectAll('path').on('mousemove', null)
|
this.svg.selectAll('path').on('mousemove', null)
|
||||||
this.svg.selectAll('path').on('mouseleave', null)
|
this.svg.selectAll('path').on('mouseleave', null)
|
||||||
this.svg.selectAll('.node').on('mouseover', null)
|
this.svg.selectAll('path').on('click', null)
|
||||||
|
this.svg.selectAll('.node').on('mouseenter', null)
|
||||||
this.svg.selectAll('.node').on('mousemove', null)
|
this.svg.selectAll('.node').on('mousemove', null)
|
||||||
this.svg.selectAll('.node').on('mouseleave', null)
|
this.svg.selectAll('.node').on('mouseleave', null)
|
||||||
|
this.svg.selectAll('.node').on('click', null)
|
||||||
this.svg.selectAll('g').remove()
|
this.svg.selectAll('g').remove()
|
||||||
this.svg = null
|
this.svg = null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
chartClick (e, data) {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.title = data.node ? data.node : data.source.node + ' ——> ' + data.target.node
|
||||||
|
this.tooltip.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.labels, value: data.showValue }) : data.showValue
|
||||||
|
this.tooltip.mapping = data.mapping
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.tooltip.dataLinkShow = true
|
||||||
|
this.setPosition(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clickout () {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.show = false
|
||||||
|
this.tooltip.dataLinkShow = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="chart-stat" ref="chart-stat-box" @mousemove="statMouseMove">
|
<div class="chart-stat" ref="chart-stat-box">
|
||||||
<div
|
<div
|
||||||
class="chart-stat-item"
|
class="chart-stat-item"
|
||||||
v-for="(item,index) in statData"
|
v-for="(item,index) in statData"
|
||||||
:key="index"
|
:key="index"
|
||||||
@mouseenter="statMouseEnter(item,$event)"
|
@mouseenter="statMouseEnter(item,$event)"
|
||||||
|
@mousemove="statMouseMove"
|
||||||
@mouseleave="statMouseleave(item)"
|
@mouseleave="statMouseleave(item)"
|
||||||
:class="statData.length===1 ?'only-stat' : ''"
|
@click="chartClick($event,item)"
|
||||||
|
:class="{'only-stat':statData.length===1,'chart-cursor-pointer':dataLink.length}"
|
||||||
:style="{
|
:style="{
|
||||||
background:item.mapping ? item.mapping.color.bac : (statData.length===1 ? '' : colorList[index]),
|
background:item.mapping ? item.mapping.color.bac : (statData.length===1 ? '' : colorList[index]),
|
||||||
height:item.height+'px',
|
height:item.height+'px',
|
||||||
@@ -74,10 +76,8 @@
|
|||||||
<!-- sparkline -->
|
<!-- sparkline -->
|
||||||
<div class="sparkline" :id="`chart-canvas-${chartId}-${index}`" v-if="chartInfo.param.sparklineMode && chartInfo.param.sparklineMode !== 'none'"></div>
|
<div class="sparkline" :id="`chart-canvas-${chartId}-${index}`" v-if="chartInfo.param.sparklineMode && chartInfo.param.sparklineMode !== 'none'"></div>
|
||||||
</div>
|
</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 :id="`chart-canvas-tooltip-${chartId}`" class="chart-canvas-tooltip no-style-class" :class="{'chart-dataLink-tooltip':tooltip.dataLinkShow}" :style="{left:tooltip.x+'px',top:tooltip.y+'px'}" v-if="tooltip.show" v-clickoutside="clickout">
|
||||||
<div class="chart-canvas-tooltip-title tooltip-title">
|
<div class="chart-canvas-tooltip-title tooltip-title">{{tooltip.title}}</div>
|
||||||
{{tooltip.title}}
|
|
||||||
</div>
|
|
||||||
<div class="chart-canvas-tooltip-content">
|
<div class="chart-canvas-tooltip-content">
|
||||||
<div>value</div>
|
<div>value</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -87,6 +87,13 @@
|
|||||||
<div style="display: inline-block">{{tooltip.value}}</div>
|
<div style="display: inline-block">{{tooltip.value}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- dataLink -->
|
||||||
|
<div class="chart-dataLink-list" v-if="tooltip.dataLinkShow">
|
||||||
|
<div class="chart-dataLink-item" v-for="(item,index) in dataLink" :key="index" @click="linkClick(item)">
|
||||||
|
<i class="nz-icon nz-icon-link"></i>
|
||||||
|
<span>{{item.title}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span class="temp-dom--12" ref="temp-dom"></span>
|
<span class="temp-dom--12" ref="temp-dom"></span>
|
||||||
</div>
|
</div>
|
||||||
@@ -120,7 +127,8 @@ export default {
|
|||||||
title: 0,
|
title: 0,
|
||||||
value: 0,
|
value: 0,
|
||||||
mapping: {},
|
mapping: {},
|
||||||
show: false
|
show: false,
|
||||||
|
dataLinkShow: ''
|
||||||
},
|
},
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
customFontSize: '',
|
customFontSize: '',
|
||||||
@@ -133,6 +141,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
randomcolor,
|
randomcolor,
|
||||||
initChart () {
|
initChart () {
|
||||||
|
this.setDataLink()
|
||||||
this.initStatData(this.chartInfo, this.chartData).then(() => {
|
this.initStatData(this.chartInfo, this.chartData).then(() => {
|
||||||
if (this.isNoData) {
|
if (this.isNoData) {
|
||||||
return
|
return
|
||||||
@@ -422,36 +431,27 @@ export default {
|
|||||||
})
|
})
|
||||||
}, 100)
|
}, 100)
|
||||||
},
|
},
|
||||||
statMouseMove (e) {
|
statMouseEnter (data, e) {
|
||||||
const windowWidth = window.innerWidth// 窗口宽度
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
const windowHeight = window.innerHeight// 窗口高度
|
this.tooltip.title = data.legend
|
||||||
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
this.tooltip.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.label, value: data.showValue }) : data.showValue
|
||||||
if (box) {
|
this.tooltip.mapping = data.mapping
|
||||||
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
|
|
||||||
}
|
|
||||||
},
|
|
||||||
statMouseEnter (that, e) {
|
|
||||||
this.tooltip.title = this.$loadsh.cloneDeep(that.legend)
|
|
||||||
this.tooltip.value = this.$loadsh.cloneDeep(that.showValue)
|
|
||||||
this.tooltip.mapping = this.$loadsh.cloneDeep(that.mapping)
|
|
||||||
this.tooltip.show = true
|
this.tooltip.show = true
|
||||||
this.$nextTick(() => {
|
this.setPosition(e)
|
||||||
|
},
|
||||||
|
statMouseMove (e) {
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.setPosition(e)
|
||||||
|
},
|
||||||
|
statMouseleave () {
|
||||||
|
if (this.tooltip.dataLinkShow) { return }
|
||||||
|
this.tooltip.show = false
|
||||||
|
},
|
||||||
|
setPosition (e) {
|
||||||
const windowWidth = window.innerWidth// 窗口宽度
|
const windowWidth = window.innerWidth// 窗口宽度
|
||||||
const windowHeight = window.innerHeight// 窗口高度
|
const windowHeight = window.innerHeight// 窗口高度
|
||||||
|
this.$nextTick(() => {
|
||||||
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
||||||
if (box) {
|
if (box) {
|
||||||
const boxWidth = box.offsetWidth
|
const boxWidth = box.offsetWidth
|
||||||
@@ -472,9 +472,6 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
statMouseleave () {
|
|
||||||
this.tooltip.show = false
|
|
||||||
},
|
|
||||||
setFontSize (item) {
|
setFontSize (item) {
|
||||||
let fontSize = ''
|
let fontSize = ''
|
||||||
|
|
||||||
@@ -513,6 +510,22 @@ export default {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
return this.chartInfo.param.comparison && this.chartInfo.param.comparison !== 'none' && item.height > minHeight && item.width > minWidth
|
return this.chartInfo.param.comparison && this.chartInfo.param.comparison !== 'none' && item.height > minHeight && item.width > minWidth
|
||||||
|
},
|
||||||
|
chartClick (e, data) {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.title = data.legend
|
||||||
|
this.tooltip.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.label, value: data.showValue }) : data.showValue
|
||||||
|
this.tooltip.mapping = data.mapping
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.tooltip.dataLinkShow = true
|
||||||
|
this.setPosition(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clickout () {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.show = false
|
||||||
|
this.tooltip.dataLinkShow = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="nz-table-list" style="height: 100%;padding: 0 10px 10px 10px;box-sizing: border-box">
|
<div class="nz-table-list tabel-chart" style="height: 100%;padding: 0 10px 10px 10px;box-sizing: border-box">
|
||||||
<el-table
|
<el-table
|
||||||
ref="dataTable"
|
ref="dataTable"
|
||||||
class="chart-table"
|
class="chart-table"
|
||||||
@@ -23,24 +23,42 @@
|
|||||||
<span class="data-column__span">{{col.title}}</span>
|
<span class="data-column__span">{{col.title}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template slot-scope="scope" :column="col">
|
<template slot-scope="scope" :column="col">
|
||||||
<div v-if="scope.row.valueMapping && scope.row.valueMapping[col.title + 'mapping']" :style="{
|
<div
|
||||||
|
v-if="scope.row.valueMapping && scope.row.valueMapping[col.title + 'mapping']"
|
||||||
|
:style="{
|
||||||
background: scope.row.valueMapping[col.title + 'mapping'].color.bac,
|
background: scope.row.valueMapping[col.title + 'mapping'].color.bac,
|
||||||
color: scope.row.valueMapping[col.title + 'mapping'].color.text + ' !important',
|
color: scope.row.valueMapping[col.title + 'mapping'].color.text + ' !important',
|
||||||
clear: 'both',
|
clear: 'both',
|
||||||
}"
|
}"
|
||||||
class="value-mapping-table"
|
class="value-mapping-table"
|
||||||
|
:class="{'chart-cursor-pointer':dataLink.length}"
|
||||||
|
@click="chartClick($event,{title:col.title,value:showValueMapping(scope.row,col.title, col)})"
|
||||||
>
|
>
|
||||||
<template v-if="scope.row.valueMapping && scope.row.valueMapping[col.title + 'mapping']">
|
<template v-if="scope.row.valueMapping && scope.row.valueMapping[col.title + 'mapping']">
|
||||||
<i :class="scope.row.valueMapping[col.title + 'mapping'].icon" :style="{color: scope.row.valueMapping[col.title + 'mapping'].color.icon}"></i>
|
<i :class="scope.row.valueMapping[col.title + 'mapping'].icon" :style="{color: scope.row.valueMapping[col.title + 'mapping'].color.icon}"></i>
|
||||||
</template>
|
</template>
|
||||||
{{showValueMapping(scope.row,col.title, col)}}
|
{{showValueMapping(scope.row,col.title, col)}}
|
||||||
</div>
|
</div>
|
||||||
<div class="value-mapping-table" v-else>
|
<div v-else class="value-mapping-table" :class="{'chart-cursor-pointer':dataLink.length}" @click="chartClick($event,{title:col.title,value:scope.row.display[col.title + 'display'].display})">
|
||||||
{{scope.row.display[col.title + 'display'].display}}
|
{{scope.row.display[col.title + 'display'].display}}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
<div :id="`chart-canvas-tooltip-${chartId}`" class="chart-canvas-tooltip no-style-class" :class="{'chart-dataLink-tooltip':tooltip.dataLinkShow}" :style="{left:tooltip.x+'px',top:tooltip.y+'px'}" v-if="tooltip.show" v-clickoutside="clickout">
|
||||||
|
<div class="chart-canvas-tooltip-title tooltip-title">{{tooltip.title}}</div>
|
||||||
|
<div class="chart-canvas-tooltip-content">
|
||||||
|
<div>value</div>
|
||||||
|
<div>{{tooltip.value}}</div>
|
||||||
|
</div>
|
||||||
|
<!-- dataLink -->
|
||||||
|
<div class="chart-dataLink-list" v-if="tooltip.dataLinkShow">
|
||||||
|
<div class="chart-dataLink-item" v-for="(item,index) in dataLink" :key="index" @click="linkClick(item)">
|
||||||
|
<i class="nz-icon nz-icon-link"></i>
|
||||||
|
<span>{{item.title}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -59,11 +77,21 @@ export default {
|
|||||||
oldTableData: [],
|
oldTableData: [],
|
||||||
columns: [],
|
columns: [],
|
||||||
valueMapping: {},
|
valueMapping: {},
|
||||||
tableTimer: null
|
tableTimer: null,
|
||||||
|
tooltip: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
title: 0,
|
||||||
|
value: 0,
|
||||||
|
mapping: {},
|
||||||
|
show: false,
|
||||||
|
dataLinkShow: ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initChart () {
|
initChart () {
|
||||||
|
this.setDataLink()
|
||||||
if (this.tableTimer) {
|
if (this.tableTimer) {
|
||||||
clearTimeout(this.tableTimer)
|
clearTimeout(this.tableTimer)
|
||||||
this.tableTimer = null
|
this.tableTimer = null
|
||||||
@@ -355,6 +383,45 @@ export default {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
setPosition (e) {
|
||||||
|
const windowWidth = window.innerWidth// 窗口宽度
|
||||||
|
const windowHeight = window.innerHeight// 窗口高度
|
||||||
|
this.$nextTick(() => {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
chartClick (e, data) {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.title = data.title
|
||||||
|
this.tooltip.value = data.value
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.tooltip.dataLinkShow = true
|
||||||
|
this.setPosition(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clickout () {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.show = false
|
||||||
|
this.tooltip.dataLinkShow = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
v-my-loading="chartLoading"
|
v-my-loading="chartLoading"
|
||||||
>
|
>
|
||||||
<div class="chart__canvas" style="position:relative">
|
<div class="chart__canvas" style="position:relative">
|
||||||
<div :id="`chart-canvas-${chartId}`"></div>
|
<div :id="`chart-canvas-${chartId}`" :class="{'chart-cursor-default':!dataLink.length}"></div>
|
||||||
<!-- 右y轴name -->
|
<!-- 右y轴name -->
|
||||||
<p class="rightYAxis-name" v-if="hasRightYAxis">
|
<p class="rightYAxis-name" v-if="hasRightYAxis">
|
||||||
<span>{{chartInfo.param.rightYAxis.label}}</span>
|
<span>{{chartInfo.param.rightYAxis.label}}</span>
|
||||||
@@ -20,6 +20,16 @@
|
|||||||
:series="series"
|
:series="series"
|
||||||
:is-fullscreen="isFullscreen"
|
:is-fullscreen="isFullscreen"
|
||||||
></chart-legend>
|
></chart-legend>
|
||||||
|
<div :id="`chart-canvas-tooltip-${chartId}`" class="chart-canvas-tooltip no-style-class" :class="{'chart-dataLink-tooltip':tooltip.dataLinkShow}" :style="{left:tooltip.x+'px',top:tooltip.y+'px'}" v-if="tooltip.show" v-clickoutside="clickout">
|
||||||
|
<div v-html="tooltip.tooltipHtml"></div>
|
||||||
|
<!-- dataLink -->
|
||||||
|
<div class="chart-dataLink-list" v-if="tooltip.dataLinkShow">
|
||||||
|
<div class="chart-dataLink-item" v-for="(item,index) in dataLink" :key="index" @click="linkClick(item)">
|
||||||
|
<i class="nz-icon nz-icon-link"></i>
|
||||||
|
<span>{{item.title}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -54,7 +64,18 @@ export default {
|
|||||||
stackTotalColorRight: null,
|
stackTotalColorRight: null,
|
||||||
isStack: false,
|
isStack: false,
|
||||||
hasRightYAxis: false,
|
hasRightYAxis: false,
|
||||||
chartLoading: false
|
chartLoading: false,
|
||||||
|
tooltip: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
title: 0,
|
||||||
|
value: 0,
|
||||||
|
mapping: {},
|
||||||
|
show: false,
|
||||||
|
dataLinkShow: '',
|
||||||
|
tooltipHtml: ''
|
||||||
|
},
|
||||||
|
tooltipHtml: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -116,6 +137,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initChart (chartOptions = this.chartOption) {
|
initChart (chartOptions = this.chartOption) {
|
||||||
|
this.setDataLink()
|
||||||
try {
|
try {
|
||||||
this.isStack = this.chartInfo.param.stack
|
this.isStack = this.chartInfo.param.stack
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
@@ -202,6 +224,15 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.isInit && this.dataLink.length) {
|
||||||
|
myChart.on('click', this.chartClick)
|
||||||
|
myChart.on('mousedown', (params) => {
|
||||||
|
if (this.tooltip.show) {
|
||||||
|
const e = params.event.event
|
||||||
|
e.stopPropagation()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
this.chartLoading = false
|
this.chartLoading = false
|
||||||
this.isInit = false
|
this.isInit = false
|
||||||
}, 200)
|
}, 200)
|
||||||
@@ -479,6 +510,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
str += '</div>'
|
str += '</div>'
|
||||||
|
self.tooltipHtml = str
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -528,6 +560,66 @@ export default {
|
|||||||
if (option.yAxis[1].min && option.yAxis[1].max) {
|
if (option.yAxis[1].min && option.yAxis[1].max) {
|
||||||
this.hasRightYAxis = true
|
this.hasRightYAxis = true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
setPosition (e) {
|
||||||
|
const windowWidth = window.innerWidth// 窗口宽度
|
||||||
|
const windowHeight = window.innerHeight// 窗口高度
|
||||||
|
this.$nextTick(() => {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
chartClick (params) {
|
||||||
|
// 先取消多表联动 防止其它图表setOption
|
||||||
|
if (this.isConnect !== 'none') {
|
||||||
|
echarts.disconnect('timeSeriesGroup')
|
||||||
|
}
|
||||||
|
echarts.disconnect('timeSeriesGroup')
|
||||||
|
const option = {
|
||||||
|
tooltip: {
|
||||||
|
extraCssText: 'z-index:99999999;visibility:hidden;transition:none;'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getChart(this.chartId).setOption(option)
|
||||||
|
getChart(this.chartId).dispatchAction({
|
||||||
|
type: 'hideTip'
|
||||||
|
})
|
||||||
|
this.tooltip.tooltipHtml = this.tooltipHtml
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.tooltip.dataLinkShow = true
|
||||||
|
const e = params.event.event
|
||||||
|
this.setPosition(e)
|
||||||
|
if (this.isConnect !== 'none') {
|
||||||
|
echarts.connect('timeSeriesGroup')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clickout () {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.show = false
|
||||||
|
this.tooltip.dataLinkShow = false
|
||||||
|
const option = {
|
||||||
|
tooltip: {
|
||||||
|
extraCssText: 'z-index:99999999;visibility:visible;'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getChart(this.chartId).setOption(option)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
@@ -537,9 +629,6 @@ 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 () {
|
|
||||||
getChart(this.chartId) && getChart(this.chartId).getZr().off('mousemove')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
class="nz-chart__component nz-chart__component--time-series" @mouseenter="mouseEnterChart"
|
class="nz-chart__component nz-chart__component--time-series" @mouseenter="mouseEnterChart"
|
||||||
@mouseleave="mouseLeaveChart"
|
@mouseleave="mouseLeaveChart"
|
||||||
>
|
>
|
||||||
<div :id="`chart-canvas-${chartId}`" class="chart__canvas"></div>
|
<div :id="`chart-canvas-${chartId}`" class="chart__canvas" :class="{'chart-cursor-default':!dataLink.length}"></div>
|
||||||
<chart-legend
|
<chart-legend
|
||||||
v-if="hasLegend"
|
v-if="hasLegend"
|
||||||
:chart-data="chartData"
|
:chart-data="chartData"
|
||||||
@@ -14,6 +14,26 @@
|
|||||||
:series="series"
|
:series="series"
|
||||||
:is-fullscreen="isFullscreen"
|
:is-fullscreen="isFullscreen"
|
||||||
></chart-legend>
|
></chart-legend>
|
||||||
|
|
||||||
|
<div :id="`chart-canvas-tooltip-${chartId}`" class="chart-canvas-tooltip no-style-class" :class="{'chart-dataLink-tooltip':tooltip.dataLinkShow}" :style="{left:tooltip.x+'px',top:tooltip.y+'px'}" v-if="tooltip.show" v-clickoutside="clickout">
|
||||||
|
<div class="chart-canvas-tooltip-title tooltip-title">{{tooltip.title}}</div>
|
||||||
|
<div class="chart-canvas-tooltip-content">
|
||||||
|
<div>value</div>
|
||||||
|
<div>
|
||||||
|
<div v-if="tooltip.mapping && tooltip.mapping.icon" style="display: inline-block">
|
||||||
|
<i :class="tooltip.mapping.icon" :style="{color: tooltip.mapping.color.icon}"></i>
|
||||||
|
</div>
|
||||||
|
<div style="display: inline-block">{{tooltip.value}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- dataLink -->
|
||||||
|
<div class="chart-dataLink-list" v-if="tooltip.dataLinkShow">
|
||||||
|
<div class="chart-dataLink-item" v-for="(item,index) in dataLink" :key="index" @click="linkClick(item)">
|
||||||
|
<i class="nz-icon nz-icon-link"></i>
|
||||||
|
<span>{{item.title}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -44,7 +64,7 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
hasLegend () {
|
hasLegend () {
|
||||||
try {
|
try {
|
||||||
return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1
|
return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1 && this.chartInfo.param.enable.legend
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -74,11 +94,21 @@ export default {
|
|||||||
active: '#53a3cb',
|
active: '#53a3cb',
|
||||||
inactive: '#7e7e7e'
|
inactive: '#7e7e7e'
|
||||||
},
|
},
|
||||||
chartId: ''
|
chartId: '',
|
||||||
|
tooltip: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
title: 0,
|
||||||
|
value: 0,
|
||||||
|
mapping: {},
|
||||||
|
show: false,
|
||||||
|
dataLinkShow: ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initChart (chartOption = this.chartOption) {
|
initChart (chartOption = this.chartOption) {
|
||||||
|
this.setDataLink()
|
||||||
this.legends = []
|
this.legends = []
|
||||||
this.series = chartOption.series = this.initTreeMapData(this.chartInfo, chartOption.series[0], this.chartData) // 生成series和legends
|
this.series = chartOption.series = this.initTreeMapData(this.chartInfo, chartOption.series[0], this.chartData) // 生成series和legends
|
||||||
chartOption.tooltip.formatter = this.formatterFunc
|
chartOption.tooltip.formatter = this.formatterFunc
|
||||||
@@ -98,6 +128,15 @@ export default {
|
|||||||
}
|
}
|
||||||
myChart.setOption(chartOption)
|
myChart.setOption(chartOption)
|
||||||
this.isInit && setChart(this.chartId, myChart) // 缓存;不使用vue的data是为避免整个chart被监听导致卡顿
|
this.isInit && setChart(this.chartId, myChart) // 缓存;不使用vue的data是为避免整个chart被监听导致卡顿
|
||||||
|
if (this.isInit && this.dataLink.length) {
|
||||||
|
myChart.on('click', this.chartClick)
|
||||||
|
myChart.on('mousedown', (params) => {
|
||||||
|
if (this.tooltip.show && params.dataIndex) {
|
||||||
|
const e = params.event.event
|
||||||
|
e.stopPropagation()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
this.isInit = false
|
this.isInit = false
|
||||||
}, 200)
|
}, 200)
|
||||||
},
|
},
|
||||||
@@ -148,28 +187,74 @@ export default {
|
|||||||
},
|
},
|
||||||
formatterFunc (params, ticket, callback) {
|
formatterFunc (params, ticket, callback) {
|
||||||
const self = this
|
const self = this
|
||||||
if (!params.data) {
|
if (!params.data || !params.dataIndex) {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
return `
|
return `
|
||||||
<div>
|
<div class="chart-canvas-tooltip-title tooltip-title">${params.data.alias}</div>
|
||||||
<div style="white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis; min-width: 150px; max-width: 600px; line-height: 18px; font-size: 14px;">
|
<div class="chart-canvas-tooltip-content">
|
||||||
<div class="tooltip-title" style="max-width: 500px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom: 5px">${params.data.alias}</div>
|
|
||||||
<div style="font-size:12px;display:flex;justify-content: space-between;">
|
|
||||||
<div>value</div>
|
<div>value</div>
|
||||||
<div>
|
<div>
|
||||||
<div style="display: ${params.data.mapping && params.data.mapping.icon ? 'inline-block' : 'none'}">
|
<div style="display: ${params.data.mapping && params.data.mapping.icon ? 'inline-block' : 'none'}">
|
||||||
<i class="${params.data.mapping && params.data.mapping.icon}" style="color: ${params.data.mapping && params.data.mapping.color && params.data.mapping.color.icon}"></i>
|
<i class="${params.data.mapping && params.data.mapping.icon}" style="color: ${params.data.mapping && params.data.mapping.color && params.data.mapping.color.icon}"></i>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: ${(params.data.mapping && params.data.mapping.display) ? 'none' : 'inline-block'}">${params.data.showValue}</div>
|
<div style="display: ${params.data.mapping && params.data.mapping.display ? 'none' : 'inline-block'}">${params.data.showValue}</div>
|
||||||
<div style="display: ${(params.data.mapping && params.data.mapping.display) ? 'inline-block' : 'none'}">
|
<div style="display: ${params.data.mapping && params.data.mapping.display ? 'inline-block' : 'none'}">${self.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.showValue })}</div>
|
||||||
${(params.data.mapping && params.data.mapping.display) ? self.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.showValue }) : ''}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
},
|
||||||
|
setPosition (e) {
|
||||||
|
const windowWidth = window.innerWidth// 窗口宽度
|
||||||
|
const windowHeight = window.innerHeight// 窗口高度
|
||||||
|
this.$nextTick(() => {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
chartClick (params) {
|
||||||
|
if (!params.dataIndex) { return } // 点击父节点(空白间隙)
|
||||||
|
const option = {
|
||||||
|
tooltip: {
|
||||||
|
extraCssText: 'z-index:99999999;visibility:hidden;transition:none;'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getChart(this.chartId).setOption(option)
|
||||||
|
this.tooltip.title = params.data.alias
|
||||||
|
this.tooltip.value = params.data.mapping && params.data.mapping.display ? this.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.showValue }) : params.data.showValue
|
||||||
|
this.tooltip.mapping = params.data.mapping
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.tooltip.dataLinkShow = true
|
||||||
|
const e = params.event.event
|
||||||
|
this.setPosition(e)
|
||||||
|
},
|
||||||
|
clickout () {
|
||||||
|
if (this.dataLink.length) {
|
||||||
|
this.tooltip.show = false
|
||||||
|
this.tooltip.dataLinkShow = false
|
||||||
|
const option = {
|
||||||
|
tooltip: {
|
||||||
|
extraCssText: 'z-index:99999999;visibility:visible;'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getChart(this.chartId).setOption(option)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const chartTreemapOption = {
|
|||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name: 'Disk Usage',
|
name: 'Parent',
|
||||||
type: 'treemap',
|
type: 'treemap',
|
||||||
visibleMin: 40,
|
visibleMin: 40,
|
||||||
childrenVisibleMin: 40,
|
childrenVisibleMin: 40,
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ export default {
|
|||||||
str = str.replace(reg, item.checked.map(label => label.replace(/\\"/g, '"').replace(/\\'/g, "'")).join('+'))
|
str = str.replace(reg, item.checked.map(label => label.replace(/\\"/g, '"').replace(/\\'/g, "'")).join('+'))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.chartInfo.varName = str
|
this.chartInfo.modifiedName = str
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- 全屏查看 -->
|
<!-- 全屏查看 -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
class="nz-dialog chart-fullscreen"
|
class="nz-dialog chart-fullscreen no-transform-dialog"
|
||||||
v-if="fullscreen.visible"
|
v-if="fullscreen.visible"
|
||||||
:visible.sync="fullscreen.visible"
|
:visible.sync="fullscreen.visible"
|
||||||
:show-close="false"
|
:show-close="false"
|
||||||
@@ -374,11 +374,11 @@ export default {
|
|||||||
let i = 0
|
let i = 0
|
||||||
this.scrollTopTimer = setTimeout(() => {
|
this.scrollTopTimer = setTimeout(() => {
|
||||||
this.copyDataList.forEach(item => {
|
this.copyDataList.forEach(item => {
|
||||||
if (this.$refs['chart' + item.id] && this.$refs['chart' + item.id][0] && this.$refs['chart' + item.id][0].$refs.chart && this.$refs['chart' + item.id][0].$refs.chart.$refs['chart' + item.id]) {
|
// if (this.$refs['chart' + item.id] && this.$refs['chart' + item.id][0] && this.$refs['chart' + item.id][0].$refs.chart && this.$refs['chart' + item.id][0].$refs.chart.$refs['chart' + item.id]) {
|
||||||
if (this.$refs['chart' + item.id][0].$refs.chart.$refs['chart' + item.id].tooltip && this.$refs['chart' + item.id][0].$refs.chart.$refs['chart' + item.id].tooltip.show) {
|
// if (this.$refs['chart' + item.id][0].$refs.chart.$refs['chart' + item.id].tooltip && this.$refs['chart' + item.id][0].$refs.chart.$refs['chart' + item.id].tooltip.show) {
|
||||||
this.$refs['chart' + item.id][0].$refs.chart.$refs['chart' + item.id].tooltip.show = false
|
// this.$refs['chart' + item.id][0].$refs.chart.$refs['chart' + item.id].tooltip.show = false
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if (!this.$refs['grid-item' + item.id] || !this.$refs['grid-item' + item.id][0]) {
|
if (!this.$refs['grid-item' + item.id] || !this.$refs['grid-item' + item.id][0]) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ export default {
|
|||||||
},
|
},
|
||||||
chartId: '',
|
chartId: '',
|
||||||
isNoData: true,
|
isNoData: true,
|
||||||
series: []
|
series: [],
|
||||||
|
dataLink: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
@@ -280,18 +281,6 @@ export default {
|
|||||||
return aliasExpression
|
return aliasExpression
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
globalVariablesReplace (expression) {
|
|
||||||
let str = expression
|
|
||||||
if (str) {
|
|
||||||
this.globalVariables.forEach(item => {
|
|
||||||
const reg = new RegExp('{{\\' + item.name + '}}', 'g')
|
|
||||||
if (item.value != null) {
|
|
||||||
str = str.replace(reg, item.value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return str
|
|
||||||
},
|
|
||||||
selectMapping (value, valueMapping, show) {
|
selectMapping (value, valueMapping, show) {
|
||||||
let mapping = ''
|
let mapping = ''
|
||||||
if (show && valueMapping) {
|
if (show && valueMapping) {
|
||||||
@@ -340,12 +329,11 @@ export default {
|
|||||||
const pointX = point[0]
|
const pointX = point[0]
|
||||||
const pointY = point[1]
|
const pointY = point[1]
|
||||||
// 外层div大小
|
// 外层div大小
|
||||||
const viewWidth = size.viewSize[0]
|
// const viewWidth = size.viewSize[0]
|
||||||
// const viewHeight = size.viewSize[1]
|
// const viewHeight = size.viewSize[1]
|
||||||
// 提示框大小
|
// 提示框大小
|
||||||
const boxWidth = size.contentSize[0]
|
const boxWidth = size.contentSize[0]
|
||||||
const boxHeight = size.contentSize[1]
|
const boxHeight = size.contentSize[1]
|
||||||
if (!this.isFullscreen) { // 本地显示
|
|
||||||
const chartDom = document.getElementById('chart-local-' + this.chartInfo.id)
|
const chartDom = document.getElementById('chart-local-' + this.chartInfo.id)
|
||||||
if (chartDom) {
|
if (chartDom) {
|
||||||
if (windowMouse.x < (windowWidth / 2)) { // 说明鼠标在左边放不下提示框
|
if (windowMouse.x < (windowWidth / 2)) { // 说明鼠标在左边放不下提示框
|
||||||
@@ -360,19 +348,6 @@ export default {
|
|||||||
}
|
}
|
||||||
return [x, y]
|
return [x, y]
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (pointX < (viewWidth / 2)) { // 说明鼠标在左边放不下提示框
|
|
||||||
x = pointX + 10
|
|
||||||
} else {
|
|
||||||
x = pointX - boxWidth
|
|
||||||
}
|
|
||||||
if (windowMouse.y + 50 + boxHeight < windowHeight) { // 说明鼠标上面放不下提示框
|
|
||||||
y = pointY + 15
|
|
||||||
} else {
|
|
||||||
y = pointY - boxHeight - 10
|
|
||||||
}
|
|
||||||
return [x, y]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
mouseLeaveChart () {
|
mouseLeaveChart () {
|
||||||
const myChart = getChart(this.chartId)
|
const myChart = getChart(this.chartId)
|
||||||
@@ -453,6 +428,38 @@ export default {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
getChart(this.chartId) && getChart(this.chartId).resize()
|
getChart(this.chartId) && getChart(this.chartId).resize()
|
||||||
}, 100)
|
}, 100)
|
||||||
|
},
|
||||||
|
// 全局变量替换
|
||||||
|
globalVariablesReplace (expression) {
|
||||||
|
let str = expression
|
||||||
|
if (str) {
|
||||||
|
this.globalVariables.forEach(item => {
|
||||||
|
const reg = new RegExp('{{\\' + item.name + '}}', 'g')
|
||||||
|
if (item.value != null) {
|
||||||
|
str = str.replace(reg, item.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return str
|
||||||
|
},
|
||||||
|
// 设置dataLink
|
||||||
|
setDataLink () {
|
||||||
|
if (this.chartInfo.param.dataLink && this.chartInfo.param.dataLink.length) {
|
||||||
|
this.dataLink = this.chartInfo.param.dataLink.map(item => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
url: this.globalVariablesReplace(item.url)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
linkClick (data) {
|
||||||
|
if (data.openIn === 'newTab') {
|
||||||
|
window.open(data.url)
|
||||||
|
} else {
|
||||||
|
window.location.href = data.url
|
||||||
|
}
|
||||||
|
this.clickout()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -482,6 +489,11 @@ export default {
|
|||||||
this.chartId = `${this.chartInfo.id}${this.isFullscreen ? '-fullscreen' : ''}`
|
this.chartId = `${this.chartInfo.id}${this.isFullscreen ? '-fullscreen' : ''}`
|
||||||
},
|
},
|
||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
|
try {
|
||||||
|
getChart(this.chartId) && getChart(this.chartId).off('click')
|
||||||
|
getChart(this.chartId) && getChart(this.chartId).off('mousedown')
|
||||||
|
getChart(this.chartId) && getChart(this.chartId).getZr().off('mousemove')
|
||||||
|
} catch (error) {}
|
||||||
getChart(this.chartId) && setChart(this.chartId, null)
|
getChart(this.chartId) && setChart(this.chartId, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export default {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
case '$G.chart.name': {
|
case '$G.chart.name': {
|
||||||
item.value = this.chartInfo.varName
|
item.value = this.chartInfo.modifiedName
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case '$G.interval.ms': {
|
case '$G.interval.ms': {
|
||||||
|
|||||||
@@ -1093,6 +1093,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Data link-->
|
<!--Data link-->
|
||||||
|
<template v-if="chartConfig.type!=='log'">
|
||||||
<div class="form__sub-title" >
|
<div class="form__sub-title" >
|
||||||
<span>{{$t('dashboard.dashboard.chartForm.dataLink')}}</span>
|
<span>{{$t('dashboard.dashboard.chartForm.dataLink')}}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -1176,6 +1177,7 @@
|
|||||||
<div @click="addDataLink" class="thresholds-add">
|
<div @click="addDataLink" class="thresholds-add">
|
||||||
{{$t('overall.addDataLink')}}
|
{{$t('overall.addDataLink')}}
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -240,7 +240,6 @@ export default {
|
|||||||
}
|
}
|
||||||
if (params.type === 'group') {
|
if (params.type === 'group') {
|
||||||
params.height = 1
|
params.height = 1
|
||||||
delete params.param.dataLink
|
|
||||||
}
|
}
|
||||||
if (!params.groupId) {
|
if (!params.groupId) {
|
||||||
params.groupId = 0
|
params.groupId = 0
|
||||||
@@ -396,7 +395,7 @@ export default {
|
|||||||
varValue: '',
|
varValue: '',
|
||||||
result: 'show'
|
result: 'show'
|
||||||
},
|
},
|
||||||
dataLink: this.editChart.param.dataLink
|
dataLink: []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -423,7 +422,7 @@ export default {
|
|||||||
varValue: '',
|
varValue: '',
|
||||||
result: 'show'
|
result: 'show'
|
||||||
},
|
},
|
||||||
dataLink: this.editChart.param.dataLink
|
dataLink: []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -465,7 +464,7 @@ export default {
|
|||||||
varValue: '',
|
varValue: '',
|
||||||
result: 'show'
|
result: 'show'
|
||||||
},
|
},
|
||||||
dataLink: this.editChart.param.dataLink
|
dataLink: []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete this.editChart.elements
|
delete this.editChart.elements
|
||||||
@@ -490,8 +489,7 @@ export default {
|
|||||||
operator: 'equal',
|
operator: 'equal',
|
||||||
varValue: '',
|
varValue: '',
|
||||||
result: 'show'
|
result: 'show'
|
||||||
},
|
}
|
||||||
dataLink: this.editChart.param.dataLink
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete this.editChart.elements
|
delete this.editChart.elements
|
||||||
|
|||||||
@@ -289,93 +289,6 @@
|
|||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Data link-->
|
|
||||||
<template v-if="chartConfig.type!=='group'">
|
|
||||||
<div class="form__sub-title" >
|
|
||||||
<span>{{$t('dashboard.dashboard.chartForm.dataLink')}}</span>
|
|
||||||
</div>
|
|
||||||
<draggable
|
|
||||||
v-model="chartConfig.param.dataLink"
|
|
||||||
@start="start"
|
|
||||||
@end="onEnd"
|
|
||||||
:scroll-sensitivity="150"
|
|
||||||
:options="{
|
|
||||||
dragClass:'drag-dataLink-class',
|
|
||||||
fallbackClass:'fallback-class',
|
|
||||||
forceFallback:true,
|
|
||||||
ghostClass:'chart-ghost',
|
|
||||||
chosenClass:'choose-class',
|
|
||||||
scroll:true,
|
|
||||||
filter: '.drag-disabled',
|
|
||||||
animation: 150,
|
|
||||||
handle: '.drag-sort'
|
|
||||||
}">
|
|
||||||
<div v-for="(item,index) in chartConfig.param.dataLink" :key="index" :class="item.error? 'is-item-box-error' : ''">
|
|
||||||
<div class="chart-title chart-title-config">
|
|
||||||
<span class="chart-title-content">
|
|
||||||
<i class="nz-icon nz-icon-arrow-down" :class="item.show?'':'is-active'" @click="showDataLink(index)"></i>
|
|
||||||
<span v-show="!item.show" class="title-content-left">
|
|
||||||
<span>
|
|
||||||
{{item.title}}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<span @click="addDataLink()" :title="$t('tip.add')">
|
|
||||||
<i class="nz-icon nz-icon-create-square" style="font-weight: normal; font-size: 17px; cursor: pointer;"></i>
|
|
||||||
</span>
|
|
||||||
<span style="margin-right: 5px" :title="$t('overall.duplicate')">
|
|
||||||
<i @click="copyDataLink(index)" class="nz-icon nz-icon-override"></i>
|
|
||||||
</span>
|
|
||||||
<span style="margin-right: 5px" class="nz-icon-minus-medium" :title="$t('overall.delete')">
|
|
||||||
<i @click="removeDataLink(index)" class="nz-icon nz-icon-minus"></i>
|
|
||||||
</span>
|
|
||||||
<span style="margin-right: 5px;fontSize:17px;cursor: grab;" class="drag-sort" :title="$t('dashboard.dashboard.chartForm.sort')">
|
|
||||||
<i class="nz-icon nz-icon-sort" style="cursor: grab;"></i>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<transition-group appear tag="div" name="el-zoom-in-top">
|
|
||||||
<el-row class="thresholds-item" v-show="item.show" :key="1">
|
|
||||||
<div>
|
|
||||||
<div class='mapping-display'>{{$t("dashboard.dashboard.chartForm.title")}}</div>
|
|
||||||
</div>
|
|
||||||
<!-- Title -->
|
|
||||||
<el-form-item :prop="'param.dataLink.' + index + '.title'" class="thresholds-from-item">
|
|
||||||
<el-input size="small" v-model="item.title" @change="change"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<div>
|
|
||||||
<div class='mapping-display'>{{$t('dashboard.dashboard.chartForm.openIn')}}</div>
|
|
||||||
</div>
|
|
||||||
<!-- Open in -->
|
|
||||||
<el-form-item :prop="'param.dataLink.' + index + '.openIn'" class="thresholds-from-item">
|
|
||||||
<el-select
|
|
||||||
v-model="item.openIn"
|
|
||||||
size="small"
|
|
||||||
@change="change"
|
|
||||||
>
|
|
||||||
<el-option value="newTab" :label="$t('dashboard.dashboard.chartForm.newTab')"></el-option>
|
|
||||||
<el-option value="currentTab" :label="$t('dashboard.dashboard.chartForm.currentTab')"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-row>
|
|
||||||
<el-row class="thresholds-item" v-show="item.show" :key="2">
|
|
||||||
<div>
|
|
||||||
<div class='mapping-display'>{{$t('dashboard.dashboard.chartForm.dataLinkUrl')}}</div>
|
|
||||||
</div>
|
|
||||||
<!-- url -->
|
|
||||||
<el-form-item :prop="'param.dataLink.' + index + '.url'" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}" class="thresholds-from-item">
|
|
||||||
<el-input v-model="item.url" size="small" @change="change('dataLink',index)"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-row>
|
|
||||||
</transition-group>
|
|
||||||
</div>
|
|
||||||
</draggable>
|
|
||||||
<div @click="addDataLink" class="thresholds-add">
|
|
||||||
{{$t('overall.addDataLink')}}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -385,14 +298,12 @@ import publicConfig from '@/components/common/rightBox/chart/publicConfig'
|
|||||||
import chartTypeShow from '@/components/common/rightBox/chart/chartTypeShow'
|
import chartTypeShow from '@/components/common/rightBox/chart/chartTypeShow'
|
||||||
import diagram from '@/components/common/ChartDiagram/diagram'
|
import diagram from '@/components/common/ChartDiagram/diagram'
|
||||||
import richTextEditor from '@/components/chart/richTextEditor'
|
import richTextEditor from '@/components/chart/richTextEditor'
|
||||||
import draggable from 'vuedraggable'
|
|
||||||
export default {
|
export default {
|
||||||
name: 'otherChartConfig',
|
name: 'otherChartConfig',
|
||||||
mixins: [publicConfig, chartTypeShow],
|
mixins: [publicConfig, chartTypeShow],
|
||||||
components: {
|
components: {
|
||||||
diagram,
|
diagram,
|
||||||
richTextEditor,
|
richTextEditor
|
||||||
draggable
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
// 'chartConfig.param.text': {
|
// 'chartConfig.param.text': {
|
||||||
@@ -462,8 +373,7 @@ export default {
|
|||||||
},
|
},
|
||||||
repeat: {
|
repeat: {
|
||||||
variable: ''
|
variable: ''
|
||||||
},
|
}
|
||||||
dataLink: this.chartConfig.param.dataLink
|
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'text':
|
case 'text':
|
||||||
@@ -479,8 +389,7 @@ export default {
|
|||||||
operator: 'equal',
|
operator: 'equal',
|
||||||
varValue: '',
|
varValue: '',
|
||||||
result: 'show'
|
result: 'show'
|
||||||
},
|
}
|
||||||
dataLink: this.chartConfig.param.dataLink
|
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'diagram':
|
case 'diagram':
|
||||||
@@ -496,8 +405,7 @@ export default {
|
|||||||
operator: 'equal',
|
operator: 'equal',
|
||||||
varValue: '',
|
varValue: '',
|
||||||
result: 'show'
|
result: 'show'
|
||||||
},
|
}
|
||||||
dataLink: this.chartConfig.param.dataLink
|
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'url':
|
case 'url':
|
||||||
@@ -513,8 +421,7 @@ export default {
|
|||||||
operator: 'equal',
|
operator: 'equal',
|
||||||
varValue: '',
|
varValue: '',
|
||||||
result: 'show'
|
result: 'show'
|
||||||
},
|
}
|
||||||
dataLink: this.chartConfig.param.dataLink
|
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'clock':
|
case 'clock':
|
||||||
@@ -530,8 +437,7 @@ export default {
|
|||||||
operator: 'equal',
|
operator: 'equal',
|
||||||
varValue: '',
|
varValue: '',
|
||||||
result: 'show'
|
result: 'show'
|
||||||
},
|
}
|
||||||
dataLink: this.chartConfig.param.dataLink
|
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -549,13 +455,6 @@ export default {
|
|||||||
this.chartConfig.param.text = html
|
this.chartConfig.param.text = html
|
||||||
this.$refs.chartForm.validateField('param.text')
|
this.$refs.chartForm.validateField('param.text')
|
||||||
this.change()
|
this.change()
|
||||||
},
|
|
||||||
start () {
|
|
||||||
document.body.classList.add('isDrag')
|
|
||||||
},
|
|
||||||
onEnd () {
|
|
||||||
this.change()
|
|
||||||
document.body.classList.remove('isDrag')
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
|
|||||||
Reference in New Issue
Block a user