diff --git a/public/index.html b/public/index.html index e17bc69..4913f31 100644 --- a/public/index.html +++ b/public/index.html @@ -9,8 +9,6 @@ <title> <%= htmlWebpackPlugin.options.title %> </title> - <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script> - <script src="https://cdn.bootcdn.net/ajax/libs/bootstrap/4.5.2/js/bootstrap.min.js"></script> </head> <body> diff --git a/src/assets/客户侧总体用能情况分析/logo.png b/src/assets/客户侧总体用能情况分析/logo.png new file mode 100644 index 0000000..e4660e6 Binary files /dev/null and b/src/assets/客户侧总体用能情况分析/logo.png differ diff --git a/src/views/KHC.vue b/src/views/KHC.vue index ac6207c..92e8286 100644 --- a/src/views/KHC.vue +++ b/src/views/KHC.vue @@ -1,7 +1,7 @@ <template> <div class="box"> <div class="title"> - <img src="../assets/客户侧总体用能情况分析/图层 2.png" alt="" /> + <img src="../assets/客户侧总体用能情况分析/logo.png" alt="" /> <p>客户侧总体用能情况分析</p> <img src="../assets/客户侧总体用能情况分析/反白稿.png" alt="" /> </div> @@ -551,30 +551,63 @@ export default { }, //用能分类占比 initYnflzb() { - let getParametricEquation = function ( + let optionData = [ + { + name: "楼宇", + value: 60, + itemStyle: { + color: "#37FFC9", + }, + }, + { + name: "工业", + value: 44, + itemStyle: { + color: "#31A1FF", + }, + }, + { + name: "其他", + value: 32, + itemStyle: { + color: "#FFF777", + }, + }, + ]; + let option = getPie3D(optionData, 0.59); + // 生成扇形的曲面参数方程 + function getParametricEquation( startRatio, endRatio, isSelected, isHovered, k, - height + h ) { // 计算 - let midRatio = (startRatio + endRatio) / 2; - let startRadian = startRatio * Math.PI * 2; - let endRadian = endRatio * Math.PI * 2; - let midRadian = midRatio * Math.PI * 2; + 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) { + // eslint-disable-next-line no-param-reassign isSelected = false; } + // 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3) + // eslint-disable-next-line no-param-reassign k = typeof k !== "undefined" ? k : 1 / 3; + // 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0) - let offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0; - let offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0; + const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0; + const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0; + // 计算高亮效果的放大比例(未高亮,则比例为 1) - let hoverRate = isHovered ? 1.05 : 1; + const hoverRate = isHovered ? 1.05 : 1; + // 返回曲面参数方程 return { u: { @@ -582,12 +615,14 @@ export default { max: Math.PI * 3, step: Math.PI / 32, }, + v: { min: 0, max: Math.PI * 2, step: Math.PI / 20, }, - x: function (u, v) { + + x(u, v) { if (u < startRadian) { return ( offsetX + @@ -603,7 +638,7 @@ export default { return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate; }, - y: function (u, v) { + y(u, v) { if (u < startRadian) { return ( offsetY + @@ -619,34 +654,36 @@ export default { return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate; }, - z: function (u, v) { + z(u, v) { if (u < -Math.PI * 0.5) { return Math.sin(u); } if (u > Math.PI * 2.5) { - return Math.sin(u); + return Math.sin(u) * h * 0.1; } - return Math.sin(v) > 0 ? 1 * height : -1; + // 当前图形的高度是Z根据h(每个value的值决定的) + return Math.sin(v) > 0 ? 1 * h * 0.1 : -1; }, }; - }; + } // 生成模拟 3D 饼图的配置项 - let getPie3D = function (pieData, internalDiameterRatio) { - let series = []; + function getPie3D(pieData, internalDiameterRatio) { + const series = []; + // 总和 let sumValue = 0; let startValue = 0; let endValue = 0; - let legendData = []; - let k = + const legendData = []; + const k = typeof internalDiameterRatio !== "undefined" ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio) : 1 / 3; // 为每一个饼图数据,生成一个 series-surface 配置 - for (let i = 0; i < pieData.length; i++) { + for (let i = 0; i < pieData.length; i += 1) { sumValue += pieData[i].value; - let seriesItem = { + const seriesItem = { name: typeof pieData[i].name === "undefined" ? `series${i}` @@ -660,17 +697,19 @@ export default { pieStatus: { selected: false, hovered: false, - k: k, + k, }, }; - if (typeof pieData[i].itemStyle != "undefined") { - let itemStyle = {}; + if (typeof pieData[i].itemStyle !== "undefined") { + const { itemStyle } = pieData[i]; - typeof pieData[i].itemStyle.color != "undefined" + // eslint-disable-next-line no-unused-expressions + typeof pieData[i].itemStyle.color !== "undefined" ? (itemStyle.color = pieData[i].itemStyle.color) : null; - typeof pieData[i].itemStyle.opacity != "undefined" + // eslint-disable-next-line no-unused-expressions + typeof pieData[i].itemStyle.opacity !== "undefined" ? (itemStyle.opacity = pieData[i].itemStyle.opacity) : null; @@ -678,12 +717,11 @@ export default { } series.push(seriesItem); } - // 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数, // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。 - for (let i = 0; i < series.length; i++) { + for (let i = 0; i < series.length; i += 1) { endValue = startValue + series[i].pieData.value; - console.log(series[i]); + series[i].pieData.startRatio = startValue / sumValue; series[i].pieData.endRatio = endValue / sumValue; series[i].parametricEquation = getParametricEquation( @@ -692,189 +730,107 @@ export default { false, false, k, - series[i].pieData.value + // 我这里做了一个处理,使除了第一个之外的值都是10 + series[i].pieData.value === series[0].pieData.value ? 35 : 10 ); startValue = endValue; legendData.push(series[i].name); } - return series; - }; - // 传入数据生成 option - const optionsData = [ - { - name: "楼宇", - value: 4256, - itemStyle: { - // opacity: 0.5, - color: "#2A71FF", - }, - }, - { - name: "工业", - value: 2356, - itemStyle: { - // opacity: 0.5, - color: "#00EDFE", + // 准备待返回的配置项,把准备好的 legendData、series 传入。 + const option = { + // animation: false, + legend: { + left: "80%", + top: "40%", + data: ["楼宇", "工业", "其他"], + orient: "vertical", + icon: "roundRect", + itemWidth: 10, // 图标宽度 + itemHeight: 10, // 图标高度 + textStyle: { + fontSize: "0.06rem", + fontFamily: "AlibabaPuHuiTi", + fontWeight: 400, + color: "rgba(255,255,255,0.8)", + }, + formatter: (name) => { + if (optionData.length) { + const item = optionData.filter((item) => item.name === name)[0]; + return ` ${name} ${item.value}%`; + } + }, }, - }, - { - name: "其他", - value: 2018, - itemStyle: { - // opacity: 0.5, - color: "#FEDB4B", - }, - }, - ]; - const series = getPie3D(optionsData, 0.8, 240, 28, 26, 0.5); - series.push({ - name: "pie2d", - type: "pie", - - label: { - show: false, - opacity: 1, - fontSize: "0.07rem", - lineHeight: 20, - textStyle: { - fontSize: "0.07rem", - color: "#fff", - }, - }, - labelLine: { - length: 30, - length2: 30, - }, - startAngle: -30, //起始角度,支持范围[0, 360]。 - clockwise: false, //饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式 - radius: ["40%", "60%"], - // center: ["30%", "50%"], - center: ["40%", "50%"], - data: optionsData, - itemStyle: { - opacity: 0, - }, - }); - let data = [ - { - name: "楼宇", - value: "30%", - }, - { - name: "工业", - value: "30%", - }, - { - name: "其他", - value: "40%", - }, - ]; - // 准备待返回的配置项,把准备好的 legendData、series 传入。 - let option = { - legend: { - show: true, tooltip: { + formatter: (params) => { + if (params.seriesName !== "mouseoutSeries") { + return `${ + params.seriesName + }<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${ + params.color + };"></span>${option.series[params.seriesIndex].pieData.value}`; + } + return ""; + }, + }, + xAxis3D: { + min: -1, + max: 1, + }, + yAxis3D: { + min: -1, + max: 1, + }, + zAxis3D: { + min: -1, + max: 1, + }, + grid3D: { show: false, + boxHeight: 10, + top: "0%", + viewControl: { + // 3d效果可以放大、旋转等,请自己去查看官方配置 + alpha: 20, + beta: 30, + autoRotate: false, // 禁用自动旋转 + distance: 200, // 初始视角距离主体的距离 + panMouseButton: "none", // 设置中键拖拽进行平移 + rotateMouseButton: "none", // 设置右键拖拽进行旋转 + zoomMouseButton: "none", // 禁用鼠标缩放 + }, + // 后处理特效可以为画面添加高光、景深、环境光遮蔽(SSAO)、调色等效果。可以让整个画面更富有质感。 + postEffect: { + // 配置这项会出现锯齿,请自己去查看官方配置有办法解决 + enable: false, + bloom: { + enable: true, + bloomIntensity: 0.1, + }, + SSAO: { + enable: true, + quality: "medium", + radius: 2, + }, + // temporalSuperSampling: { + // enable: true, + // }, + }, }, - orient: "vertical", - data: data, - top: "center", - itemGap: 14, - itemHeight: 8, - itemWidth: 17, - right: "2%", - textStyle: { - color: "#fff", - fontSize: "0.06rem", - }, - formatter: function (name) { - let res = data.filter((v) => v.name === name); - res = res[0] || {}; - let unit = res.unit || ""; - return name + " " + res.value + unit; - }, - }, - animation: false, - tooltip: { - show: false, - formatter: (params) => { - if ( - params.seriesName !== "mouseoutSeries" && - params.seriesName !== "pie2d" - ) { - return `${ - params.seriesName - }<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${ - params.color - };"></span>${ - option.series[params.seriesIndex].pieData.value + "%" - }`; - } - }, - textStyle: { - fontSize: "0.07rem", - }, - }, - title: { - x: "center", - top: "20", - textStyle: { - color: "#fff", - fontSize: "0.11rem", - }, - }, - // backgroundColor: "#0E3567", - labelLine: { - show: false, - lineStyle: { - color: "#7BC0CB", - }, - normal: { - show: true, - length: 10, - length2: 10, - }, - }, - label: { - show: false, - // position: "outside", - // formatter: "{b} \n{d}%", - // textStyle: { - // color: "#fff", - // fontSize: "14px", - // }, - }, - xAxis3D: { - min: -1, - max: 1, - }, - yAxis3D: { - min: -1, - max: 1, - }, - zAxis3D: { - min: -1, - max: 1, - }, - grid3D: { - show: false, - boxHeight: 0.01, - //top: '30%', - bottom: "500%", - left: "-7%", - // environment: "rgba(255,255,255,0)", - viewControl: { - distance: 180, - alpha: 25, - beta: 60, - }, - }, - series: series, - }; - this.defineEcharts("ynflzb", option); + series, + }; + return option; + } + let chartDom = document.getElementById("ynflzb"); + var myChart = this.$echarts.init(chartDom, null, { + devicePixelRatio: 10, // 设置为2或更高的值 + }); + myChart.setOption(option); + window.addEventListener("resize", function () { + myChart.resize(); + }); }, //地图 initMap() { @@ -1582,14 +1538,16 @@ export default { #ynflzb { width: 100%; height: 100%; + padding-right: 40px; + box-sizing: border-box; } .pic { - width: 300px; + width: 250px; position: absolute; - height: 150px; - top: 100px; - left: 40px; + height: 120px; + top: 120px; + left: 70px; } }