right.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. <template>
  2. <div>
  3. <CusModule title="告警信息">
  4. <BaseChart height="200px" width="100%" :option="pieOptions" />
  5. <div class="custom-table">
  6. <el-table :data="tableData" class="customer-table" style="width: 100%" height="650">
  7. <el-table-column type="index" label="序号" width="60" align="center" />
  8. <el-table-column prop="type" label="报警类型" align="center">
  9. <template #default="{ row }">
  10. <el-tag v-if="row.type == '预警'" type="info">预警</el-tag>
  11. <el-tag v-else-if="row.type == '一般'">一般</el-tag>
  12. <el-tag v-else-if="row.type == '严重'" type="warning">严重</el-tag>
  13. <el-tag v-else-if="row.type == '紧急'" type="danger">紧急</el-tag>
  14. </template>
  15. </el-table-column>
  16. <el-table-column prop="content" label="报警内容" align="center" />
  17. <el-table-column prop="time" label="处理时间" align="center" />
  18. </el-table>
  19. <el-pagination :current-page="page.pageIndex" :page-size="100" :small="'small'" :background="true"
  20. layout="total, prev, pager, next, jumper" :total="400" @size-change="handleSizeChange"
  21. @current-change="handleCurrentChange" />
  22. </div>
  23. </CusModule>
  24. </div>
  25. </template>
  26. <script>
  27. import CusModule from '../components/CusModule.vue';
  28. import BaseChart from '@/components/BaseChart/index.vue'
  29. import {mapState} from 'vuex';
  30. export default {
  31. name: 'DeviceRight',
  32. data () {
  33. return {
  34. pieData: [],
  35. tableData: [
  36. {
  37. code: "12321",
  38. time: "2023/02/23 12:02",
  39. content: "变压器报警",
  40. type: "紧急",
  41. },
  42. {
  43. code: "12321",
  44. time: "2023/02/23 12:02",
  45. content: "电梯报警",
  46. type: "严重",
  47. },
  48. {
  49. code: "12321",
  50. time: "2023/02/23 12:02",
  51. content: "路灯报警",
  52. type: "一般",
  53. },
  54. {
  55. code: "12321",
  56. time: "2023/02/23 12:02",
  57. content: "空调报警",
  58. type: "一般",
  59. },
  60. {
  61. code: "12321",
  62. time: "2023/02/23 12:02",
  63. content: "变压器报警",
  64. type: "一般",
  65. },
  66. {
  67. code: "12321",
  68. time: "2023/02/23 12:02",
  69. content: "变压器报警",
  70. type: "预警",
  71. },
  72. {
  73. code: "12321",
  74. time: "2023/02/23 12:02",
  75. content: "变压器报警",
  76. type: "预警",
  77. },
  78. {
  79. code: "12321",
  80. time: "2023/02/23 12:02",
  81. content: "变压器报警",
  82. type: "预警",
  83. },
  84. {
  85. code: "12321",
  86. time: "2023/02/23 12:02",
  87. content: "变压器报警",
  88. type: "预警",
  89. },
  90. {
  91. code: "12321",
  92. time: "2023/02/23 12:02",
  93. content: "变压器报警",
  94. type: "预警",
  95. },
  96. ],
  97. page: {
  98. pageIndex: 1,
  99. pageNun: 10
  100. }
  101. }
  102. },
  103. components: {
  104. CusModule,
  105. BaseChart,
  106. },
  107. computed: {
  108. ...mapState('userState', ['areaType']),
  109. pieOptions () {
  110. return this.getPie3D(this.pieData, 0)// 可做为调整内环大小 0为实心圆饼图,大于0 小于1 为圆环
  111. }
  112. },
  113. watch: {
  114. areaType () {
  115. this.getPieData()
  116. }
  117. },
  118. mounted () {
  119. this.getPieData()
  120. },
  121. methods: {
  122. handleSizeChange () {
  123. },
  124. handleCurrentChange () {
  125. },
  126. getPieData () {
  127. const pieData = [
  128. {
  129. name: '紧急',
  130. value: Math.floor(Math.random() * 100),
  131. itemStyle: {
  132. color: '#FF4949'
  133. },
  134. },
  135. {
  136. name: '严重',
  137. value: Math.floor(Math.random() * 100),
  138. itemStyle: {
  139. color: '#FFBD1F'
  140. },
  141. },
  142. {
  143. name: '一般',
  144. value: Math.floor(Math.random() * 100),
  145. itemStyle: {
  146. color: '#1990FF'
  147. },
  148. },
  149. {
  150. name: '预警',
  151. value: Math.floor(Math.random() * 100),
  152. itemStyle: {
  153. color: '#A1A2A7'
  154. },
  155. }]
  156. let totalValue = pieData.reduce((acc, cur) => acc + cur.value, 0);
  157. this.pieData = pieData.map(item => ({
  158. ...item,
  159. proportion: ((item.value / totalValue) * 100).toFixed(2)
  160. }))
  161. },
  162. getParametricEquation (startRatio, endRatio, isSelected, isHovered, k, h) {
  163. const midRatio = (startRatio + endRatio) / 2;
  164. const startRadian = startRatio * Math.PI * 2;
  165. const endRadian = endRatio * Math.PI * 2;
  166. const midRadian = midRatio * Math.PI * 2;
  167. // 如果只有一个扇形,则不实现选中效果。
  168. if (startRatio === 0 && endRatio === 1) {
  169. isSelected = false;
  170. }
  171. k = typeof k !== 'undefined' ? k : 1 / 3;
  172. const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
  173. const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
  174. // 鼠标滑过时外环放大大小
  175. const hoverRate = isHovered ? 1.05 : 1;
  176. // 返回曲面参数方程
  177. return {
  178. u: {
  179. min: -Math.PI,
  180. max: Math.PI * 3,
  181. step: Math.PI / 32,
  182. },
  183. v: {
  184. min: 0,
  185. max: Math.PI * 2,
  186. step: Math.PI / 20,
  187. },
  188. x (u, v) {
  189. if (u < startRadian) {
  190. return offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
  191. }
  192. if (u > endRadian) {
  193. return offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
  194. }
  195. return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
  196. },
  197. y (u, v) {
  198. if (u < startRadian) {
  199. return offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
  200. }
  201. if (u > endRadian) {
  202. return offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
  203. }
  204. return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
  205. },
  206. z (u, v) {
  207. if (u < -Math.PI * 0.5) {
  208. return Math.sin(u);
  209. }
  210. if (u > Math.PI * 2.5) {
  211. return Math.sin(u) * h * 0.1;
  212. }
  213. // 当前图形的高度是Z根据h(每个value的值决定的)
  214. return Math.sin(v) > 0 ? 1 * h * 0.1 : -1;
  215. },
  216. };
  217. },
  218. getPie3D (pieData, internalDiameterRatio) {
  219. const series = [];
  220. let sumValue = 0;
  221. let startValue = 0;
  222. let endValue = 0;
  223. const legendData = [];
  224. const k =
  225. typeof internalDiameterRatio !== 'undefined'
  226. ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio)
  227. : 1 / 3;
  228. for (let i = 0; i < pieData.length; i += 1) {
  229. sumValue += pieData[i].value;
  230. const seriesItem = {
  231. name: typeof pieData[i].name === 'undefined' ? `series${i}` : pieData[i].name,
  232. type: 'surface',
  233. parametric: true,
  234. wireframe: {
  235. show: false,
  236. },
  237. pieData: pieData[i],
  238. pieStatus: {
  239. selected: false,
  240. hovered: false,
  241. k,
  242. },
  243. };
  244. if (typeof pieData[i].itemStyle !== 'undefined') {
  245. const {itemStyle} = pieData[i];
  246. // eslint-disable-next-line no-unused-expressions
  247. typeof pieData[i].itemStyle.color !== 'undefined' ? (itemStyle.color = pieData[i].itemStyle.color) : null;
  248. // eslint-disable-next-line no-unused-expressions
  249. typeof pieData[i].itemStyle.opacity !== 'undefined'
  250. ? (itemStyle.opacity = pieData[i].itemStyle.opacity)
  251. : null;
  252. seriesItem.itemStyle = itemStyle;
  253. }
  254. series.push(seriesItem);
  255. }
  256. for (let i = 0; i < series.length; i += 1) {
  257. endValue = startValue + series[i].pieData.value;
  258. series[i].pieData.startRatio = startValue / sumValue;
  259. series[i].pieData.endRatio = endValue / sumValue;
  260. series[i].parametricEquation = this.getParametricEquation(
  261. series[i].pieData.startRatio,
  262. series[i].pieData.endRatio,
  263. false,
  264. false,
  265. k,
  266. 10//在此处传入饼图初始高度h
  267. );
  268. startValue = endValue;
  269. legendData.push(series[i].name);
  270. }
  271. // 准备待返回的配置项,把准备好的series 传入。
  272. const option = {
  273. legend: {
  274. orient: "vertical",
  275. right: '8%',
  276. top: '22%',
  277. textStyle: {
  278. color: "#fff",
  279. fontSize: 14,
  280. },
  281. icon: 'circle',
  282. formatter: (name) => {
  283. if (this.pieData.length) {
  284. const item = this.pieData.filter((item) => item.name === name)[0];
  285. let str = `${name}(${item.value}) ${item.proportion}%`
  286. return str
  287. }
  288. },
  289. },
  290. tooltip: {
  291. formatter: (params) => {
  292. let str = `${params.marker}${params.seriesName}:${this.pieData[params.seriesIndex].value}` + '个,占比:' + `${this.pieData[params.seriesIndex].proportion}` + '%'
  293. return str;
  294. },
  295. },
  296. xAxis3D: {
  297. min: -1,
  298. max: 1,
  299. },
  300. yAxis3D: {
  301. min: -1,
  302. max: 1,
  303. },
  304. zAxis3D: {
  305. min: -1,
  306. max: 1,
  307. },
  308. grid3D: {
  309. show: false,
  310. boxHeight: 25,//修改立体饼图的高度
  311. top: '-10%',
  312. left: '-20%',
  313. viewControl: {
  314. // 3d效果可以放大、旋转等,
  315. alpha: 35,//饼图翻转的程度
  316. beta: 30,
  317. rotateSensitivity: 1,
  318. zoomSensitivity: 0,
  319. panSensitivity: 0,
  320. autoRotate: true,//是否自动旋转
  321. distance: 300,//距离越小看到的饼图越大
  322. },
  323. },
  324. series,
  325. };
  326. return option;
  327. }
  328. }
  329. }
  330. </script>
  331. <style lang='scss' scoped>
  332. @import url("../index.scss");
  333. .custom-table {
  334. position: relative;
  335. /* 去掉table所有边框 */
  336. ::v-deep.el-table--border th.el-table__cell,
  337. ::v-deep.el-table td.el-table__cell {
  338. border-bottom: 1px solid #204D74;
  339. }
  340. ::v-deep .el-table th.is-leaf {
  341. /* 去除上边框 */
  342. border: none;
  343. }
  344. ::v-deep.el-table--border .el-table__cell {
  345. border-right: none !important;
  346. }
  347. ::v-deep.el-table--group,
  348. .el-table--border {
  349. border: none !important;
  350. }
  351. ::v-deep.el-table::before,
  352. .el-table--group::after,
  353. .el-table--border::after {
  354. background-color: unset !important;
  355. }
  356. // 去掉el-table的所有背景颜色以及所有hover的颜色
  357. ::v-deep.el-table,
  358. ::v-deep.el-table .el-table__header-wrapper th,
  359. ::v-deep.el-table--border {
  360. background-color: transparent;
  361. color: #07e3f9;
  362. }
  363. ::v-deep.el-table tr,
  364. ::v-deep.el-table__body tr:hover>td {
  365. background-color: transparent !important;
  366. }
  367. ::v-deep .el-table__header-wrapper thead th {
  368. background: #1B4B6D !important;
  369. color: #07e3f9;
  370. }
  371. ::v-deep .el-table__body-wrapper td {
  372. color: #B3E3E8;
  373. background: #0A2431;
  374. }
  375. }
  376. .el-pagination {
  377. margin-top: 10px;
  378. }
  379. ::v-deep .el-pagination__total,
  380. ::v-deep .el-pagination__jump {
  381. color: #fff;
  382. }
  383. </style>