diff --git a/package.json b/package.json index f646f014c..5e5d0f947 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "babel-eslint": "^8.0.1", "babel-plugin-component": "^1.1.1", "echarts": "^5.2.2", + "echarts-gl": "^2.0.9", "element-theme": "^2.0.1", "element-ui": "^2.13.0", "file-saver": "^2.0.5", diff --git a/src/assets/img/shuju/3d-pid-bg.png b/src/assets/img/shuju/3d-pid-bg.png new file mode 100644 index 000000000..4519b38e8 Binary files /dev/null and b/src/assets/img/shuju/3d-pid-bg.png differ diff --git a/src/assets/scss/modules/visual/search_1.scss b/src/assets/scss/modules/visual/search_1.scss index 55aaef76f..ffb46b67f 100644 --- a/src/assets/scss/modules/visual/search_1.scss +++ b/src/assets/scss/modules/visual/search_1.scss @@ -24,6 +24,7 @@ display: flex; align-items: center; margin-left:40px; + z-index: 10; .second-select { diff --git a/src/assets/scss/modules/visual/shijianchulifenxi.scss b/src/assets/scss/modules/visual/shijianchulifenxi.scss index bd9655728..ca099bed4 100644 --- a/src/assets/scss/modules/visual/shijianchulifenxi.scss +++ b/src/assets/scss/modules/visual/shijianchulifenxi.scss @@ -21,8 +21,8 @@ } .l_bottom { - height: calc(100vh - 200px - 355px); - margin-top: 20px; + height: calc(100vh - 200px - 365px); + margin-top: 0; } } @@ -35,25 +35,7 @@ } .l_bottom { - .bottom_label { - position: relative; - padding-left: 40px; - font-size: 16px; - font-weight: 500; - color: #fff; - } - .bottom_label::after { - content: ''; - position: absolute; - top: 50%; - left: 20px; - width: 12px; - height: 12px; - box-sizing: border-box; - margin-top: -6px; - background: #2865fa; - border-radius: 50%; - } + > span { font-size: 18px; font-family: PingFang SC; @@ -66,6 +48,26 @@ } } +.bottom_label { + position: relative; + padding-left: 40px; + font-size: 16px; + font-weight: 500; + color: #fff; +} +.bottom_label::after { + content: ''; + position: absolute; + top: 50%; + left: 20px; + width: 12px; + height: 12px; + box-sizing: border-box; + margin-top: -6px; + background: #2865fa; + border-radius: 50%; +} + .g-r { .m-tb { diff --git a/src/views/components/resiSearch.vue b/src/views/components/resiSearch.vue index ddbd29fab..78da43f1d 100644 --- a/src/views/components/resiSearch.vue +++ b/src/views/components/resiSearch.vue @@ -173,6 +173,7 @@ size="small" clearable class="resi-cell-select" + :collapse-tags="n.multiSelect == 1 ? true : false" :multiple="n.multiSelect == 1 ? true : false" > { + const series = [] + let sumValue = 0 + let startValue = 0 + let endValue = 0 + let legendData = [] + let legendBfb = [] + const k = 1 - internalDiameterRatio + pieData.sort((a, b) => { + return b.value - a.value + }) + // 为每一个饼图数据,生成一个 series-surface 配置 + for (let i = 0; i < pieData.length; i++) { + sumValue += pieData[i].value + const seriesItem = { + name: + typeof pieData[i].name === 'undefined' + ? `series${i}` + : pieData[i].name, + type: 'surface', + parametric: true, + wireframe: { + show: false + }, + pieData: pieData[i], + pieStatus: { + selected: false, + hovered: false, + k: k + }, + center: ['10%', '50%'] + } + if (typeof pieData[i].itemStyle !== 'undefined') { + const itemStyle = {} + itemStyle.color = + typeof pieData[i].itemStyle.color !== 'undefined' + ? pieData[i].itemStyle.color + : opacity + itemStyle.opacity = + typeof pieData[i].itemStyle.opacity !== 'undefined' + ? pieData[i].itemStyle.opacity + : opacity + seriesItem.itemStyle = itemStyle + } + series.push(seriesItem) + } + + // 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数, + // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。 + legendData = [] + legendBfb = [] + for (let i = 0; i < series.length; i++) { + endValue = startValue + series[i].pieData.value + series[i].pieData.startRatio = startValue / sumValue + series[i].pieData.endRatio = endValue / sumValue + series[i].parametricEquation = getParametricEquation( + series[i].pieData.startRatio, + series[i].pieData.endRatio, + false, + false, + k, + series[i].pieData.value + ) + startValue = endValue + const bfb = fomatFloat(series[i].pieData.value / sumValue, 4) + legendData.push({ + name: series[i].name, + value: bfb + }) + legendBfb.push({ + name: series[i].name, + value: bfb + }) + } + const boxHeight = getHeight3D(series, pieHeight) // 通过pieHeight设定3d饼/环的高度,单位是px + // 准备待返回的配置项,把准备好的 legendData、series 传入。 + const option = { + legend: { + show: false, + data: legendData, + orient: 'vertical', + left: 10, + top: 10, + itemGap: 10, + textStyle: { + color: '#A1E2FF' + }, + icon: 'circle', + formatter: function (param) { + const item = legendBfb.filter(item => item.name === param)[0] + const bfs = fomatFloat(item.value * 100, 2) + '%' + return `${item.name} ${bfs}` + } + }, + labelLine: { + show: true, + lineStyle: { + color: '#fff' + } + }, + label: { + show: true, + position: 'outside', + formatter: '{b} \n{c} {d}%' + }, + tooltip: { + backgroundColor: '#033b77', + borderColor: '#21f2c4', + textStyle: { + color: '#fff', + fontSize: 13 + }, + formatter: params => { + + // if ( + // params.seriesName !== 'mouseoutSeries' && + // params.seriesName !== 'pie2d' + // ) { + // const bfb = ( + // (option.series[params.seriesIndex].pieData.endRatio - + // option.series[params.seriesIndex].pieData.startRatio) * + // 100 + // ).toFixed(2) + // return ( + // `${params.seriesName}
` + + // `` + + // `${bfb}%` + // ) + // } + } + }, + xAxis3D: { + min: -1, + max: 1 + }, + yAxis3D: { + min: -1, + max: 1 + }, + zAxis3D: { + min: -1, + max: 1 + }, + grid3D: { + show: false, + boxHeight: boxHeight, // 圆环的高度 + viewControl: { + // 3d效果可以放大、旋转等,请自己去查看官方配置 + alpha, // 角度 + beta: -40, + distance, // 调整视角到主体的距离,类似调整zoom + rotateSensitivity: 0, // 设置为0无法旋转 + zoomSensitivity: 0, // 设置为0无法缩放 + panSensitivity: 0, // 设置为0无法平移 + autoRotate: false // 自动旋转 + } + }, + series: series + } + return option +} + +/** + * 生成扇形的曲面参数方程,用于 series-surface.parametricEquation + */ +const getParametricEquation = (startRatio, endRatio, isSelected, isHovered, k, h) => { + // 计算 + const midRatio = (startRatio + endRatio) / 2 + const startRadian = startRatio * Math.PI * 2 + const endRadian = endRatio * Math.PI * 2 + const midRadian = midRatio * Math.PI * 2 + // 如果只有一个扇形,则不实现选中效果。 + if (startRatio === 0 && endRatio === 1) { + isSelected = false + } + // 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3) + k = typeof k !== 'undefined' ? k : 1 / 3 + // 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0) + const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0 + const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0 + // 计算高亮效果的放大比例(未高亮,则比例为 1) + const hoverRate = isHovered ? 1.05 : 1 + // 返回曲面参数方程 + return { + u: { + min: -Math.PI, + max: Math.PI * 3, + step: Math.PI / 32 + }, + v: { + min: 0, + max: Math.PI * 2, + step: Math.PI / 20 + }, + x: function (u, v) { + if (u < startRadian) { + return ( + offsetX + + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate + ) + } + if (u > endRadian) { + return ( + offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate + ) + } + return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate + }, + y: function (u, v) { + if (u < startRadian) { + return ( + offsetY + + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate + ) + } + if (u > endRadian) { + return ( + offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate + ) + } + return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate + }, + z: function (u, v) { + if (u < -Math.PI * 0.5) { + return Math.sin(u) + } + if (u > Math.PI * 2.5) { + return Math.sin(u) * h * 0.1 + } + return Math.sin(v) > 0 ? 1 * h * 0.1 : -1 + } + } +} + +/** + * 获取3d丙图的最高扇区的高度 + */ +const getHeight3D = (series, height) => { + series.sort((a, b) => { + return b.pieData.value - a.pieData.value + }) + return (height * 25) / series[0].pieData.value +} + +/** + * 格式化浮点数 + */ +const fomatFloat = (num, n) => { + let f = parseFloat(num) + if (isNaN(f)) { + return false + } + f = Math.round(num * Math.pow(10, n)) / Math.pow(10, n) // n 幂 + let s = f.toString() + let rs = s.indexOf('.') + // 判定如果是整数,增加小数点再补0 + if (rs < 0) { + rs = s.length + s += '.' + } + while (s.length <= rs + n) { + s += '0' + } + return s +} + +export { getPie3D, getParametricEquation } \ No newline at end of file diff --git a/src/views/modules/visual/communityGovern/shijianchuli/lineOption copy.js b/src/views/modules/visual/communityGovern/shijianchuli/lineOption copy.js new file mode 100644 index 000000000..04b4f9503 --- /dev/null +++ b/src/views/modules/visual/communityGovern/shijianchuli/lineOption copy.js @@ -0,0 +1,86 @@ +import * as echarts from 'echarts' +export function lineOption () { + + return { + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross', + label: { + backgroundColor: '#6a7985' + } + } + }, + xAxis: { + type: 'category', + // boundaryGap: false, + axisLabel: { + color: '#8ec7dc', + fontSize: 16 + }, + axisTick: { + show: false + }, + axisLine: { + lineStyle: { + color: '#0c4b59' + } + } + }, + yAxis: { + nameTextStyle: { + color: '#8ec7dc', + fontSize: 18 + }, + splitNumber: 4, + minInterval: 1, + show: true, + type: 'value', + axisLabel: { + color: '#8ec7dc', + fontSize: 18 + }, + axisTick: { + show: false + }, + splitLine: { + lineStyle: { + color: ['#145968'], + type: 'dotted' + } + }, + axisLine: { + show: true, + symbol: ['none', 'arrow'], + symbolOffset: [0, 15], + lineStyle: { + color: '#0c4b59' + } + } + }, + series: [ + { + name: '项目数', + type: 'line', + smooth: true, + barWidth: 15, + areaStyle: {}, + itemStyle: { + color: new echarts.graphic.LinearGradient( + 0, 1, 0, 0, + [ + { offset: 0, color: 'rgba(121, 55, 255, 0)' }, + { offset: 1, color: '#6339FF' } + ] + ) + } + }, + // { + // data: [820, 932, 901, 934, 1290, 1330, 1320], + // type: 'line', + // areaStyle: {} + // } + ] + + } +} diff --git a/src/views/modules/visual/communityGovern/shijianchuli/lineOption.js b/src/views/modules/visual/communityGovern/shijianchuli/lineOption.js index 04b4f9503..d02e4b20b 100644 --- a/src/views/modules/visual/communityGovern/shijianchuli/lineOption.js +++ b/src/views/modules/visual/communityGovern/shijianchuli/lineOption.js @@ -1,4 +1,11 @@ import * as echarts from 'echarts' +let circleList = [ + 'image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAhCAYAAAC4JqlRAAAFdklEQVRYhY1YTY/bRBh+/BHbiRN7l02bqst+st1dVT0gceXABYk7PfYPwIELv4IfABJ3euuBCxKCKxckBEKi2y1F6Xa3abTZT+fLHxnbaMZje+zE3Y70aiLPzPs888w778xEin/8EO9YJKGbVDEkrvhdWdSKBumGehGJReBVdVZyApsPk/roicSdi4aKb4sUEK38jeLEHIdVRQWOnsgLgORCLWsKzFUDqlmHXEvGRzMCMnEx6XmIgpCDRaU6saMnMTYfRpmMQgzIJdCiNTebqHc6kHUbMYkQBT7ikCReFBWypkNSZUS+A/f0FOOjMSdRtlgglikgypwCK8z0FQPWzgYkpQn/8grT3jFmo0ggjMxhrSWjsWqhcXcP9c4Yo5fH8AYugFDQOSVBx8apAqkzRQBXYd1bhnF7G8HVNZznV4hDhZNWuIkEQm4EkhLC3luGtrwEb9DF8MUV+560R7xmpFXMB1kCYu+1obc3MD7qY9qbAagDqHFTKwhQkBnicIbrgyEaqy6am9uQ5Fdwnp8LfaW0FpcgX3NzvcXARy/6cAchB9e5aZxEqhaEWVGiAQCftU97PuJZH617GzBdH5Njh4/JglKdi3i1XkNzbQuTNwO4A8LBjZJpXAWRAOHgnkBOgjtwoZgD5tM/ewripkHJMFMHuQr2fgehTzB+ORVmTUmYAJoAWgAsAHbJLN7W5H1z1agv6pP6LgZvYRdIkGsKVLOD64Mel1njM6fOGtxxg33rfLwNe3+DjXYOX+H0t64we0nYasnSjLrnWLq/CrnWZ3mDkygSsHdtRLMA/iXhYJqgQELAuvc+9r98BOPWeqbdnU+Ajc+PcfjdDxi+eC2Akywu/MsJ800xrp6epQTkwi5QmzYCZ8yJqYIKCYn6nTYefP1FATwt9Btto31y+TVh16jMN8UQMOWCAnKtgeDaK+SCnISGDx59CrW5PAeeLWhzmfVJ+xe3rMx8yzVTPE+KQSgpOmbD2cKMyBLTzoNK8LQkfcRkJWdKU9+SoolBKJeGS4gjlLZmbkrdupGA0rAqx+e+s1ImEPNVKR+riYX+6EYCoTeqHJ/7XkggRhwGqFk1IYqjQo4fdZ/dSGDUPRTyfij4iZlviiGQSAkkDKPZFJplCMBEyHABuo9/BZlWq0Dbuo9/yfrn4xMi1DfFEC4ossAmBpk4qC01CwdLnts9TE5Ocfjt9wicwRx44CRttE+SkHw+dpaRoL4phoCpZuDURl0HKx9tQVuiW6ac25MMd/l3F79/9Q1WP7uP1vY6l/0YvZ8PEIf07J9yc/nYRAnqU9F1XP/jiAoUCZApAZkO0Npq4+KvMz5YFRJWcuzSdXz90x8A/uTjIz5TnwOnBHIVWlu3mG+KUVoCCCQiOAd9KA0d5pohKJA6pVmSxsCQngAlG/K28ZwC1JfSMJjv/EaEVAFxq0QgLoHbfwlzfQdk2oN/4S3I7W+7D/gF01ckmOsduP3/mO/SJbW4BKkjGguKfgJ7fw3Df9/AO/OEwAxuvBGlshu3FFi7dxFcnjCf+bYsxEB6RUovCSGrr58NYO9FsHY3ob93Aee5w52rhQuHuHzi1rX3bOjtFfjnR/w6Fop3wXRceikt3/9TABX1TgOt7Q12unnnV5icjBB65fhJlkExAHOtBaO9zOQfdV/BPZ1yUlFJgUgkAIFA+V2QkLF2LRjt25BVC2HgI/LpuyCZiaTIkHUdiqYjIkP4F2dcsaiUDefeBSKBRQeIPFerpgJz3YRq1NlDhAlJIhDPxeR4AjKZm2U58BblgfTNFvPnWeHqLMQHQCYSnGd+xeM0fwNWAGbPMv42rHqelx+gVa/lcnnba1gkl5Wq53m587v8NyCOXfR7vgD4H8khvGFl000HAAAAAElFTkSuQmCC', + 'image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAhCAYAAAC4JqlRAAAFb0lEQVRYhY1YW28bRRT+ZtbrS24mjVu3btPUDoiqFIEQ4gUh8dKX8hf4A/wT+Am88cA7b5GgrxVPFIREL0rapHHbOHGcxM7Fa3u9c9BMZrZn1+umI43W2j2Xb75z5pwZi89/JLznEExMTFGhKb+njtyUD+KCZxaILOfTnvGIAfj3z5/hmjGcnpjyLosBPtPvtB+yfsxIMBCuQWY4komnD09eRVHMoISc1R9jTH0EahcDhIisM5V6mhmugfz75t35qlgOyJTTxJQ3MCcqqIo8yhRBIcQQCmOrmYOPgvAgaYQedbCnXuPUgkhPYsBiBjjNzrGnp1hEUd7CCiTmqIsjtYsmnRllyfSMQTELKa5iQVTxsXcZp6qJJh0gAAwrbjgQWpc4gLTznKxjUSyhgR660Qu8hDLv8w5cCkBEZ4joBU4h0fNWsSjr+IQWsKm2cDQlYQ2AdJKdO2+gIi5hhV6jpXYRAijpHLIzlwXAZAMQ6gBFGziWVxGIG2hIgW21iQ6TFe7JGYhjLmuY187VS7SoYwxr5wU78xaEZ+VhaY2Mc2AEYKi/q10MxRgtHUI5wFDtoGd14qTMpTNeFOHLGupqD23qmBVp58XUzFsWOICxdT5g4AR1EFAJbW2TDvGYBnFSCs5AzIJcRZVGGKtX6AOYsasu2d8lxoafAhDalfPwmOTUtsQi5rXt6DFe8zqSTEIfnphBNdrAG+sgb1fuAMzaZ7FxG40rNaxo5fYOtjefYZOtXrCtZkKjmuh4H+E6fLQQGrbEBACvjjKFGFHXCMxaAJyB2cvXcOPre/h+dgE33SpW7wCffoXmnw/w637LrJBYWExeUBdn2rb2Ea1j3wGQiV0wgzKdmAKSs9PnIOY/QOXb7/ADd+7G3AJu6m9ahoUpz3ZNztieQZn7lJwB4WOGjg2NcS1gIPJffoN7+SIW087d0N+0jJNPbVmpbQvfMCs4A2+TUKKAU0PZREXUhipV3J3m3A0rk2N6MmZa25YGWJyEMqUvSLGkTE0/j4WLAPgFI5Opz2zHIw2AbFDSbfW8k4U4uQhAODIymfrMdiYAgsIIcyZuxDpY5MrsYRtPLwJw2MYzm/1OT8UNSNtWplglWnC8YhqjL+bNvlestrsKN3r0EA/sCqeu/tFD/OHkmb4Bom1rH/yAIhkaQh89MY+5RGN5W9sH3QPsPfwdPwd9tNPOg/75Ny1jC9LQ6oYOhLHdN/0g0Q1jBlQTPe8u6qIMSb2J2m4q3M42Nn/7BT/d/gx3KtXzetDZQ/PZv3hCyvT+vp2B1TVMaJsij0K0HgMwIBIAKMCYBmjLZVSinqlWI9Z0XHmNSGH09B/8BeBvq897QcAAxCzIZVzWtrWPLAAOhFIbaMm7qMgaimrHKPNEdeV1eEE3HHAGtC1RRDH6D+vsRAQHgG8VRQOMqY0tUcOHIsAbOjJG0rX9XeeBIZ9iEULUUFVtPNe2kTqkJkLgDOlckHm8kqtYVlvYoQMDImKrfPeJyNIuluDJOmrUxSttk23LRAjcEckdErSQUM/Rlg0or45bqowDtWkMhLy2pw+lfOvKBsryEpbUIV7a45irC/GJOM2AYB+MoFakE/TlMla8L1CmQxypFk4MuZNVVOn+J6+Z45xuWMNoG09o3yTkGMnjOTJ3AYvn252xj9NoH09lHQtiCVdyVdwifScYYYjIynqmxRSEjwKNcUxdbKkXhjGVqoYqlXMTu4BnO88LqbZwiC10RQmeuI5ZUUAJecvCGIqOEag3OKMgEefM21F6F5hh72xkr2eJozPLD1AAQc9NELIup9x4VkOCu5ZN3A3dC+6MGZt2W06Pd92G3QITY9r1PEHTe/43wHWzfk8OAP8D28XBfaJJ48oAAAAASUVORK5CYII=' +] +let className = ['1号停车场', '2号停车场', '3号停车场', '4号停车场', '5号停车场', '6号停车场', '7号停车场'] +let serviceCount = [50, 28, 17, 38, 90, 73, 39] + export function lineOption () { return { @@ -11,6 +18,13 @@ export function lineOption () { } } }, + // grid: { + // left: '5%', + // right: '5%', + // bottom: '5%', + // top: '10%', + // containLabel: true + // }, xAxis: { type: 'category', // boundaryGap: false, @@ -25,7 +39,8 @@ export function lineOption () { lineStyle: { color: '#0c4b59' } - } + }, + // data: className }, yAxis: { nameTextStyle: { @@ -58,29 +73,82 @@ export function lineOption () { } } }, + // series: [ + // { + // name: '项目数', + // type: 'line', + // smooth: true, + // barWidth: 15, + // areaStyle: {}, + // itemStyle: { + // color: new echarts.graphic.LinearGradient( + // 0, 1, 0, 0, + // [ + // { offset: 0, color: 'rgba(121, 55, 255, 0)' }, + // { offset: 1, color: '#6339FF' } + // ] + // ) + // } + // }, + // // { + // // data: [820, 932, 901, 934, 1290, 1330, 1320], + // // type: 'line', + // // areaStyle: {} + // // } + // ] series: [ { - name: '项目数', - type: 'line', - smooth: true, - barWidth: 15, - areaStyle: {}, - itemStyle: { - color: new echarts.graphic.LinearGradient( - 0, 1, 0, 0, - [ - { offset: 0, color: 'rgba(121, 55, 255, 0)' }, - { offset: 1, color: '#6339FF' } - ] - ) - } + name: '', + type: 'bar', + zlevel: 1, + itemStyle: { + + normal: { + barBorderRadius: 0, + color: function (params) { + // 大于等于50%的是黄色 反之为蓝色 + var colorList = [ + ['rgba(252, 210, 152, .2)', 'rgba(252, 210, 152, 1)'], + ['rgba(36, 253, 231, .2)', 'rgba(36, 253, 231, 1)'], + ]; + var colorItem + + colorItem = colorList[1]; + + // 设置线条渐变色 + return new echarts.graphic.LinearGradient(0, 1, 0, 0, [{ + offset: 0, + color: colorItem[0] + }, + { + offset: 1, + color: colorItem[1] + } + ], false); + } + + }, + }, + barWidth: 4, + // data: serviceCount + }, + + { + name: 'XXX', + type: 'pictorialBar', + symbol: function (params, value) { + // 设置图片 + + return circleList[1] }, - // { - // data: [820, 932, 901, 934, 1290, 1330, 1320], - // type: 'line', - // areaStyle: {} - // } + symbolPosition: 'end', + symbolSize: [30, 30], + symbolOffset: [0, -12], + z: 20, + // data: serviceCount + } ] + } } diff --git a/src/views/modules/visual/communityGovern/shijianchuli/pieOption copy.js b/src/views/modules/visual/communityGovern/shijianchuli/pieOption copy.js new file mode 100644 index 000000000..5eb83badb --- /dev/null +++ b/src/views/modules/visual/communityGovern/shijianchuli/pieOption copy.js @@ -0,0 +1,183 @@ + +export function pieOption (_charts) { +const center= ['50%', '170px'] + return { + title: { + text: '0', + top: 140, + left: 'center', + textStyle: { + width: '100%', + fontSize: 32, + color: '#FFFFFF', + fontWeight: 400 + }, + itemGap: 5, + subtext: '总数', + subtextStyle: { + fontSize: 20, + color: '#fff', + fontWeight: 400 + } + }, + tooltip: { + show: false + }, + // legend: { + // top: 350, + // bottom: 0, + // itemWidth: 20, + // itemHeight: 10, + // textStyle: { + // color: '#D2E7FF', + // fontSize: 16, + // lineHeight: 20, + // }, + + // }, + series: [ + // 外侧圆环 + { + type: 'pie', + // 起始刻度的角度,默认为 90 度,即圆心的正上方。0 度为圆心的正右方。 + startAngle: 0, + hoverAnimation: false, + // tooltip: { + // }, + center: center, + radius: ['58%', '58.3%'], + label: { + normal: { + show: false + } + }, + labelLine: { + normal: { + show: false + } + }, + data: [{ + value: 360, + itemStyle: { + normal: { + color: 'rgba(40, 101, 250, 0)', + width:0, + borderColor: 'rgba(40, 101, 250, 0.5)', + borderWidth: 1, + borderType: 'dotted' + } + } + } + ] + }, + + // 突出的 + { + hoverAnimation: false, + // name: 'Access From', + type: 'pie', + center: center, + radius: ['35%', '48%'], + avoidLabelOverlap: false, + // top: top + '%', + // height: '80%', + selectedMode: 'single', + left: 'center', + width: 400, + label: { + // show: false, + position: 'outside', + alignTo: 'edge', + // formatter: '{a|{c}}\n\n{name|{b}}', + formatter: '{a|{c}%}\n{r|}\n{name|{b}}', + minMargin: 5, + edgeDistance: 1, + lineHeight: 15, + color: '#fff', + fontSize: 12, + // distanceToLabelLine: -60, + rich: { + name: { + padding: [0, 6, 0, 6] + }, + a: { + fontSize: 30, + color: '#fff', + padding: [0, 6, 6, 6] + }, + r: { + backgroundColor: 'auto', + borderRadius: 6, + width: 6, + height: 6, + // padding: [3, 3, 0, -12] + } + } + }, + labelLine: { + show: false, + smooth: 0.2, + length: 30, + length2: 0, + maxSurfaceAngle: 80 + }, + labelLayout: function (params) { + + const isLeft = params.labelRect.x < _charts.getWidth() / 2; + const points = params.labelLinePoints; + // Update the end point. + if (points) { + points[2][0] = isLeft + ? params.labelRect.x + : params.labelRect.x + params.labelRect.width; + } + + return { + labelLinePoints: points + }; + }, + itemStyle: { + color:function(params) { + //自定义颜色 + var colorList = [ '#FAC126', '#3DDA83']; + return colorList[params.dataIndex] + } + }, + data: [], + + }, + // 中间圆环 + { + type: 'pie', + // 起始刻度的角度,默认为 90 度,即圆心的正上方。0 度为圆心的正右方。 + startAngle: 0, + hoverAnimation: false, + center: center, + // tooltip: { + // }, + radius: ['0%', '25%'], + label: { + + show: false + + }, + labelLine: { + + show: false + + }, + data: [{ + value: 360, + itemStyle: { + normal: { + color: 'rgba(8, 37, 134, 1)', + + } + } + } + ] + }, + ] + + } +} diff --git a/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi copy 2.vue b/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi copy 2.vue new file mode 100644 index 000000000..8ec4d06f2 --- /dev/null +++ b/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi copy 2.vue @@ -0,0 +1,328 @@ + + + + + \ No newline at end of file diff --git a/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi copy.vue b/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi copy.vue new file mode 100644 index 000000000..301a60a96 --- /dev/null +++ b/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi copy.vue @@ -0,0 +1,740 @@ + + + + + + + + diff --git a/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi.vue b/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi.vue index 301a60a96..c3a5c819b 100644 --- a/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi.vue +++ b/src/views/modules/visual/communityGovern/shijianchuli/shijianchulifenxi.vue @@ -23,7 +23,7 @@ :key="item.value" :label="item.label" :value="item.value" - @click.native="handleChangeDate(item.value)"> + @click.native="handleChangeDate(item.value,true)">
@@ -47,26 +47,32 @@
+
事件总览
- +
+ + +
+
-
+ +
-
+
-->
{ + + item.itemStyle = { + color: color[index] + } + item.label = { + normal: { + show: true, + 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 = { + normal: { + length: 30, + length2: 80, + lineStyle: { + 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 + }; + } + }) + }, + + // 图表初始化 + initChart () { + this.$nextTick(() => { + // 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.statusChart.setOption(this.option) + // 是否需要label指引线,如果要就添加一个透明的2d饼状图并调整角度使得labelLine和3d的饼状图对齐,并再次setOption + this.option.series.push({ + name: '', //自己根据场景修改 + backgroundColor: 'transparent', + type: 'pie', + label: { + opacity: 1, + fontSize: 13, + lineHeight: 20 + }, + startAngle: 40, // 起始角度,支持范围[0, 360]。 + clockwise: false, // 饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式 + radius: ['30%', '35%'], + center: ['50%', '50%'], + data: this.optionData, + itemStyle: { + opacity: 0 //这里必须是0,不然2d的图会覆盖在表面 + } + }) + this.statusChart.setOption(this.option) + this.bindListen(this.statusChart) + }) + + }, + // 监听鼠标事件,实现饼图选中效果(单选),近似实现高亮(放大)效果。 + // optionName是防止有多个图表进行定向option传递,单个图表可以不传,默认是opiton + bindListen (myChart, optionName = 'option') { + 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 = '' + } + // 如果触发 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]) + }) + + }, + handleChangeAgency () { let obj = this.$refs["myCascader"].getCheckedNodes()[0].data if (obj) { @@ -719,7 +994,7 @@ export default { this.userId = id; }, userId () { - // this.getApiData(); + window.scrollTo(0, 0); }, }, @@ -737,4 +1012,33 @@ export default { scoped > + + diff --git a/src/views/modules/visual/cpts/tb.vue b/src/views/modules/visual/cpts/tb.vue index 317f438f0..8b77155dd 100644 --- a/src/views/modules/visual/cpts/tb.vue +++ b/src/views/modules/visual/cpts/tb.vue @@ -1,68 +1,66 @@