diff --git a/nezha-fronted/src/components/chart/chart/chartPieD3.vue b/nezha-fronted/src/components/chart/chart/chartPieD3.vue
index 71c742fb1..277cbdced 100644
--- a/nezha-fronted/src/components/chart/chart/chartPieD3.vue
+++ b/nezha-fronted/src/components/chart/chart/chartPieD3.vue
@@ -1,6 +1,20 @@
-
@@ -38,6 +53,8 @@ import chartMixin from '@/components/chart/chartMixin'
import chartDataFormat from '@/components/chart/chartDataFormat'
import { getMetricTypeValue } from '@/components/common/js/tools'
import { initColor } from '@/components/chart/chart/tools'
+import legend from '@/components/chart/chart/legend'
+import { chartLegendPlacement } from '@/components/common/js/constants'
export default {
data () {
return {
@@ -65,6 +82,9 @@ export default {
chartOption: Object,
isFullscreen: Boolean
},
+ components: {
+ chartLegend: legend
+ },
mounted () {
this.colorList = initColor(20)
this.initChart()
@@ -82,7 +102,7 @@ export default {
this.chartOption.series[0],
this.chartData
)[0].data
- this.drawArcPie()
+ this.drawArcPie(this.dataset)
}, 200)
})
},
@@ -100,11 +120,15 @@ export default {
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 type = 'pie'
+ const color = this.colorList[colorIndex]
// eslint-disable-next-line vue/no-mutating-props
mapping && this.chartOption.color && (this.chartOption.color[colorIndex] = mapping.color.bac)
const legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex)
s.data.push({
value: value,
+ type: type,
+ color: color,
realValue: value,
showValue: showValue,
name: legend.name,
@@ -128,7 +152,7 @@ export default {
},
// 绘制饼图
- drawArcPie () {
+ drawArcPie (data) {
this.$nextTick(() => {
d3.select(`#chart-canvas-${this.chartId}`).selectAll('svg').remove()// 清空作图区域
// 重新赋值宽高
@@ -139,7 +163,7 @@ export default {
} catch (error) {
}
// 如果数据全为0 则设置默认值(否则图表不显示)
- let dataset = lodash.cloneDeep(this.dataset)
+ let dataset = lodash.cloneDeep(data)
if (dataset.every(item => item.value == 0)) {
dataset = dataset.map(item => {
return {
@@ -159,7 +183,7 @@ export default {
const pie = d3.pie().value(function (d) {
return d.value
})
- const piedata = pie(this.dataset)
+ const piedata = pie(data)
const arc = d3
.arc()
.innerRadius(this.innerRadius)
@@ -184,34 +208,63 @@ export default {
// 边界线
// .attr('stroke', 'white')
// 颜色
- .attr('fill', (d, i) => this.colorList[i])
+ .attr('fill', (d, i) => {
+ if (d.data.color) {
+ return d.data.color
+ } else {
+ return this.colorList[i]
+ }
+ })
// 文字
arcs
.append('foreignObject')
.attr('y', d => { // y轴居中减文字大小的一半
const y = arc.centroid(d)[1]
- return y - Math.sqrt(2) / 2 * (this.outerRadius / 2) + Math.floor(this.outerRadius / 18)
+ return y - Math.sqrt(2) / 2 * (this.outerRadius / 2) + Math.ceil(this.outerRadius / 16)
})
.attr('transform', (d, i) => {
- return 'translate(' + (arc.centroid(d)[0] - Math.abs(arc.centroid(d)[0]) - Math.floor(this.outerRadius / 18)) + ',' + (0) + ')' // x轴为最左侧 //x轴居中减文字大小的一半
+ return 'translate(' + (arc.centroid(d)[0] - Math.abs(arc.centroid(d)[0]) - Math.ceil(this.outerRadius / 16)) + ',' + (0) + ')' // x轴为最左侧 //x轴居中减文字大小的一半
})
- .style('font-size', () => {
- return Math.floor(this.outerRadius / 9)
+ .style('font-size', (i) => {
+ if (Math.ceil(this.outerRadius / 8) > 30) {
+ return 30
+ } else {
+ return Math.ceil(this.outerRadius / 8)
+ }
})
- .attr('width', function (d, i) {
+ .attr('width', (d, i) => {
if ((d.endAngle - d.startAngle) < 0.25) {
return 0
} else {
return Math.abs(arc.centroid(d)[0]) * 2
}
})
- .attr('height', function (d, i) {
- return Math.abs(arc.centroid(d)[1])
+ .attr('height', (d, i) => {
+ if (Math.ceil(this.outerRadius / 8) > 30) {
+ return 90
+ } else {
+ return Math.ceil(this.outerRadius / 8) * 3
+ }
+ // return Math.abs(arc.centroid(d)[1]) - Math.ceil(this.outerRadius / 10)
})
- // .attr('height', '20px')
- .style('line-height', '20px')
- .style('text-align', 'center')
+ .style('padding-left', () => {
+ if (this.isFullscreen) {
+ return 20
+ } else {
+ return 5
+ }
+ })
+ .style('padding-right', (d, i) => {
+ const path = document.getElementsByClassName('path')[i]
+ const w = path.getBoundingClientRect().width
+ if (((d.endAngle - d.startAngle) < 0.25) || (Math.abs(arc.centroid(d)[0]) * 2 < w / 2)) {
+ return 0
+ } else {
+ return (Math.abs(arc.centroid(d)[0]) * 2 - w / 3) / 2
+ }
+ })
+ .style('line-height', '16px')
.html((d) => {
return this.drawText(d)
})
@@ -253,7 +306,7 @@ export default {
if (str && valueStr) {
return `
-
+
${str}
@@ -264,14 +317,14 @@ export default {
node.data.mapping.color &&
node.data.mapping.color.icon
};font-size:1em;">
- ${valueStr}
+ ${valueStr}
`
} else if (str) {
return `
-
-
+
`
} else if (valueStr) {
return `
-
+
- ${valueStr}
+ ${valueStr}
`
@@ -346,7 +399,7 @@ export default {
},
resize () {
setTimeout(() => {
- this.drawArcPie()
+ this.drawArcPie(this.dataset)
}, 50)
},
clearCache () {
@@ -356,10 +409,38 @@ export default {
},
beforeDestroy () {
this.clearCache()
+ },
+ hasLegend () {
+ try {
+ return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1
+ } catch (e) {
+ return false
+ }
+ },
+ legendPlacement () {
+ try {
+ switch (this.chartInfo.param.legend.placement) {
+ case 'left':
+ case 'right':
+ case 'bottom': {
+ return `nz-chart__component--${this.chartInfo.param.legend.placement}`
+ }
+ default: return ''
+ }
+ } catch (e) {
+ return ''
+ }
+ },
+ pieData (data) {
+ this.drawArcPie(data)
}
}
}
->
diff --git a/nezha-fronted/src/components/chart/chart/legend.vue b/nezha-fronted/src/components/chart/chart/legend.vue
index d9aade502..a4ee74dd4 100644
--- a/nezha-fronted/src/components/chart/chart/legend.vue
+++ b/nezha-fronted/src/components/chart/chart/legend.vue
@@ -14,7 +14,7 @@
:key="index"
:class="{'row--inactive': isGrey[index]}"
class="legend--table-row"
- @click="clickLegend(item.name, index)"
+ @click="clickLegend(item.name, index,item)"
>
{{item.alias ? item.alias : item.name}}
@@ -98,6 +98,10 @@ export default {
this.clickLegendTreemap(legendName, index, hasGrey, curIsGrey, currentIsTheOnlyOneHighlight)
return
}
+ if (this.chartInfo.type === 'pie') {
+ this.clickLegendPie(legendName, index, hasGrey, curIsGrey, currentIsTheOnlyOneHighlight)
+ return
+ }
if (echarts) {
// 判断timeSeries类型图表 先取消多表联动
@@ -161,6 +165,17 @@ export default {
}
}
},
+ clickLegendPie (legendName, index, hasGrey, curIsGrey, currentIsTheOnlyOneHighlight) {
+ if (!hasGrey) { // 1.除当前legend外全置灰
+ this.isGrey = this.isGrey.map((g, i) => i !== index)
+ } else if (currentIsTheOnlyOneHighlight) { // 2.全高亮
+ this.isGrey = this.isGrey.map(() => false)
+ } else { // 对应高亮
+ this.$set(this.isGrey, index, !this.isGrey[index])
+ }
+ const data = this.legends.filter((item, i) => !this.isGrey[i])
+ this.$emit('pieData', data)
+ },
clickLegendBar (legendName, index, hasGrey, curIsGrey, currentIsTheOnlyOneHighlight) {
const echarts = getChart(this.chartId)
if (echarts) {