LightMatrix.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976
  1. <template>
  2. <div class="light-matrix">
  3. <div class="panel">
  4. <div class="dot left top"></div>
  5. <div class="dot left bottom"></div>
  6. <div class="dot right top"></div>
  7. <div class="dot right bottom"></div>
  8. <Row>
  9. <Col :span="3">
  10. <div class="panel-item-gf">
  11. <div class="panel-item-gf-left">
  12. <span class="svg-icon svg-icon-write svg-icon-md">
  13. <SvgIcon :svgid="panelData.first.icon"></SvgIcon>
  14. </span>
  15. </div>
  16. <div class="panel-item-gf-right">
  17. <div class="panel-item-gf-up">{{ panelData.first.text }}</div>
  18. <div class="panel-item-gf-down">{{ panelData.first.num }}</div>
  19. </div>
  20. </div>
  21. </Col>
  22. <Col :span="3" v-for="(data, index) of panelData.datas" :key="index">
  23. <div class="panel-item" :class="data.color">
  24. <div class="panel-item-left">
  25. <div class="panel-item-li">
  26. <span>{{ data.name }}</span>
  27. <span class="svg-icon svg-icon-sm" :class="'svg-icon-' + data.color">
  28. <SvgIcon :svgid="data.nameIcon"></SvgIcon>
  29. </span>
  30. </div>
  31. <div class="panel-item-li">
  32. <span>{{ data.num }}</span>
  33. <span class="svg-icon svg-icon-sm" :class="'svg-icon-' + data.color">
  34. <SvgIcon :svgid="data.numIcon"></SvgIcon>
  35. </span>
  36. </div>
  37. </div>
  38. <div class="panel-item-right">
  39. <div class="panel-item-ri">
  40. <span>{{ data.text1 }}</span>
  41. <span>{{ data.num1 }}</span>
  42. </div>
  43. <div class="panel-item-ri">
  44. <span>{{ data.text2 }}</span>
  45. <span>{{ data.num2 }}</span>
  46. </div>
  47. </div>
  48. </div>
  49. </Col>
  50. </Row>
  51. </div>
  52. <div class="panel-title">
  53. <div class="panel-title-name">
  54. <i class="fa fa-send"></i>
  55. <span>某某某风电场</span>
  56. <div class="sub-title-item" v-for="(data, index) of subTitleDatas" :key="index">
  57. <span class="sub-title">{{ data.text }}</span>
  58. <span class="sub-count" :class="data.color">{{ data.num }}</span>
  59. </div>
  60. </div>
  61. </div>
  62. <div class="panel-body">
  63. <div class="card" v-for="(col, j) of datas" :key="j" :class="col.color">
  64. <div class="card-panel">
  65. <div class="card-left">
  66. <div class="tag">{{ col.tag }}</div>
  67. <div class="icon">
  68. <span class="svg-icon svg-icon-sm" :class="col.color == 'black' ? 'svg-icon-black' : col.color == 'gray' ? 'svg-icon-gray' : 'svg-icon-write'">
  69. <SvgIcon :svgid="col.icon"></SvgIcon>
  70. </span>
  71. </div>
  72. </div>
  73. <div class="card-right">
  74. <div class="num">
  75. <i class="svg-icon svg-icon-sm" :class="'svg-icon-' + col.color">
  76. <SvgIcon svgid="svg-A"></SvgIcon>
  77. </i>
  78. <span>{{ col.num1 }}</span>
  79. </div>
  80. <div class="num">
  81. <i class="svg-icon svg-icon-sm" :class="'svg-icon-' + col.color">
  82. <SvgIcon svgid="svg-W"></SvgIcon>
  83. </i>
  84. <span>{{ col.num2 }}</span>
  85. </div>
  86. <div class="num">
  87. <i class="svg-icon svg-icon-sm" :class="'svg-icon-' + col.color">
  88. <SvgIcon svgid="svg-V"></SvgIcon>
  89. </i>
  90. <span>{{ col.num3 }}</span>
  91. </div>
  92. </div>
  93. </div>
  94. </div>
  95. <!-- 站位用 保证卡片布局最后一行不会有问题 -->
  96. <i class="blank" v-for="i in datas.length" :key="i"></i>
  97. </div>
  98. </div>
  99. </template>
  100. <script>
  101. import Row from "@/components/coms/grid/row.vue";
  102. import Col from "@/components/coms/grid/col.vue";
  103. import SvgIcon from "@com/coms/icon/svg-icon.vue";
  104. import util from "@/helper/util.js";
  105. export default {
  106. // 名称
  107. name: "LightMatrix",
  108. // 使用组件
  109. components: {
  110. Row,
  111. Col,
  112. SvgIcon,
  113. },
  114. // 数据
  115. data() {
  116. return {
  117. panelData: {
  118. first: {
  119. icon: "svg-photovoltaic",
  120. text: "接入光伏",
  121. num: 256,
  122. },
  123. datas: [
  124. {
  125. color: "green",
  126. name: "待机",
  127. nameIcon: "svg-standby",
  128. num: 50,
  129. numIcon: "svg-manual",
  130. text1: "待风",
  131. num1: 30,
  132. text2: "手动停机",
  133. num2: 30,
  134. },
  135. {
  136. color: "blue",
  137. name: "运行",
  138. nameIcon: "svg-normal-power",
  139. num: 50,
  140. numIcon: "svg-drop-output",
  141. text1: "正常发电",
  142. num1: 30,
  143. text2: "降出力",
  144. num2: 30,
  145. },
  146. {
  147. color: "pink",
  148. name: "限电",
  149. nameIcon: "svg-limit-power",
  150. num: 50,
  151. numIcon: "svg-downtime",
  152. text1: "降出力",
  153. num1: 30,
  154. text2: "停机",
  155. num2: 30,
  156. },
  157. {
  158. color: "red",
  159. name: "故障",
  160. nameIcon: "svg-gz-downtime",
  161. num: 50,
  162. numIcon: "svg-field-involved",
  163. text1: "故障停机",
  164. num1: 30,
  165. text2: "场内受累",
  166. num2: 30,
  167. },
  168. {
  169. color: "orange",
  170. name: "检测",
  171. nameIcon: "svg-jx-downtime",
  172. num: 50,
  173. numIcon: "svg-field-involved",
  174. text1: "检修停机",
  175. num1: 30,
  176. text2: "产内受累",
  177. num2: 30,
  178. },
  179. {
  180. color: "gray",
  181. name: "离线",
  182. nameIcon: "svg-offline",
  183. num: 50,
  184. numIcon: "svg-unknown",
  185. text1: "离线",
  186. num1: 30,
  187. text2: "未知",
  188. num2: 30,
  189. },
  190. {
  191. color: "write",
  192. name: "受累",
  193. nameIcon: "svg-intranet-involvement",
  194. num: 50,
  195. numIcon: "svg-environment",
  196. text1: "电网",
  197. num1: 30,
  198. text2: "环境",
  199. num2: 30,
  200. },
  201. ],
  202. },
  203. col: 15,
  204. subTitleDatas: [
  205. {
  206. text: "接入台数",
  207. num: 256,
  208. color: "write",
  209. },
  210. {
  211. text: "待机台数",
  212. num: 256,
  213. color: "green",
  214. },
  215. {
  216. text: "并网台数",
  217. num: 256,
  218. color: "blue",
  219. },
  220. {
  221. text: "限电台数",
  222. num: 256,
  223. color: "pink",
  224. },
  225. {
  226. text: "故障台数",
  227. num: 256,
  228. color: "red",
  229. },
  230. {
  231. text: "检修台数",
  232. num: 256,
  233. color: "orange",
  234. },
  235. {
  236. text: "受累台数",
  237. num: 256,
  238. color: "write",
  239. },
  240. {
  241. text: "离线台数",
  242. num: 256,
  243. color: "gray",
  244. },
  245. {
  246. text: "风速",
  247. num: 256,
  248. color: "gray",
  249. },
  250. {
  251. text: "预测功率",
  252. num: 256,
  253. color: "gray",
  254. },
  255. {
  256. text: "保证功率",
  257. num: 256,
  258. color: "gray",
  259. },
  260. {
  261. text: "应发功率",
  262. num: 256,
  263. color: "gray",
  264. },
  265. {
  266. text: "实际功率",
  267. num: 256,
  268. color: "gray",
  269. },
  270. {
  271. text: "AGC指令",
  272. num: 256,
  273. color: "gray",
  274. },
  275. {
  276. text: "出线功率",
  277. num: 256,
  278. color: "gray",
  279. },
  280. ],
  281. datas: [
  282. {
  283. tag: "01#",
  284. num1: 3262.8,
  285. num2: 12.6,
  286. num3: 12.6,
  287. icon: "svg-photovoltaic",
  288. color: "blue",
  289. },
  290. ],
  291. };
  292. },
  293. // 函数
  294. methods: {},
  295. // 生命周期钩子
  296. beforeCreate() {
  297. // 创建前
  298. },
  299. created() {
  300. // 创建后
  301. let tempData = [];
  302. for (let i = 0; i < 195; i++) {
  303. tempData.push(util.copy(this.datas[0]));
  304. if (i == 114) {
  305. tempData[i].color = "green";
  306. }
  307. if (i == 115) {
  308. tempData[i].color = "pink";
  309. }
  310. if (i == 116) {
  311. tempData[i].color = "orange";
  312. }
  313. if (i == 117) {
  314. tempData[i].color = "red";
  315. }
  316. if (i == 118) {
  317. tempData[i].color = "black";
  318. }
  319. if (i == 119) {
  320. tempData[i].color = "gray";
  321. }
  322. }
  323. this.datas = util.copy(tempData);
  324. },
  325. beforeMount() {
  326. // 渲染前
  327. },
  328. mounted() {
  329. // 渲染后
  330. },
  331. beforeUpdate() {
  332. // 数据更新前
  333. },
  334. updated() {
  335. // 数据更新后
  336. },
  337. };
  338. </script>
  339. <style lang="less" scoped>
  340. @panelHeight: 6.481vh;
  341. @titleHeight: 3.704vh;
  342. .light-matrix {
  343. width: calc(100% - 1.111vh);
  344. height: calc(100vh - 7.222vh);
  345. display: flex;
  346. flex-direction: column;
  347. .panel {
  348. width: 100%;
  349. border: 0.093vh solid @darkgray;
  350. position: relative;
  351. padding: 1.111vh 2.222vh;
  352. background-color: fade(@darkgray, 15%);
  353. .dot {
  354. width: 0.185vh;
  355. height: 0.185vh;
  356. border-radius: 50%;
  357. background-color: @write;
  358. position: absolute;
  359. &.left {
  360. left: 0.37vh;
  361. }
  362. &.right {
  363. right: 0.37vh;
  364. }
  365. &.top {
  366. top: 0.37vh;
  367. }
  368. &.bottom {
  369. bottom: 0.37vh;
  370. }
  371. }
  372. .panel-item-gf {
  373. width: 100%;
  374. background-color: fade(@darkgray, 15%);
  375. display: flex;
  376. height: @panelHeight;
  377. .panel-item-gf-left {
  378. width: @panelHeight;
  379. height: @panelHeight;
  380. background-color: fade(@darkgray, 40%);
  381. display: flex;
  382. align-items: center;
  383. justify-content: center;
  384. i {
  385. font-size: 2.778vh;
  386. color: @write;
  387. }
  388. }
  389. .panel-item-gf-right {
  390. flex-grow: 1;
  391. color: @write;
  392. text-align: right;
  393. .panel-item-gf-up {
  394. height: @panelHeight / 2;
  395. border-bottom: 0.093vh solid fade(@darkgray, 40%);
  396. line-height: @panelHeight / 2;
  397. padding-right: 1.111vh;
  398. font-size: @fontsize;
  399. }
  400. .panel-item-gf-down {
  401. height: @panelHeight / 2;
  402. line-height: @panelHeight / 2;
  403. padding-right: 1.111vh;
  404. font-weight: 600;
  405. font-size: @fontsize;
  406. }
  407. }
  408. }
  409. .panel-item {
  410. width: 100%;
  411. height: @panelHeight;
  412. display: flex;
  413. font-size: @fontsize-s;
  414. .panel-item-left {
  415. width: @panelHeight;
  416. height: @panelHeight;
  417. .panel-item-li {
  418. width: 100%;
  419. height: @panelHeight / 2;
  420. line-height: @panelHeight / 2;
  421. padding: 0 1.111vh;
  422. display: flex;
  423. align-items: center;
  424. font-size: @fontsize-s;
  425. .svg-icon {
  426. margin-left: auto;
  427. }
  428. }
  429. }
  430. .panel-item-right {
  431. flex-grow: 1;
  432. height: @panelHeight;
  433. .panel-item-ri {
  434. height: @panelHeight / 2;
  435. line-height: @panelHeight / 2;
  436. padding: 0 1.111vh;
  437. &:first-child {
  438. border-bottom: 0.093vh solid;
  439. }
  440. span {
  441. &:first-child {
  442. float: left;
  443. }
  444. &:last-child {
  445. float: right;
  446. color: @write;
  447. }
  448. }
  449. }
  450. }
  451. &.green {
  452. background-color: fade(@green, 15%);
  453. color: @green;
  454. .panel-item-left {
  455. background-color: fade(@green, 15%);
  456. }
  457. .panel-item-right {
  458. .panel-item-ri {
  459. &:first-child {
  460. border-color: @green;
  461. }
  462. }
  463. }
  464. }
  465. &.blue {
  466. background-color: fade(@darkBlue, 15%);
  467. color: @darkBlue;
  468. .panel-item-left {
  469. background-color: fade(@darkBlue, 15%);
  470. }
  471. .panel-item-right {
  472. .panel-item-ri {
  473. &:first-child {
  474. border-color: @darkBlue;
  475. }
  476. }
  477. }
  478. }
  479. &.pink {
  480. background-color: fade(@pink, 15%);
  481. color: @pink;
  482. .panel-item-left {
  483. background-color: fade(@pink, 15%);
  484. }
  485. .panel-item-right {
  486. .panel-item-ri {
  487. &:first-child {
  488. border-color: @pink;
  489. }
  490. }
  491. }
  492. }
  493. &.red {
  494. background-color: fade(@red, 15%);
  495. color: @red;
  496. .panel-item-left {
  497. background-color: fade(@red, 15%);
  498. }
  499. .panel-item-right {
  500. .panel-item-ri {
  501. &:first-child {
  502. border-color: @red;
  503. }
  504. }
  505. }
  506. }
  507. &.orange {
  508. background-color: fade(@orange, 15%);
  509. color: @orange;
  510. .panel-item-left {
  511. background-color: fade(@orange, 15%);
  512. }
  513. .panel-item-right {
  514. .panel-item-ri {
  515. &:first-child {
  516. border-color: @orange;
  517. }
  518. }
  519. }
  520. }
  521. &.gray {
  522. background-color: fade(@darkgray, 15%);
  523. color: @gray;
  524. .panel-item-left {
  525. background-color: fade(@darkgray, 15%);
  526. }
  527. .panel-item-right {
  528. .panel-item-ri {
  529. &:first-child {
  530. border-color: @darkgray;
  531. }
  532. }
  533. }
  534. }
  535. &.write {
  536. background-color: fade(@write, 15%);
  537. color: @write;
  538. .panel-item-left {
  539. background-color: fade(@write, 15%);
  540. }
  541. .panel-item-right {
  542. .panel-item-ri {
  543. &:first-child {
  544. border-color: @write;
  545. }
  546. }
  547. }
  548. }
  549. }
  550. }
  551. .panel-title {
  552. width: 100%;
  553. height: @titleHeight;
  554. line-height: @titleHeight;
  555. background-color: fade(@darkgray, 40%);
  556. .panel-title-name {
  557. font-size: @fontsize-s;
  558. color: @green;
  559. display: flex;
  560. align-items: center;
  561. i {
  562. margin: 0 0.556vh 0 1.481vh;
  563. }
  564. .sub-title-item {
  565. display: flex;
  566. .sub-title {
  567. color: @gray;
  568. font-size: @fontsize-s;
  569. margin: 0 0.556vh 0 1.481vh;
  570. }
  571. .sub-count {
  572. font-size: @fontsize-s;
  573. font-family: "Bicubik";
  574. font-weight: 500;
  575. &.write {
  576. color: @write;
  577. }
  578. &.green {
  579. color: @green;
  580. }
  581. &.blue {
  582. color: @blue;
  583. }
  584. &.pink {
  585. color: @pink;
  586. }
  587. &.red {
  588. color: @red;
  589. }
  590. &.orange {
  591. color: @orange;
  592. }
  593. &.gray {
  594. color: @gray;
  595. }
  596. }
  597. }
  598. }
  599. }
  600. .panel-body {
  601. background-color: fade(@darkgray, 20%);
  602. padding: 0.741vh;
  603. margin-bottom: 1.481vh;
  604. width: 100%;
  605. display: flex;
  606. flex-direction: row;
  607. flex-wrap: wrap;
  608. justify-content: space-between;
  609. .blank {
  610. margin-right: 4px;
  611. flex: 1 0 125px;
  612. }
  613. .card {
  614. margin-right: 4px;
  615. margin-top: 4px;
  616. flex: 1 0 125px;
  617. }
  618. .card {
  619. border: 1px solid;
  620. .card-panel {
  621. display: flex;
  622. flex-grow: row;
  623. .card-left {
  624. width: 40%;
  625. border-right: 0.093vh dotted;
  626. display: flex;
  627. flex-direction: column;
  628. .tag {
  629. color: @write;
  630. font-size: @fontsize-s;
  631. width: 100%;
  632. text-align: center;
  633. }
  634. .icon {
  635. flex-grow: 1;
  636. display: flex;
  637. align-items: center;
  638. justify-content: center;
  639. i {
  640. font-size: 14px;
  641. }
  642. }
  643. }
  644. .card-right {
  645. width: 60%;
  646. margin-top: 2px;
  647. .num {
  648. width: 100%;
  649. font-size: 14px;
  650. text-align: left;
  651. padding-right: 0.278vh;
  652. display: flex;
  653. align-items: center;
  654. justify-content: space-around;
  655. i {
  656. margin: 0 0.37vh;
  657. }
  658. span {
  659. flex: 1;
  660. }
  661. }
  662. }
  663. }
  664. .card-percent {
  665. height: 0.926vh;
  666. padding: 0.093vh 0.185vh;
  667. position: relative;
  668. border-top: 1px solid;
  669. background-color: transparent;
  670. .percent {
  671. height: 0.648vh;
  672. background-color: @green;
  673. position: absolute;
  674. left: 0.185vh;
  675. top: 0.093vh;
  676. }
  677. }
  678. &.blue {
  679. border-color: @darkBlue;
  680. background-color: fade(@darkBlue, 15%);
  681. .card-panel {
  682. .card-left {
  683. border-color: @darkBlue;
  684. .tag {
  685. background-color: @darkBlue;
  686. }
  687. .icon {
  688. svg {
  689. use {
  690. fill: @write;
  691. }
  692. }
  693. }
  694. }
  695. .card-right {
  696. .num {
  697. color: @darkBlue;
  698. }
  699. }
  700. }
  701. .card-percent {
  702. border-color: @darkBlue;
  703. }
  704. }
  705. &.pink {
  706. border-color: @pink;
  707. background-color: fade(@pink, 15%);
  708. .card-panel {
  709. .card-left {
  710. border-color: @pink;
  711. .tag {
  712. background-color: @pink;
  713. }
  714. .icon {
  715. svg {
  716. use {
  717. fill: @write;
  718. }
  719. }
  720. }
  721. }
  722. .card-right {
  723. .num {
  724. color: @pink;
  725. }
  726. }
  727. }
  728. .card-percent {
  729. border-color: @pink;
  730. }
  731. }
  732. &.orange {
  733. border-color: @orange;
  734. background-color: fade(@orange, 15%);
  735. .card-panel {
  736. .card-left {
  737. border-color: @orange;
  738. .tag {
  739. background-color: @orange;
  740. }
  741. .icon {
  742. use {
  743. fill: @write;
  744. }
  745. }
  746. }
  747. .card-right {
  748. .num {
  749. color: @orange;
  750. }
  751. }
  752. }
  753. .card-percent {
  754. border-color: @orange;
  755. }
  756. }
  757. &.green {
  758. border-color: @green;
  759. background-color: fade(@green, 15%);
  760. .card-panel {
  761. .card-left {
  762. border-color: @green;
  763. .tag {
  764. background-color: @green;
  765. }
  766. .icon {
  767. use {
  768. fill: @write;
  769. }
  770. }
  771. }
  772. .card-right {
  773. .num {
  774. color: @green;
  775. }
  776. }
  777. }
  778. .card-percent {
  779. border-color: @green;
  780. }
  781. }
  782. &.gray {
  783. border-color: @darkgray;
  784. background-color: fade(@darkgray, 15%);
  785. .card-panel {
  786. .card-left {
  787. border-color: @darkgray;
  788. .tag {
  789. background-color: @darkgray;
  790. }
  791. .icon {
  792. use {
  793. fill: @black;
  794. }
  795. }
  796. }
  797. .card-right {
  798. .num {
  799. color: @gray;
  800. }
  801. }
  802. }
  803. .card-percent {
  804. border-color: @darkgray;
  805. }
  806. }
  807. &.red {
  808. border-color: @red;
  809. .card-panel {
  810. background-color: @red;
  811. .card-left {
  812. border-color: @darkRed;
  813. .tag {
  814. background-color: @darkRed;
  815. }
  816. .icon {
  817. use {
  818. fill: @write;
  819. }
  820. }
  821. }
  822. .card-right {
  823. .num {
  824. color: @write;
  825. }
  826. }
  827. }
  828. .card-percent {
  829. border-color: @red;
  830. }
  831. }
  832. &.black {
  833. border-color: @write;
  834. .card-panel {
  835. background-color: @write;
  836. .card-left {
  837. border-color: @black;
  838. .tag {
  839. background-color: @darkgray;
  840. }
  841. .icon {
  842. .svg-icon {
  843. svg {
  844. use {
  845. fill: @black;
  846. }
  847. }
  848. }
  849. }
  850. }
  851. .card-right {
  852. .num {
  853. color: @black;
  854. }
  855. }
  856. }
  857. }
  858. }
  859. }
  860. }
  861. </style>