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 ` -
-

+

+

- ${str} + ${str}

` } 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) {