diff --git a/package-lock.json b/package-lock.json index d154059..1a70def 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "echarts": "^5.4.2", "echarts-gl": "^2.0.9", "element-ui": "^2.15.13", + "highcharts": "^11.1.0", "highcharts-vue": "^1.4.3", "js-cookie": "^3.0.1", "less": "3.9.0", @@ -8511,8 +8512,7 @@ "node_modules/highcharts": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-11.1.0.tgz", - "integrity": "sha512-vhmqq6/frteWMx0GKYWwEFL25g4OYc7+m+9KQJb/notXbNtIb8KVy+ijOF7XAFqF165cq0pdLIePAmyFY5ph3g==", - "peer": true + "integrity": "sha512-vhmqq6/frteWMx0GKYWwEFL25g4OYc7+m+9KQJb/notXbNtIb8KVy+ijOF7XAFqF165cq0pdLIePAmyFY5ph3g==" }, "node_modules/highcharts-vue": { "version": "1.4.3", @@ -22483,8 +22483,7 @@ "highcharts": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-11.1.0.tgz", - "integrity": "sha512-vhmqq6/frteWMx0GKYWwEFL25g4OYc7+m+9KQJb/notXbNtIb8KVy+ijOF7XAFqF165cq0pdLIePAmyFY5ph3g==", - "peer": true + "integrity": "sha512-vhmqq6/frteWMx0GKYWwEFL25g4OYc7+m+9KQJb/notXbNtIb8KVy+ijOF7XAFqF165cq0pdLIePAmyFY5ph3g==" }, "highcharts-vue": { "version": "1.4.3", diff --git a/package.json b/package.json index cc519b8..537e729 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "echarts": "^5.4.2", "echarts-gl": "^2.0.9", "element-ui": "^2.15.13", + "highcharts": "^11.1.0", "highcharts-vue": "^1.4.3", "js-cookie": "^3.0.1", "less": "3.9.0", diff --git a/src/assets/safetyIndex/back001.png b/src/assets/safetyIndex/back001.png new file mode 100644 index 0000000..6f42f36 Binary files /dev/null and b/src/assets/safetyIndex/back001.png differ diff --git a/src/assets/safetyIndex/companyNum01.png b/src/assets/safetyIndex/companyNum01.png new file mode 100644 index 0000000..d5055e9 Binary files /dev/null and b/src/assets/safetyIndex/companyNum01.png differ diff --git a/src/assets/safetyIndex/companyNum02.png b/src/assets/safetyIndex/companyNum02.png new file mode 100644 index 0000000..f4814f0 Binary files /dev/null and b/src/assets/safetyIndex/companyNum02.png differ diff --git a/src/assets/safetyIndex/companyNum03.png b/src/assets/safetyIndex/companyNum03.png new file mode 100644 index 0000000..a7310b9 Binary files /dev/null and b/src/assets/safetyIndex/companyNum03.png differ diff --git a/src/assets/safetyIndex/employee01.png b/src/assets/safetyIndex/employee01.png new file mode 100644 index 0000000..d42dfab Binary files /dev/null and b/src/assets/safetyIndex/employee01.png differ diff --git a/src/main.js b/src/main.js index cfd78e1..0c7fe48 100644 --- a/src/main.js +++ b/src/main.js @@ -2,6 +2,9 @@ import Vue from 'vue' import App from './App.vue' import ElementUI from 'element-ui'; import HighchartsVue from 'highcharts-vue' +import highcharts from 'highcharts' +import highcharts3d from 'highcharts/highcharts-3d' +highcharts3d(highcharts) import 'element-ui/lib/theme-chalk/index.css'; import router from './router' import store from './store' diff --git a/src/utils/request.js b/src/utils/request.js index bbddc92..56dd381 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -7,8 +7,8 @@ const request = axios.create({ //baseURL: 'http://172.18.113.50:8080/zhapi', //baseURL: 'http://172.18.113.13:8080/zhapi', // 孙强 //baseURL: 'http://192.168.0.188:8888/zhapi', - //baseURL: 'http://121.41.91.94:12002/zhapi', - baseURL: `http://${window.location.host}/zhapi`, + baseURL: 'http://121.41.91.94:12002/zhapi', + //baseURL: `http://${window.location.host}/zhapi`, timeout: 50000, headers: { 'content-type': 'application/json' }, }) diff --git a/src/views/compositeIndex/components/chart.js b/src/views/compositeIndex/components/chart.js new file mode 100644 index 0000000..5f1606e --- /dev/null +++ b/src/views/compositeIndex/components/chart.js @@ -0,0 +1,287 @@ +/** + * 绘制3d图 + * @param pieData 总数据 + * @param internalDiameterRatio:透明的空心占比 + * @param distance 视角到主体的距离 + * @param alpha 旋转角度 + * @param pieHeight 立体的高度 + * @param opacity 饼或者环的透明度 + */ +const getPie3D = ( + pieData, + internalDiameterRatio, + distance, + alpha, + pieHeight, + opacity = 1 + ) => { + 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 !== "信用评价" + ) { + // console.log(option.series,params.seriesName,'option.series[params.seriesIndex].pieData'); + 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, // 角度 + 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/compositeIndex/components/companyNum.vue b/src/views/compositeIndex/components/companyNum.vue index 53b6e08..d547a29 100644 --- a/src/views/compositeIndex/components/companyNum.vue +++ b/src/views/compositeIndex/components/companyNum.vue @@ -4,25 +4,25 @@
- +
园区企业
-
+
{{ statisticsAlarmData.safeSum }}
平安企业
-
+
{{ statisticsAlarmData.companySum }}
石化企业
-
+
{{ statisticsAlarmData.alarmSum }}
@@ -83,6 +83,7 @@ export default { getstatisticsDanger() { statisticsDanger().then((res) => { this.statisticsDangerData = res.data; + // all_company_num前四公司的数据 let all_company_num = this.statisticsDangerData .map((item) => item.companyTypeSum) .slice(0, 4); @@ -90,7 +91,7 @@ export default { for (let i = 0; i < all_company_num.length; i++) { sum += all_company_num[i]; } - console.log(sum); + // 算出每个企业的数据占比 for (let i = 0; i < all_company_num.length; i++) { this.proportion_list.push( Math.round((Number(all_company_num[i]) / Number(sum)) * 10000) / @@ -187,7 +188,7 @@ export default { width: 24vw; height: 28vh; // border: 0.1px solid #495e70; - background: url("~@/assets/safetyIndex/homescreen03.png") no-repeat; + background: url("~@/assets/safetyIndex/back001.png") no-repeat; background-size: 100% 100%; /* 盒子标题 */ .title { @@ -211,8 +212,9 @@ export default { } .title_text { width: 4vw; - height: 2.7vh; - line-height: 2.7vh; + height: 3.2vh; + line-height: 3.2vh; + text-align: right; } } .company_num_box_body { @@ -224,13 +226,13 @@ export default { .company_num_box_body_item { width: 6vw; height: 8vh; - background: url("~@/assets/safetyIndex/back002.png") no-repeat; - background-size: 100% 100%; .num_green { width: 6vw; height: 5vh; line-height: 5vh; - color: #32d9ae; + background: linear-gradient(#fff, #00ffd4); + background-clip: text; + color: transparent; font-size: 46px; font-weight: 700; text-align: center; @@ -239,7 +241,9 @@ export default { width: 6vw; height: 5vh; line-height: 5vh; - color: #ff6600; + background: linear-gradient(#fff, #fef699); + background-clip: text; + color: transparent; font-size: 46px; font-weight: 700; text-align: center; @@ -248,7 +252,9 @@ export default { width: 6vw; height: 5vh; line-height: 5vh; - color: #e11e1e; + background: linear-gradient(#fff, #ff4b4b); + background-clip: text; + color: transparent; font-size: 46px; font-weight: 700; text-align: center; @@ -257,11 +263,23 @@ export default { font-size: 14px; width: 6vw; height: 3vh; - line-height: 3vh; - color: #d9e7ff; + // line-height: 3vh; + color: #fff; text-align: center; } } + .green { + background: url("~@/assets/safetyIndex/companyNum01.png") no-repeat; + background-size: 100% 100%; + } + .orange { + background: url("~@/assets/safetyIndex/companyNum02.png") no-repeat; + background-size: 100% 100%; + } + .red { + background: url("~@/assets/safetyIndex/companyNum03.png") no-repeat; + background-size: 100% 100%; + } } .company_danger { margin-top: 1vh; diff --git a/src/views/compositeIndex/components/employee.vue b/src/views/compositeIndex/components/employee.vue new file mode 100644 index 0000000..bbbd99b --- /dev/null +++ b/src/views/compositeIndex/components/employee.vue @@ -0,0 +1,335 @@ + + + + \ No newline at end of file diff --git a/src/views/compositeIndex/index.vue b/src/views/compositeIndex/index.vue index ba3c336..126232f 100644 --- a/src/views/compositeIndex/index.vue +++ b/src/views/compositeIndex/index.vue @@ -3,23 +3,26 @@
- + + +
\ No newline at end of file diff --git a/src/views/head3.vue b/src/views/head3.vue new file mode 100644 index 0000000..b88073b --- /dev/null +++ b/src/views/head3.vue @@ -0,0 +1,489 @@ + + + + + \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 96b8151..83fea92 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4740,7 +4740,7 @@ "resolved" "https://registry.npmjs.org/highcharts-vue/-/highcharts-vue-1.4.3.tgz" "version" "1.4.3" -"highcharts@>=5.0.0": +"highcharts@^11.1.0", "highcharts@>=5.0.0": "integrity" "sha512-vhmqq6/frteWMx0GKYWwEFL25g4OYc7+m+9KQJb/notXbNtIb8KVy+ijOF7XAFqF165cq0pdLIePAmyFY5ph3g==" "resolved" "https://registry.npmjs.org/highcharts/-/highcharts-11.1.0.tgz" "version" "11.1.0"