NEZ-2243 feat:排行图表样式调整
This commit is contained in:
@@ -19,6 +19,11 @@
|
|||||||
<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>rank</div>
|
||||||
|
<div>{{tooltip.rank+1}}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -27,7 +32,7 @@
|
|||||||
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 * as d3 from 'd3'
|
import * as d3 from 'd3'
|
||||||
import { formatScientificNotation, 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 lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
@@ -57,6 +62,7 @@ export default {
|
|||||||
title: 0,
|
title: 0,
|
||||||
value: 0,
|
value: 0,
|
||||||
mapping: {},
|
mapping: {},
|
||||||
|
rank: 0,
|
||||||
show: false
|
show: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,24 +91,26 @@ export default {
|
|||||||
originalDatas.forEach((originalData, expressionIndex) => {
|
originalDatas.forEach((originalData, expressionIndex) => {
|
||||||
originalData.forEach((data, dataIndex) => {
|
originalData.forEach((data, dataIndex) => {
|
||||||
const value = getMetricTypeValue(data.values, chartInfo.param.statistics)
|
const value = getMetricTypeValue(data.values, chartInfo.param.statistics)
|
||||||
const showValue = chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(value, null, -1, decimals)
|
if (value != 0) {
|
||||||
const mapping = this.selectMapping(value, chartInfo.param.valueMapping, chartInfo.param.enable && this.chartInfo.param.enable.valueMapping)
|
const showValue = chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(value, null, -1, decimals)
|
||||||
const legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex)
|
const mapping = this.selectMapping(value, chartInfo.param.valueMapping, chartInfo.param.enable && this.chartInfo.param.enable.valueMapping)
|
||||||
this.rankData.push({
|
const legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex)
|
||||||
value: value,
|
this.rankData.push({
|
||||||
realValue: value,
|
value: value,
|
||||||
showValue: showValue,
|
realValue: value,
|
||||||
name: legend.name,
|
showValue: showValue,
|
||||||
alias: legend.alias,
|
name: legend.name,
|
||||||
labels: {
|
alias: legend.alias,
|
||||||
...data.metric,
|
labels: {
|
||||||
legend: legend.alias
|
...data.metric,
|
||||||
},
|
legend: legend.alias
|
||||||
seriesIndex: expressionIndex,
|
},
|
||||||
dataIndex: dataIndex,
|
seriesIndex: expressionIndex,
|
||||||
mapping: mapping
|
dataIndex: dataIndex,
|
||||||
})
|
mapping: mapping
|
||||||
colorIndex++
|
})
|
||||||
|
colorIndex++
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -119,14 +127,12 @@ export default {
|
|||||||
const height = svgDom.getBoundingClientRect().height
|
const height = svgDom.getBoundingClientRect().height
|
||||||
const bodyX = 50
|
const bodyX = 50
|
||||||
const bodyY = 50
|
const bodyY = 50
|
||||||
const bodyWidth = width - 2 * bodyX
|
const bodyWidth = width - 3 * bodyX
|
||||||
const bodyHeight = height - 2 * bodyY
|
const bodyHeight = height - 2 * bodyY
|
||||||
const svg = d3.select(`#rank-svg-${this.chartId}`)
|
const svg = d3.select(`#rank-svg-${this.chartId}`)
|
||||||
|
|
||||||
// 从大到小排序
|
// 从大到小排序
|
||||||
let rankData = lodash.cloneDeep(this.rankData)
|
let rankData = lodash.cloneDeep(this.rankData)
|
||||||
// 过滤掉为0的数据
|
|
||||||
rankData = rankData.filter(item => item.value != 0)
|
|
||||||
rankData.sort((a, b) => b.value - a.value)
|
rankData.sort((a, b) => b.value - a.value)
|
||||||
rankData = rankData.map((item, index) => {
|
rankData = rankData.map((item, index) => {
|
||||||
return {
|
return {
|
||||||
@@ -144,8 +150,10 @@ export default {
|
|||||||
const scaleY = d3.scaleBand()
|
const scaleY = d3.scaleBand()
|
||||||
.domain(rankData.map((d) => d.rank).sort((a, b) => b - a))
|
.domain(rankData.map((d) => d.rank).sort((a, b) => b - a))
|
||||||
.range([bodyHeight, 0])
|
.range([bodyHeight, 0])
|
||||||
.paddingInner(0.3)
|
|
||||||
.paddingOuter(0.06)
|
.paddingOuter(0.06)
|
||||||
|
.paddingInner(0.6)
|
||||||
|
|
||||||
|
const minWidth = 10
|
||||||
|
|
||||||
// 渲染柱形
|
// 渲染柱形
|
||||||
const bars = svg.append('g')
|
const bars = svg.append('g')
|
||||||
@@ -159,32 +167,13 @@ export default {
|
|||||||
.attr('y', (d) => scaleY(d.rank))
|
.attr('y', (d) => scaleY(d.rank))
|
||||||
.attr('height', scaleY.bandwidth())
|
.attr('height', scaleY.bandwidth())
|
||||||
.attr('fill', (d) => d.background)
|
.attr('fill', (d) => d.background)
|
||||||
.attr('width', (d) => scaleX(d.value) > 10 ? scaleX(d.value) : 10)
|
.attr('width', (d) => scaleX(d.value) > minWidth ? scaleX(d.value) : minWidth)
|
||||||
|
.style('cursor', 'pointer')
|
||||||
|
.on('mouseenter', this.rankEnter)
|
||||||
|
.on('mousemove', this.rankMove)
|
||||||
|
.on('mouseleave', this.rankLeave)
|
||||||
bars.exit().remove()
|
bars.exit().remove()
|
||||||
|
|
||||||
// 坐标轴
|
|
||||||
const xAxis = d3.axisTop(scaleX)
|
|
||||||
.ticks(6)
|
|
||||||
.tickSize(-(bodyHeight))
|
|
||||||
// .tickSizeOuter(0)
|
|
||||||
// .tickSizeInner(0)
|
|
||||||
.tickFormat(d => {
|
|
||||||
const value = formatScientificNotation(d, 6)
|
|
||||||
let chartUnit = this.chartInfo.unit
|
|
||||||
chartUnit = chartUnit || 2
|
|
||||||
const unit = chartDataFormat.getUnit(chartUnit)
|
|
||||||
return unit.compute(value, null, -1, 2)
|
|
||||||
})
|
|
||||||
const ticks = svg.append('g')
|
|
||||||
.attr('class', 'xAxis')
|
|
||||||
.call(xAxis)
|
|
||||||
.attr('transform', `translate(${bodyX},${bodyY})`)
|
|
||||||
ticks.select('.tick:first-of-type text').remove()
|
|
||||||
ticks.selectAll('.tick text').attr('class', 'tickTest')
|
|
||||||
ticks.select('.tick:first-of-type line').attr('class', 'tickLineFirst')
|
|
||||||
ticks.selectAll('.tick:not(:first-of-type) line').attr('class', 'tickLine')
|
|
||||||
ticks.select('.domain').remove()
|
|
||||||
|
|
||||||
// 文本标签
|
// 文本标签
|
||||||
svg.append('g')
|
svg.append('g')
|
||||||
.attr('transform', `translate(${bodyX},${bodyY})`)
|
.attr('transform', `translate(${bodyX},${bodyY})`)
|
||||||
@@ -196,63 +185,59 @@ export default {
|
|||||||
.on('mousemove', this.rankMove)
|
.on('mousemove', this.rankMove)
|
||||||
.on('mouseleave', this.rankLeave)
|
.on('mouseleave', this.rankLeave)
|
||||||
.html((d) => {
|
.html((d) => {
|
||||||
let flag = true
|
|
||||||
// 判断柱子宽度和高度
|
// 判断柱子宽度和高度
|
||||||
if (scaleY.bandwidth() < 38 || scaleX(d.value) < 120) {
|
if (scaleY.bandwidth() > 10) {
|
||||||
flag = false
|
return this.rankFormatterLabel(d)
|
||||||
}
|
}
|
||||||
return flag ? this.rankFormatterLabel(d) : ''
|
|
||||||
})
|
})
|
||||||
.attr('x', scaleX(0))
|
.attr('x', (d) => {
|
||||||
|
let x = 0
|
||||||
|
if (scaleX(d.value) > minWidth) {
|
||||||
|
x = scaleX(d.value) + 10
|
||||||
|
} else {
|
||||||
|
x = minWidth + 10
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
})
|
||||||
.attr('y', (d) => scaleY(d.rank))
|
.attr('y', (d) => scaleY(d.rank))
|
||||||
.attr('height', scaleY.bandwidth())
|
.attr('height', scaleY.bandwidth())
|
||||||
.attr('width', (d) => scaleX(d.value) > 10 ? scaleX(d.value) : 10)
|
|
||||||
.style('cursor', 'pointer')
|
.style('cursor', 'pointer')
|
||||||
|
.style('overflow', 'visible')
|
||||||
|
|
||||||
|
// 生成标签和矩形
|
||||||
|
svg.append('g')
|
||||||
|
.attr('transform', `translate(${bodyX},${bodyY})`)
|
||||||
|
.selectAll('text')
|
||||||
|
.data(rankData)
|
||||||
|
.enter()
|
||||||
|
.append('text')
|
||||||
|
.attr('x', 4)
|
||||||
|
.attr('y', d => scaleY(d.rank) - 12)
|
||||||
|
.text(d => {
|
||||||
|
if (this.chartInfo.param.text !== 'all' && this.chartInfo.param.text !== 'legend') {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
const margin = scaleY(1) - scaleY(0) - scaleY.bandwidth()
|
||||||
|
if (margin > 30 || !margin) {
|
||||||
|
return d.alias
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理label
|
// 处理label
|
||||||
rankFormatterLabel (data) {
|
rankFormatterLabel (data) {
|
||||||
let str = ''
|
|
||||||
let valueStr = ''
|
let valueStr = ''
|
||||||
if (this.chartInfo.param.text === 'all') {
|
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
|
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, { ...data.labels, 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 (valueStr) {
|
||||||
str += data.alias
|
|
||||||
}
|
|
||||||
if (this.chartInfo.param.text === 'none') {
|
|
||||||
str += ''
|
|
||||||
}
|
|
||||||
if (str && valueStr) {
|
|
||||||
return `
|
return `
|
||||||
<div style="width:100%;height: 100%;display: flex;align-items: flex-end;justify-content: center;flex-direction: column;color:#000000">
|
<div style="width:auto;height: 100%;display: flex;justify-content: center;flex-direction: column;">
|
||||||
<p style="width:100%;padding:0 12px;box-sizing: border-box;text-overflow: ellipsis;white-space: nowrap;overflow:hidden;text-align:right;color: ${data.mapping && data.mapping.color && data.mapping.color.text}">
|
<p class="chart-label" style="cursor:pointer;white-space: nowrap;color: ${data.mapping && data.mapping.color && data.mapping.color.text}">
|
||||||
<span>${str}</span>
|
|
||||||
</p>
|
|
||||||
<p style="width:100%;padding:0 12px;box-sizing: border-box;text-overflow: ellipsis;white-space: nowrap;overflow:hidden;text-align:right;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) {
|
|
||||||
return `
|
|
||||||
<div style="width:100%;height: 100%;display: flex;align-items: flex-end;justify-content: center;flex-direction: column;color:#000000">
|
|
||||||
<p style="width:100%;padding:0 12px;box-sizing: border-box;text-overflow: ellipsis;white-space: nowrap;overflow:hidden;text-align:right;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) {
|
|
||||||
return `
|
|
||||||
<div style="width:100%;height: 100%;display: flex;align-items: flex-end;justify-content: center;flex-direction: column;color:#000000">
|
|
||||||
<p style="width:100%;padding:0 12px;box-sizing: border-box;text-overflow: ellipsis;white-space: nowrap;overflow:hidden;text-align:right;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>
|
||||||
@@ -265,6 +250,7 @@ export default {
|
|||||||
this.tooltip.title = data.alias
|
this.tooltip.title = data.alias
|
||||||
this.tooltip.value = data.showValue
|
this.tooltip.value = data.showValue
|
||||||
this.tooltip.mapping = data.mapping
|
this.tooltip.mapping = data.mapping
|
||||||
|
this.tooltip.rank = data.rank
|
||||||
this.tooltip.show = true
|
this.tooltip.show = true
|
||||||
this.setPosition(e)
|
this.setPosition(e)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -99,16 +99,18 @@ export default {
|
|||||||
originalDatas.forEach((originalData) => {
|
originalDatas.forEach((originalData) => {
|
||||||
originalData.forEach((data, dataIndex) => {
|
originalData.forEach((data, dataIndex) => {
|
||||||
const value = getMetricTypeValue(data.values, chartInfo.param.statistics)
|
const value = getMetricTypeValue(data.values, chartInfo.param.statistics)
|
||||||
const obj = {
|
if (value != 0) {
|
||||||
value: value,
|
const obj = {
|
||||||
realValue: value,
|
value: value,
|
||||||
labels: data.metric,
|
realValue: value,
|
||||||
dataIndex: dataIndex
|
labels: data.metric,
|
||||||
}
|
dataIndex: dataIndex
|
||||||
if (data.metric[chartInfo.param.sourceLabel] && data.metric[chartInfo.param.targetLabel]) {
|
}
|
||||||
obj.source = data.metric[chartInfo.param.sourceLabel]
|
if (data.metric[chartInfo.param.sourceLabel] && data.metric[chartInfo.param.targetLabel]) {
|
||||||
obj.target = data.metric[chartInfo.param.targetLabel]
|
obj.source = data.metric[chartInfo.param.sourceLabel]
|
||||||
sankeyData.push(obj)
|
obj.target = data.metric[chartInfo.param.targetLabel]
|
||||||
|
sankeyData.push(obj)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -705,6 +705,7 @@
|
|||||||
:prop="'param.valueMapping.' + index + '.value'"
|
:prop="'param.valueMapping.' + index + '.value'"
|
||||||
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
||||||
class="thresholds-from-item"
|
class="thresholds-from-item"
|
||||||
|
key="value"
|
||||||
>
|
>
|
||||||
<el-input-number
|
<el-input-number
|
||||||
:controls="false"
|
:controls="false"
|
||||||
@@ -719,6 +720,7 @@
|
|||||||
:prop="'param.valueMapping.' + index + '.from'"
|
:prop="'param.valueMapping.' + index + '.from'"
|
||||||
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
||||||
class="thresholds-from-item"
|
class="thresholds-from-item"
|
||||||
|
key="from"
|
||||||
>
|
>
|
||||||
<el-input-number
|
<el-input-number
|
||||||
:controls="false"
|
:controls="false"
|
||||||
@@ -733,6 +735,7 @@
|
|||||||
:prop="'param.valueMapping.' + index + '.to'"
|
:prop="'param.valueMapping.' + index + '.to'"
|
||||||
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
||||||
class="thresholds-from-item"
|
class="thresholds-from-item"
|
||||||
|
key="to"
|
||||||
>
|
>
|
||||||
<el-input-number
|
<el-input-number
|
||||||
:controls="false"
|
:controls="false"
|
||||||
@@ -747,6 +750,7 @@
|
|||||||
:prop="'param.valueMapping.' + index + '.regx'"
|
:prop="'param.valueMapping.' + index + '.regx'"
|
||||||
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
||||||
class="thresholds-from-item"
|
class="thresholds-from-item"
|
||||||
|
key="regx"
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
size="small"
|
size="small"
|
||||||
|
|||||||
@@ -620,6 +620,7 @@
|
|||||||
:prop="'param.valueMapping.' + index + '.value'"
|
:prop="'param.valueMapping.' + index + '.value'"
|
||||||
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
||||||
class="thresholds-from-item"
|
class="thresholds-from-item"
|
||||||
|
key="value"
|
||||||
>
|
>
|
||||||
<el-input-number
|
<el-input-number
|
||||||
:controls="false"
|
:controls="false"
|
||||||
@@ -634,6 +635,7 @@
|
|||||||
:prop="'param.valueMapping.' + index + '.from'"
|
:prop="'param.valueMapping.' + index + '.from'"
|
||||||
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
||||||
class="thresholds-from-item"
|
class="thresholds-from-item"
|
||||||
|
key="from"
|
||||||
>
|
>
|
||||||
<el-input-number
|
<el-input-number
|
||||||
:controls="false"
|
:controls="false"
|
||||||
@@ -648,6 +650,7 @@
|
|||||||
:prop="'param.valueMapping.' + index + '.to'"
|
:prop="'param.valueMapping.' + index + '.to'"
|
||||||
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
||||||
class="thresholds-from-item"
|
class="thresholds-from-item"
|
||||||
|
key="to"
|
||||||
>
|
>
|
||||||
<el-input-number
|
<el-input-number
|
||||||
:controls="false"
|
:controls="false"
|
||||||
@@ -662,6 +665,7 @@
|
|||||||
:prop="'param.valueMapping.' + index + '.regx'"
|
:prop="'param.valueMapping.' + index + '.regx'"
|
||||||
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
||||||
class="thresholds-from-item"
|
class="thresholds-from-item"
|
||||||
|
key="regx"
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
size="small"
|
size="small"
|
||||||
|
|||||||
Reference in New Issue
Block a user