From 04d7db2dddcccc1410ee205a5773b9f576cb6073 Mon Sep 17 00:00:00 2001 From: jiangyy Date: Fri, 24 Jun 2022 16:11:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86=E5=88=86?= =?UTF-8?q?=E6=9E=90=E5=9B=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../communityGovern/shijianchuli/chart.js | 8 +- .../shijianchuli/shijianchulifenxi copy.vue | 2 - .../shijianchuli/shijianchulifenxi.vue | 558 ++++++++++-------- 3 files changed, 326 insertions(+), 242 deletions(-) diff --git a/src/views/modules/visual/communityGovern/shijianchuli/chart.js b/src/views/modules/visual/communityGovern/shijianchuli/chart.js index f7c5dda59..a1006c0ac 100644 --- a/src/views/modules/visual/communityGovern/shijianchuli/chart.js +++ b/src/views/modules/visual/communityGovern/shijianchuli/chart.js @@ -7,7 +7,8 @@ * @param pieHeight 立体的高度 * @param opacity 饼或者环的透明度 */ - const getPie3D = (pieData, internalDiameterRatio, distance, alpha, pieHeight, opacity = 1) => { + const getPie3D = (pieData, internalDiameterRatio, distance, alpha, pieHeight, opacity = 1,beta) => { + const series = [] let sumValue = 0 let startValue = 0 @@ -53,7 +54,7 @@ } series.push(seriesItem) } - + // 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数, // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。 legendData = [] @@ -156,7 +157,7 @@ viewControl: { // 3d效果可以放大、旋转等,请自己去查看官方配置 alpha, // 角度 - beta: -40, + beta, distance, // 调整视角到主体的距离,类似调整zoom rotateSensitivity: 0, // 设置为0无法旋转 zoomSensitivity: 0, // 设置为0无法缩放 @@ -245,6 +246,7 @@ const getParametricEquation = (startRatio, endRatio, isSelected, isHovered, k, h * 获取3d丙图的最高扇区的高度 */ const getHeight3D = (series, height) => { + series.sort((a, b) => { return b.pieData.value - a.pieData.value }) diff --git a/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi copy.vue b/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi copy.vue index 301a60a96..68732303d 100644 --- a/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi copy.vue +++ b/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi copy.vue @@ -637,8 +637,6 @@ export default { }; // element.selected = !element.selected } else { - - element.selected = false element.label = { show: false, diff --git a/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi.vue b/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi.vue index c3a5c819b..f789a52d5 100644 --- a/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi.vue +++ b/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi.vue @@ -190,6 +190,16 @@ export default { value: 72 } ], + optionDataLine: [ + { + name: '处理中', + value: 50 + }, + { + name: '已完成', + value: 50 + } + ], statusChart: null, option: {}, @@ -300,6 +310,9 @@ export default { showProject: false, eventId: '', + beta: 20, + selectedIndex: '' + }; }, // mixins: [animate] @@ -360,7 +373,7 @@ export default { } if (index !== '0' && isRefresh) { await this.getApiData() - // this.assignPieChart() + } @@ -368,7 +381,7 @@ export default { assignData () { this.initChart() - // this.getPie() + this.getLine() }, @@ -444,16 +457,68 @@ export default { url: require('@/assets/img/shuju/measure/lv@2x.png') } ] + let dataClosed = Math.floor(data.closedRatio * 10000) / 100 + let dataPro = Math.floor(data.processingRatio * 10000) / 100 + if (data.closedRatio === 0 && data.processingRatio === 0) { + dataClosed = 50 + dataPro = 50 + } + let dataClosedLine = Math.floor(data.closedRatio * 10000) / 100 + let dataProLine = Math.floor(data.processingRatio * 10000) / 100 + + // dataClosed = 5 + // dataPro = 95 + + // dataClosed = 10 + // dataPro = 90 + + // dataClosed = 20 + // dataPro = 80 + + // dataClosed = 30 + // dataPro = 70 + + // dataClosed = 40 + // dataPro = 60 + + // dataClosed = 50 + // dataPro = 50 + + + if (Math.abs(dataClosed - dataPro) > 80) { + this.beta = 70 + } else if (Math.abs(dataClosed - dataPro) > 70) { + this.beta = 60 + } else if (Math.abs(dataClosed - dataPro) > 50) { + this.beta = 20 + } else if (Math.abs(dataClosed - dataPro) > 30) { + this.beta = -20 + } else if (Math.abs(dataClosed - dataPro) > 10) { + this.beta = -30 + } else { + this.beta = -60 + } this.optionData = [ + { + name: "已完成", + value: dataClosed + }, + { + name: "处理中", + value: dataPro + }, + ] + + this.optionDataLine = [ { name: "已完成", - value: Math.floor(data.closedRatio * 10000) / 100 + value: dataClosedLine }, { name: "处理中", - value: Math.floor(data.processingRatio * 10000) / 100 + value: dataProLine }, ] this.setLabel() @@ -596,101 +661,68 @@ export default { }, true) }, - getPie () { - - if (this.pieInitState) { - this.assignPieChart() - } else { - setTimeout(() => { - this.getPie() - }, 500) - } - }, - // 获取饼状图 - async assignPieChart () { - - let maxIndex = 0 - - const _that = this - - // 获取pieChart配置 - this.pieOption = pieOption(this.pieChartS) - - this.pieData[0].selected = false - this.pieData[1].selected = false - - this.pieOption.title.text = this.projectTotal - - this.clickPie() - - let fun = function (params) { - - _that.clickPie(params) - } - this.$refs.pieChart.handleClick(fun) - - }, - - clickPie (params) { + setLabel () { + this.optionDataLine.forEach((item, index) => { - let dataIndex = params ? params.dataIndex : null - let componentIndex = params ? params.componentIndex : null - if (componentIndex === 1) {//点击数据 - if (dataIndex === 0) { - this.processStatus = 'closed_case' - } else if (dataIndex === 1) { - this.processStatus = 'processing' + item.itemStyle = { + color: color[index] } - } else if (componentIndex === 2) {//点击中心 - this.processStatus = '' - dataIndex = 3 - } - - if (dataIndex === 3) { - this.$refs.pieChart.clear() - } - this.pieData.forEach((element, index) => { - if (index === dataIndex) { - element.selected = true - element.label = { - show: true, - }; - element.labelLine = { + item.label = { + normal: { show: true, - lineStyle: { - opacity: 1, + color: color[index], + formatter: [ + '{d|{d}%}', + '{b|{b}}' + ].join('\n'), // 用\n来换行 + rich: { + b: { + color: '#fff', + lineHeight: 25, + align: 'left', + fontSize: 13, + marginTop: 20 + }, + c: { + fontSize: 22, + color: '#fff', + textShadowColor: '#1c90a6', + textShadowOffsetX: 0, + textShadowOffsetY: 2, + textShadowBlur: 5 + }, + d: { + color: color[index], + fontSize: 22, + align: 'left' + } } + } + } + item.labelLine = { - }; - // element.selected = !element.selected - } else { - - - element.selected = false - element.label = { - show: false, - - }; - element.labelLine = { - show: false, + normal: { + show: true, + length: 30, + length2: 80, lineStyle: { - opacity: 0, - color: 'rgba(255,255,255,0)' + width: 1, + color: 'rgba(255,255,255,0.7)' } + } + } + item.labelLayout = function (params) { + const isLeft = params.labelRect.x < myChart.getWidth() / 2; + const points = params.labelLinePoints; + // Update the end point. + points[2][0] = isLeft + ? params.labelRect.x + : params.labelRect.x + params.labelRect.width; + return { + labelLinePoints: points }; - element.selected = false } - }); - - this.pieOption.series[1].data = this.pieData - this.demand.pageNo = 1 - this.getTable() - - // this.$refs.pieChart.hideLoading() - this.$refs.pieChart.setOption(this.pieOption) - }, - - setLabel () { + }) this.optionData.forEach((item, index) => { item.itemStyle = { @@ -703,8 +735,6 @@ export default { formatter: [ '{d|{d}%}', '{b|{b}}' - - ].join('\n'), // 用\n来换行 rich: { b: { @@ -731,7 +761,9 @@ export default { } } item.labelLine = { + normal: { + show: true, length: 30, length2: 80, lineStyle: { @@ -760,7 +792,8 @@ export default { // let statusChart = echarts.init(document.getElementById('cityGreenLand-charts')); this.statusChart = echarts.init(document.getElementById('cityGreenLand')); // 传入数据生成 option, 构建3d饼状图, 参数工具文件已经备注的很详细 - this.option = getPie3D(this.optionData, 0.8, 300, 28, 22, 0.4) + this.option = getPie3D(this.optionData, 0.8, 300, 28, 22, 0.4, this.beta) + console.log(this.option) this.statusChart.setOption(this.option) // 是否需要label指引线,如果要就添加一个透明的2d饼状图并调整角度使得labelLine和3d的饼状图对齐,并再次setOption this.option.series.push({ @@ -772,14 +805,15 @@ export default { fontSize: 13, lineHeight: 20 }, - startAngle: 40, // 起始角度,支持范围[0, 360]。 + startAngle: -this.beta, // 起始角度,支持范围[0, 360]。 clockwise: false, // 饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式 radius: ['30%', '35%'], center: ['50%', '50%'], - data: this.optionData, + data: this.optionDataLine, itemStyle: { opacity: 0 //这里必须是0,不然2d的图会覆盖在表面 - } + }, + }) this.statusChart.setOption(this.option) this.bindListen(this.statusChart) @@ -789,155 +823,205 @@ export default { // 监听鼠标事件,实现饼图选中效果(单选),近似实现高亮(放大)效果。 // optionName是防止有多个图表进行定向option传递,单个图表可以不传,默认是opiton bindListen (myChart, optionName = 'option') { - let selectedIndex = '' + // let selectedIndex = '' let hoveredIndex = '' + // 监听点击事件,实现选中效果(单选) myChart.on('click', (params) => { - debugger - // 从 option.series 中读取重新渲染扇形所需的参数,将是否选中取反。 - const isSelected = !this[optionName].series[params.seriesIndex].pieStatus - .selected - const isHovered = - this[optionName].series[params.seriesIndex].pieStatus.hovered - const k = this[optionName].series[params.seriesIndex].pieStatus.k - const startRatio = - this[optionName].series[params.seriesIndex].pieData.startRatio - const endRatio = - this[optionName].series[params.seriesIndex].pieData.endRatio - // 如果之前选中过其他扇形,将其取消选中(对 option 更新) - if (selectedIndex !== '' && selectedIndex !== params.seriesIndex) { - this[optionName].series[ - selectedIndex - ].parametricEquation = getParametricEquation( - this[optionName].series[selectedIndex].pieData.startRatio, - this[optionName].series[selectedIndex].pieData.endRatio, - false, - false, - k, - this[optionName].series[selectedIndex].pieData.value - ) - this[optionName].series[selectedIndex].pieStatus.selected = false - } - // 对当前点击的扇形,执行选中/取消选中操作(对 option 更新) - this[optionName].series[ - params.seriesIndex - ].parametricEquation = getParametricEquation( - startRatio, - endRatio, - isSelected, - isHovered, - k, - this[optionName].series[params.seriesIndex].pieData.value - ) - this[optionName].series[params.seriesIndex].pieStatus.selected = isSelected - // 如果本次是选中操作,记录上次选中的扇形对应的系列号 seriesIndex - selectedIndex = isSelected ? params.seriesIndex : null - // 使用更新后的 option,渲染图表 - myChart.setOption(this[optionName]) - }) - // 监听 mouseover,近似实现高亮(放大)效果 - myChart.on('mouseover', (params) => { - // 准备重新渲染扇形所需的参数 - let isSelected - let isHovered - let startRatio - let endRatio - let k - // 如果触发 mouseover 的扇形当前已高亮,则不做操作 - if (hoveredIndex === params.seriesIndex) { - // 否则进行高亮及必要的取消高亮操作 - } else { - // 如果当前有高亮的扇形,取消其高亮状态(对 option 更新) - if (hoveredIndex !== '') { - // 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 false。 - isSelected = this[optionName].series[hoveredIndex].pieStatus.selected - isHovered = false - startRatio = this[optionName].series[hoveredIndex].pieData.startRatio - endRatio = this[optionName].series[hoveredIndex].pieData.endRatio - k = this[optionName].series[hoveredIndex].pieStatus.k - // 对当前点击的扇形,执行取消高亮操作(对 option 更新) - this[optionName].series[ - hoveredIndex - ].parametricEquation = getParametricEquation( - startRatio, - endRatio, - isSelected, - isHovered, - k, - this[optionName].series[hoveredIndex].pieData.value - ) - this[optionName].series[hoveredIndex].pieStatus.hovered = isHovered - // 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空 - hoveredIndex = '' + let dataIndex = null + console.log('params', params) + console.log('params.seriesIndex', params.seriesIndex) + console.log('this[optionName].series', this[optionName].series) + console.log('this[optionName].series[params.seriesIndex]', this[optionName].series[params.seriesIndex]) + + if (params.componentSubType === 'pie') {//点击指引线 + dataIndex = params.dataIndex + this.click3DPie(myChart, 'option', dataIndex) + + + if (dataIndex === 0) {//序列1 已完成 + this.processStatus = 'closed_case' + + } else if (dataIndex === 1) {//序列2 处理中 + this.processStatus = 'processing' + } else { + this.processStatus = '' } - // 如果触发 mouseover 的扇形不是透明圆环,将其高亮(对 option 更新) - if ( - params.seriesName !== 'mouseoutSeries' && - params.seriesName !== 'pie2d' - ) { - // 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。 - isSelected = - this[optionName].series[params.seriesIndex].pieStatus.selected - isHovered = true - startRatio = - this[optionName].series[params.seriesIndex].pieData.startRatio - endRatio = this[optionName].series[params.seriesIndex].pieData.endRatio - k = this[optionName].series[params.seriesIndex].pieStatus.k - // 对当前点击的扇形,执行高亮操作(对 option 更新) - this[optionName].series[ - params.seriesIndex - ].parametricEquation = getParametricEquation( - startRatio, - endRatio, - isSelected, - isHovered, - k, - this[optionName].series[params.seriesIndex].pieData.value + 60 - ) - this[optionName].series[ - params.seriesIndex - ].pieStatus.hovered = isHovered - // 记录上次高亮的扇形对应的系列号 seriesIndex - hoveredIndex = params.seriesIndex + if (!this.selectedIndex) { + this.processStatus = '' } - // 使用更新后的 option,渲染图表 - myChart.setOption(this[optionName]) - } - }) - // 修正取消高亮失败的 bug - myChart.on('globalout', () => { - // 准备重新渲染扇形所需的参数 - let isSelected - let isHovered - let startRatio - let endRatio - let k - if (hoveredIndex !== '') { - // 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。 - isSelected = this[optionName].series[hoveredIndex].pieStatus.selected - isHovered = false - k = this[optionName].series[hoveredIndex].pieStatus.k - startRatio = this[optionName].series[hoveredIndex].pieData.startRatio - endRatio = this[optionName].series[hoveredIndex].pieData.endRatio - // 对当前点击的扇形,执行取消高亮操作(对 option 更新) - this[optionName].series[ - hoveredIndex - ].parametricEquation = getParametricEquation( - startRatio, - endRatio, - isSelected, - isHovered, - k, - this[optionName].series[hoveredIndex].pieData.value - ) - this[optionName].series[hoveredIndex].pieStatus.hovered = isHovered - // 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空 - hoveredIndex = '' + + } else {//点击环形 + dataIndex = params.seriesIndex + this.click3DPie(myChart, 'option', dataIndex) + + + //刷新右侧table + if (this.selectedIndex || this.selectedIndex === 0) { + + if (this.selectedIndex === 0) { + this.processStatus = 'closed_case' + } else if (this.selectedIndex === 1) { + this.processStatus = 'processing' + } + + + } else { + this.processStatus = '' + + } + } - // 使用更新后的 option,渲染图表 - myChart.setOption(this[optionName]) + this.getTable() + }) + // 监听 mouseover,近似实现高亮(放大)效果 + // myChart.on('mouseover', (params) => { + // // 准备重新渲染扇形所需的参数 + // let isSelected + // let isHovered + // let startRatio + // let endRatio + // let k + // // 如果触发 mouseover 的扇形当前已高亮,则不做操作 + // if (hoveredIndex === params.seriesIndex) { + // // 否则进行高亮及必要的取消高亮操作 + // } else { + // // 如果当前有高亮的扇形,取消其高亮状态(对 option 更新) + // if (hoveredIndex !== '') { + // // 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 false。 + // isSelected = this[optionName].series[hoveredIndex].pieStatus.selected + // isHovered = false + // startRatio = this[optionName].series[hoveredIndex].pieData.startRatio + // endRatio = this[optionName].series[hoveredIndex].pieData.endRatio + // k = this[optionName].series[hoveredIndex].pieStatus.k + // // 对当前点击的扇形,执行取消高亮操作(对 option 更新) + // this[optionName].series[ + // hoveredIndex + // ].parametricEquation = getParametricEquation( + // startRatio, + // endRatio, + // isSelected, + // isHovered, + // k, + // this[optionName].series[hoveredIndex].pieData.value + // ) + // this[optionName].series[hoveredIndex].pieStatus.hovered = isHovered + // // 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空 + // hoveredIndex = '' + // } + // // 如果触发 mouseover 的扇形不是透明圆环,将其高亮(对 option 更新) + // if ( + // params.seriesName !== 'mouseoutSeries' && + // params.seriesName !== 'pie2d' + // ) { + // // 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。 + // isSelected = + // this[optionName].series[params.seriesIndex].pieStatus.selected + // isHovered = true + // startRatio = + // this[optionName].series[params.seriesIndex].pieData.startRatio + // endRatio = this[optionName].series[params.seriesIndex].pieData.endRatio + // k = this[optionName].series[params.seriesIndex].pieStatus.k + // // 对当前点击的扇形,执行高亮操作(对 option 更新) + // this[optionName].series[ + // params.seriesIndex + // ].parametricEquation = getParametricEquation( + // startRatio, + // endRatio, + // isSelected, + // isHovered, + // k, + // this[optionName].series[params.seriesIndex].pieData.value + 60 + // ) + // this[optionName].series[ + // params.seriesIndex + // ].pieStatus.hovered = isHovered + // // 记录上次高亮的扇形对应的系列号 seriesIndex + // hoveredIndex = params.seriesIndex + // } + // // 使用更新后的 option,渲染图表 + // myChart.setOption(this[optionName]) + // } + // }) + // // 修正取消高亮失败的 bug + // myChart.on('globalout', () => { + // // 准备重新渲染扇形所需的参数 + // let isSelected + // let isHovered + // let startRatio + // let endRatio + // let k + // if (hoveredIndex !== '') { + // // 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。 + // isSelected = this[optionName].series[hoveredIndex].pieStatus.selected + // isHovered = false + // k = this[optionName].series[hoveredIndex].pieStatus.k + // startRatio = this[optionName].series[hoveredIndex].pieData.startRatio + // endRatio = this[optionName].series[hoveredIndex].pieData.endRatio + // // 对当前点击的扇形,执行取消高亮操作(对 option 更新) + // this[optionName].series[ + // hoveredIndex + // ].parametricEquation = getParametricEquation( + // startRatio, + // endRatio, + // isSelected, + // isHovered, + // k, + // this[optionName].series[hoveredIndex].pieData.value + // ) + // this[optionName].series[hoveredIndex].pieStatus.hovered = isHovered + // // 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空 + // hoveredIndex = '' + // } + // // 使用更新后的 option,渲染图表 + // myChart.setOption(this[optionName]) + // }) + + }, + + click3DPie (myChart, optionName, seriesIndex) { + + // 从 option.series 中读取重新渲染扇形所需的参数,将是否选中取反。 + const isSelected = !this[optionName].series[seriesIndex].pieStatus.selected + const isHovered = this[optionName].series[seriesIndex].pieStatus.hovered + const k = this[optionName].series[seriesIndex].pieStatus.k + + const startRatio = this[optionName].series[seriesIndex].pieData.startRatio + const endRatio = this[optionName].series[seriesIndex].pieData.endRatio + + // 如果之前选中过其他扇形,将其取消选中(对 option 更新) + if (this.selectedIndex !== '' && this.selectedIndex !== null && this.selectedIndex !== seriesIndex) { + this[optionName].series[ + this.selectedIndex + ].parametricEquation = getParametricEquation( + this[optionName].series[this.selectedIndex].pieData.startRatio, + this[optionName].series[this.selectedIndex].pieData.endRatio, + false, + false, + k, + this[optionName].series[this.selectedIndex].pieData.value + ) + this[optionName].series[this.selectedIndex].pieStatus.selected = false + } + // 对当前点击的扇形,执行选中/取消选中操作(对 option 更新) + this[optionName].series[ + seriesIndex + ].parametricEquation = getParametricEquation( + startRatio, + endRatio, + isSelected, + isHovered, + k, + this[optionName].series[seriesIndex].pieData.value + ) + this[optionName].series[seriesIndex].pieStatus.selected = isSelected + + // 如果本次是选中操作,记录上次选中的扇形对应的系列号 seriesIndex + this.selectedIndex = isSelected ? seriesIndex : null + // 使用更新后的 option,渲染图表 + myChart.setOption(this[optionName]) }, handleChangeAgency () {