Browse Source

健康矩阵-进入单机页面。页面增加风机下拉选择框

wsy 3 years ago
parent
commit
253eca7da1

+ 90 - 89
package.json

@@ -1,89 +1,90 @@
-{
-  "name": "electronic-map",
-  "version": "0.1.0",
-  "private": true,
-  "scripts": {
-    "serve": "vue-cli-service serve",
-    "build": "vue-cli-service build",
-    "test:unit": "vue-cli-service test:unit",
-    "lint": "vue-cli-service lint"
-  },
-  "dependencies": {
-    "@antv/x6": "^1.24.4",
-    "@arcgis/core": "^4.19.3",
-    "axios": "^0.21.1",
-    "core-js": "^3.6.5",
-    "echarts": "^5.1.1",
-    "echarts-gl": "^2.0.4",
-    "element-plus": "^1.0.2-beta.53",
-    "file-saver": "^2.0.5",
-    "font-awesome": "^4.7.0",
-    "html2canvas": "^1.0.0-rc.7",
-    "jquery": "^3.6.0",
-    "jspdf": "^2.3.1",
-    "stompjs": "^2.3.3",
-    "three": "^0.129.0",
-    "vivus": "^0.4.6",
-    "vue": "^3.0.0",
-    "vue-axios": "^3.2.4",
-    "vue-router": "^4.0.0-0",
-    "vuex": "^4.0.0-0",
-    "xlsx": "^0.17.0"
-  },
-  "devDependencies": {
-    "@vue/cli-plugin-babel": "~4.5.0",
-    "@vue/cli-plugin-eslint": "~4.5.0",
-    "@vue/cli-plugin-router": "~4.5.0",
-    "@vue/cli-plugin-unit-mocha": "~4.5.0",
-    "@vue/cli-plugin-vuex": "~4.5.0",
-    "@vue/cli-service": "~4.5.0",
-    "@vue/compiler-sfc": "^3.0.0",
-    "@vue/test-utils": "^2.0.0-0",
-    "babel-eslint": "^10.1.0",
-    "chai": "^4.1.2",
-    "eslint": "^6.7.2",
-    "eslint-plugin-vue": "^7.0.0",
-    "less": "^3.0.4",
-    "less-loader": "^5.0.0",
-    "sass": "^1.27.0",
-    "sass-loader": "^10.0.4",
-    "script-loader": "^0.7.2",
-    "style-resources-loader": "^1.4.1",
-    "svg-sprite-loader": "^6.0.7",
-    "svgo-loader": "^3.0.0"
-  },
-  "eslintConfig": {
-    "root": true,
-    "env": {
-      "node": true
-    },
-    "extends": [
-      "plugin:vue/vue3-essential",
-      "eslint:recommended"
-    ],
-    "parserOptions": {
-      "parser": "babel-eslint"
-    },
-    "rules": {
-      "no-debugger": "off",
-      "no-console": "off",
-      "no-unused-vars": "off"
-    },
-    "overrides": [
-      {
-        "files": [
-          "**/__tests__/*.{j,t}s?(x)",
-          "**/tests/unit/**/*.spec.{j,t}s?(x)"
-        ],
-        "env": {
-          "mocha": true
-        }
-      }
-    ]
-  },
-  "browserslist": [
-    "> 1%",
-    "last 2 versions",
-    "not dead"
-  ]
-}
+{
+  "name": "electronic-map",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "servebig": "node --max-old-space-size=6000  ./node_modules/@vue/cli-service/bin/vue-cli-service.js serve",
+    "build": "vue-cli-service build",
+    "test:unit": "vue-cli-service test:unit",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "@antv/x6": "^1.24.4",
+    "@arcgis/core": "^4.19.3",
+    "axios": "^0.21.1",
+    "core-js": "^3.6.5",
+    "echarts": "^5.1.1",
+    "echarts-gl": "^2.0.4",
+    "element-plus": "^1.0.2-beta.53",
+    "file-saver": "^2.0.5",
+    "font-awesome": "^4.7.0",
+    "html2canvas": "^1.0.0-rc.7",
+    "jquery": "^3.6.0",
+    "jspdf": "^2.3.1",
+    "stompjs": "^2.3.3",
+    "three": "^0.129.0",
+    "vivus": "^0.4.6",
+    "vue": "^3.0.0",
+    "vue-axios": "^3.2.4",
+    "vue-router": "^4.0.0-0",
+    "vuex": "^4.0.0-0",
+    "xlsx": "^0.17.0"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "~4.5.0",
+    "@vue/cli-plugin-eslint": "~4.5.0",
+    "@vue/cli-plugin-router": "~4.5.0",
+    "@vue/cli-plugin-unit-mocha": "~4.5.0",
+    "@vue/cli-plugin-vuex": "~4.5.0",
+    "@vue/cli-service": "~4.5.0",
+    "@vue/compiler-sfc": "^3.0.0",
+    "@vue/test-utils": "^2.0.0-0",
+    "babel-eslint": "^10.1.0",
+    "chai": "^4.1.2",
+    "eslint": "^6.7.2",
+    "eslint-plugin-vue": "^7.0.0",
+    "less": "^3.0.4",
+    "less-loader": "^5.0.0",
+    "sass": "^1.27.0",
+    "sass-loader": "^10.0.4",
+    "script-loader": "^0.7.2",
+    "style-resources-loader": "^1.4.1",
+    "svg-sprite-loader": "^6.0.7",
+    "svgo-loader": "^3.0.0"
+  },
+  "eslintConfig": {
+    "root": true,
+    "env": {
+      "node": true
+    },
+    "extends": [
+      "plugin:vue/vue3-essential",
+      "eslint:recommended"
+    ],
+    "parserOptions": {
+      "parser": "babel-eslint"
+    },
+    "rules": {
+      "no-debugger": "off",
+      "no-console": "off",
+      "no-unused-vars": "off"
+    },
+    "overrides": [
+      {
+        "files": [
+          "**/__tests__/*.{j,t}s?(x)",
+          "**/tests/unit/**/*.spec.{j,t}s?(x)"
+        ],
+        "env": {
+          "mocha": true
+        }
+      }
+    ]
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not dead"
+  ]
+}

+ 70 - 0
src/components/coms/wt-chooser/wt-chooser.vue

@@ -0,0 +1,70 @@
+<template>
+  <div class="query mg-b-8">
+    <div class="query-items">
+      <div class="query-item">
+        <div class="lable">风场:</div>
+        <div class="search-input">
+          <el-select v-model="wpId" clearable placeholder="请选择风场" popper-class="select" @change="getWtList">
+            <el-option v-for="item in wpList" :key="item.id" :label="item.name" :value="item.id">
+            </el-option>
+          </el-select>
+        </div>
+      </div>
+      <div class="query-item">
+        <div class="lable">风机:</div>
+        <div class="search-input">
+          <el-select v-model="wtId" clearable placeholder="请选择风机" popper-class="select" @change="wtChange">
+            <el-option v-for="item in wtList" :key="item.id" :label="item.name" :value="item.id">
+            </el-option>
+          </el-select>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  // 传参
+  props: {
+    wpId: { type: String, default: "MHS_FDC" },
+    wtId: { type: String, default: "MG01_01" },
+  },
+  // 事件
+  emits: {
+  },
+  data() {
+    return {
+      wpList: [],
+      wtList: [],
+    };
+  },
+  created() {
+    this.getWpList();
+    this.getWtList();
+  },
+  methods: {
+    async getWpList() {
+      const { data } = await this.API.requestData({
+        subUrl: "powercompare/windfarmAjax",
+      });
+      this.wpList = data.data;
+    },
+    async getWtList() {
+      const { data } = await this.API.requestData({
+        subUrl: "powercompare/windturbineAjax",
+        data: {
+          wpId: this.wpId,
+        },
+      });
+      this.wtList = data.data;
+    },
+    wtChange() {
+      this.$emit("change", { wtId: this.wtId, wpId: this.wpId });
+    },
+  },
+};
+</script>
+
+<style lang="less">
+</style>

File diff suppressed because it is too large
+ 859 - 852
src/views/HealthControl/Health10.vue


+ 298 - 289
src/views/HealthControl/healthLineChart2.vue

@@ -1,289 +1,298 @@
-<template>
-  <div class="health-7">
-    <div class="power-info mg-b-16">
-      <div class="info-tab">
-        <div
-          class="tab"
-          v-for="(item, index) in infoList"
-          :key="index"
-          :class="item.active ? 'active' : ''"
-          @click="onClickInfo(item)"
-        >
-          <i class="svg-icon svg-icon svg-icon-sm">
-            <svg-icon :svgid="item.svgid" />
-          </i>
-          <span> {{ item.title }} </span>
-        </div>
-        <div class="empty"></div>
-      </div>
-      <div class="info-chart">
-        <panel class="info-chart-panel" :title="'健康趋势'">
-          <vertival-bar-line-chart :height="'310px'" :bardata="bardata" :lineData="lineData"/>
-        </panel>
-      </div>
-    </div>
-    <div class="fc-info mg-b-16">
-      <panel :title="'健康走势图'" :showLine="false">
-        <normal-line-chart :height="'150px'" />
-      </panel>
-    </div>
-    <div class="data-list">
-      <Table :data="tableData" :canScroll="true" />
-    </div>
-  </div>
-</template>
-
-<script>
-import VertivalBarLineChart from "../../components/chart/combination/vertival-bar-line-chart.vue";
-import NormalLineChart from "../../components/chart/line/normal-line-chart.vue";
-import SvgIcon from "../../components/coms/icon/svg-icon.vue";
-import Panel from "../../components/coms/panel/panel.vue";
-import Table from "../../components/coms/table/table.vue";
-export default {
-  setup() {},
-  components: { SvgIcon, Panel, VertivalBarLineChart, NormalLineChart, Table },
-  data() {
-    return {
-      infoList: [
-        // {title: '24小时健康趋势', svgid: 'svg-24-houre', active: false, type: 'houre'},
-        { title: "7日健康趋势", svgid: "svg-h-day", active: true, type: "day" },
-        { title: "30日健康趋势", svgid: "svg-h-month", active: false, type: "month"},
-      ],
-      tableData: {
-        column: [
-          { name: "部件名称",field: "name" },
-          { name: "MTBF(h)",field: "v1", is_num: true },
-          { name: "MTTR(h)",field: "v2", is_num: true },
-          { name: "损失电量(kw/h)",field: "v3",is_num: true },
-          { name: "当前状态",field: "v4",
-            template: function(data) {
-              if (data == 1) return "<div class='dot green'></div>";
-              else if (data == 2) return "<div class='dot purple'></div>";
-              else if (data == 3) return "<div class='dot yellow'></div>";
-              else if (data == 4) return "<div class='dot orange'></div>";
-            },
-          },
-        ],
-        data: [],
-      },
-      bardata: { area: [], legend: [], data: [] }, // 损失电量分析echart数值
-      lineData: [],
-      wtId: undefined,
-      wpId: undefined,
-      hisValue: {},  //健康走势图
-    };
-  },
-  created() {
-    this.wtId = this.$route.params.wtId;
-    this.wpId = this.$route.params.wpId;
-    this.requestCoulometry(2)
-    this.requestHisValue()
-    this.requestMttrrand()
-  },
-  methods:{
-     // 未确认缺陷按钮下的健康趋势选项
-    onClickInfo(item) {
-      this.infoList.forEach((element) => {
-        if (item.type == element.type) {
-          item.active = true;
-          switch (item.type) {
-            case "day":
-              this.requestCoulometry(2);
-              break;
-            case "month":
-              this.requestCoulometry(3);
-          }
-        } else {
-          element.active = false;
-        }
-      });
-    },
-    // 损失电量分析  type:1 表示24小时健康趋势,2 表示七天健康趋势 3 表示30天健康趋势
-    requestCoulometry(type) {
-      let that = this;
-      that.API.requestData({
-        method: "POST",
-        timeout: 8000,
-        subUrl: "recommen/findAllChartjz",
-        data: { wpId: 0, type: type },
-        success(res) {
-          if (res.code == 200) {
-            that.bardata.legend = ["优数量", "良数量", "差数量"];
-            that.lineData = res.data.lvchart;
-            that.bardata.area = res.data.datechart;
-            that.bardata.data[2] = res.data.cslchart;
-            that.bardata.data[1] = res.data.lslchart;
-            that.bardata.data[0] = res.data.yslchart;
-          }
-        },
-      });
-    },
-    //风机健康走势图
-    requestHisValue(){
-      let that = this;
-      that.API.requestData({
-        method: "POST",
-        subUrl: "healthsub/findWtHisValueForBj",
-        data: { wtId: that.wtId },
-        success(res) {
-          if(res.code == 200){
-            let data = res.data;
-            data.time = data.time.slice(0, 65)
-            that.hisValue = data
-          }
-        },
-      });
-    },
-    //部件健康情况
-    requestMttrrand(){
-      let that = this;
-      that.API.requestData({
-        method: "POST",
-        subUrl: "healthsub/getWtMttrandMtbfByBj",
-        data: { wtId: that.wtId },
-        success(res) {
-          if(res.code == 200){
-            let data = res.data;
-            that.tableData.data = [
-              {name:data.clx[1], v1:data.clx[4], v2:data.clx[5], v3:data.clx[6], v4:data.clx[0]},
-              {name:data.fdj[1], v1:data.fdj[4], v2:data.fdj[5], v3:data.fdj[6], v4:data.fdj[0]},
-              {name:data.bj[1], v1:data.bj[4], v2:data.bj[5], v3:data.bj[6], v4:data.bj[0]},
-              {name:data.zk[1], v1:data.zk[4], v2:data.zk[5], v3:data.zk[6], v4:data.zk[0]},
-              {name:data.zz[1], v1:data.zz[4], v2:data.zz[5], v3:data.zz[6], v4:data.zz[0]},
-              {name:data.ph[1], v1:data.ph[4], v2:data.ph[5], v3:data.ph[6], v4:data.ph[0]},
-              {name:data.jc[1], v1:data.jc[4], v2:data.jc[5], v3:data.jc[6], v4:data.jc[0]},
-              {name:data.bpq[1], v1:data.bpq[4], v2:data.bpq[5], v3:data.bpq[6], v4:data.bpq[0]},
-            ]
-          }
-        },
-      });
-    }
-  }
-};
-</script>
-
-<style lang="less">
-.health-7 {
-  // 电量健康情况
-  .power-info {
-    display: flex;
-    .info-tab {
-      flex: 0 0 156px;
-      display: flex;
-      flex-direction: column;
-      height: 350px;
-      margin-right: 1.4815vh;
-
-      .tab {
-        position: relative;
-        flex: 0 0 auto;
-        text-align: center;
-        line-height: 33px;
-        margin-right: 8px;
-        color: @gray-l;
-        font-size: 12px;
-        background: fade(@gray, 20);
-        border: 1px solid fade(@gray, 20);
-
-        display: flex;
-        align-items: center;
-
-        i {
-          margin: 0 1.4815vh;
-          svg use {
-            fill: @gray-l;
-          }
-        }
-
-        &:hover,
-        &.active {
-          background: fade(@green, 20);
-          border: 1px solid @green;
-          color: @green;
-          cursor: pointer;
-          i {
-            svg use {
-              fill: @green;
-            }
-          }
-        }
-
-        &.active::after {
-          box-sizing: content-box;
-          width: 0px;
-          height: 0px;
-          position: absolute;
-          right: -19px;
-          padding: 0;
-          border-bottom: 9px solid @green;
-          border-top: 9px solid transparent;
-          border-left: 9px solid transparent;
-          border-right: 9px solid transparent;
-          display: block;
-          content: "";
-          z-index: 10;
-          transform: rotate(90deg);
-        }
-
-        &.active::before {
-          box-sizing: content-box;
-          width: 0px;
-          height: 0px;
-          position: absolute;
-          right: -17px;
-          padding: 0;
-          border-bottom: 9px solid #063319;
-          border-top: 9px solid transparent;
-          border-left: 9px solid transparent;
-          border-right: 9px solid transparent;
-          display: block;
-          content: "";
-          z-index: 12;
-          transform: rotate(90deg);
-        }
-
-        & + .tab {
-          margin-top: 0.7407vh;
-        }
-
-        &:last-child {
-          text-align: center;
-          justify-content: center;
-        }
-      }
-
-      .empty {
-        flex: 1 0 auto;
-      }
-    }
-
-    .info-chart {
-      flex: 1 0 auto;
-    }
-  }
-
-  .data-list {
-    .dot {
-      width: 12px;
-      height: 12px;
-      margin: auto;
-
-      &.green {
-        background: @green;
-      }
-
-      &.purple {
-        background: @purple;
-      }
-
-      &.yellow {
-        background: @yellow;
-      }
-
-      &.orange {
-        background: @orange;
-      }
-    }
-  }
-}
-</style>
+<template>
+  <div class="health-7">
+    <wt-chooser @change="switchWt" :wpId="wpId" :wtId="wtId"></wt-chooser>
+    <div class="power-info mg-b-16">
+      <div class="info-tab">
+        <div
+          class="tab"
+          v-for="(item, index) in infoList"
+          :key="index"
+          :class="item.active ? 'active' : ''"
+          @click="onClickInfo(item)"
+        >
+          <i class="svg-icon svg-icon svg-icon-sm">
+            <svg-icon :svgid="item.svgid" />
+          </i>
+          <span> {{ item.title }} </span>
+        </div>
+        <div class="empty"></div>
+      </div>
+      <div class="info-chart">
+        <panel class="info-chart-panel" :title="'健康趋势'">
+          <vertival-bar-line-chart :height="'310px'" :bardata="bardata" :lineData="lineData"/>
+        </panel>
+      </div>
+    </div>
+    <div class="fc-info mg-b-16">
+      <panel :title="'健康走势图'" :showLine="false">
+        <normal-line-chart :height="'150px'" />
+      </panel>
+    </div>
+    <div class="data-list">
+      <Table :data="tableData" :canScroll="true" />
+    </div>
+  </div>
+</template>
+
+<script>
+import VertivalBarLineChart from "../../components/chart/combination/vertival-bar-line-chart.vue";
+import NormalLineChart from "../../components/chart/line/normal-line-chart.vue";
+import SvgIcon from "../../components/coms/icon/svg-icon.vue";
+import Panel from "../../components/coms/panel/panel.vue";
+import Table from "../../components/coms/table/table.vue";
+import WtChooser from "@com/coms/wt-chooser/wt-chooser.vue"
+export default {
+  setup() {},
+  components: { SvgIcon, Panel, VertivalBarLineChart, NormalLineChart, Table, WtChooser },
+  data() {
+    return {
+      infoList: [
+        // {title: '24小时健康趋势', svgid: 'svg-24-houre', active: false, type: 'houre'},
+        { title: "7日健康趋势", svgid: "svg-h-day", active: true, type: "day" },
+        { title: "30日健康趋势", svgid: "svg-h-month", active: false, type: "month"},
+      ],
+      tableData: {
+        column: [
+          { name: "部件名称",field: "name" },
+          { name: "MTBF(h)",field: "v1", is_num: true },
+          { name: "MTTR(h)",field: "v2", is_num: true },
+          { name: "损失电量(kw/h)",field: "v3",is_num: true },
+          { name: "当前状态",field: "v4",
+            template: function(data) {
+              if (data == 1) return "<div class='dot green'></div>";
+              else if (data == 2) return "<div class='dot purple'></div>";
+              else if (data == 3) return "<div class='dot yellow'></div>";
+              else if (data == 4) return "<div class='dot orange'></div>";
+            },
+          },
+        ],
+        data: [],
+      },
+      bardata: { area: [], legend: [], data: [] }, // 损失电量分析echart数值
+      lineData: [],
+      wtId: undefined,
+      wpId: undefined,
+      hisValue: {},  //健康走势图
+    };
+  },
+  created() {
+    this.init();
+  },
+  methods:{
+    init(){
+      this.wtId = this.$route.params.wtId;
+      this.wpId = this.$route.params.wpId;
+      this.requestCoulometry(2);
+      this.requestHisValue();
+      this.requestMttrrand();
+    },
+    switchWt(data){
+      this.$router.push(`/health/health10/${data.wpId}/${data.wtId}`);
+      this.init();
+    },
+     // 未确认缺陷按钮下的健康趋势选项
+    onClickInfo(item) {
+      this.infoList.forEach((element) => {
+        if (item.type == element.type) {
+          item.active = true;
+          switch (item.type) {
+            case "day":
+              this.requestCoulometry(2);
+              break;
+            case "month":
+              this.requestCoulometry(3);
+          }
+        } else {
+          element.active = false;
+        }
+      });
+    },
+    // 损失电量分析  type:1 表示24小时健康趋势,2 表示七天健康趋势 3 表示30天健康趋势
+    requestCoulometry(type) {
+      let that = this;
+      that.API.requestData({
+        method: "POST",
+        timeout: 8000,
+        subUrl: "recommen/findAllChartjz",
+        data: { wpId: 0, type: type },
+        success(res) {
+          if (res.code == 200) {
+            that.bardata.legend = ["优数量", "良数量", "差数量"];
+            that.lineData = res.data.lvchart;
+            that.bardata.area = res.data.datechart;
+            that.bardata.data[2] = res.data.cslchart;
+            that.bardata.data[1] = res.data.lslchart;
+            that.bardata.data[0] = res.data.yslchart;
+          }
+        },
+      });
+    },
+    //风机健康走势图
+    requestHisValue(){
+      let that = this;
+      that.API.requestData({
+        method: "POST",
+        subUrl: "healthsub/findWtHisValueForBj",
+        data: { wtId: that.wtId },
+        success(res) {
+          if(res.code == 200){
+            let data = res.data;
+            data.time = data.time.slice(0, 65)
+            that.hisValue = data
+          }
+        },
+      });
+    },
+    //部件健康情况
+    requestMttrrand(){
+      let that = this;
+      that.API.requestData({
+        method: "POST",
+        subUrl: "healthsub/getWtMttrandMtbfByBj",
+        data: { wtId: that.wtId },
+        success(res) {
+          if(res.code == 200){
+            let data = res.data;
+            that.tableData.data = [
+              {name:data.clx[1], v1:data.clx[4], v2:data.clx[5], v3:data.clx[6], v4:data.clx[0]},
+              {name:data.fdj[1], v1:data.fdj[4], v2:data.fdj[5], v3:data.fdj[6], v4:data.fdj[0]},
+              {name:data.bj[1], v1:data.bj[4], v2:data.bj[5], v3:data.bj[6], v4:data.bj[0]},
+              {name:data.zk[1], v1:data.zk[4], v2:data.zk[5], v3:data.zk[6], v4:data.zk[0]},
+              {name:data.zz[1], v1:data.zz[4], v2:data.zz[5], v3:data.zz[6], v4:data.zz[0]},
+              {name:data.ph[1], v1:data.ph[4], v2:data.ph[5], v3:data.ph[6], v4:data.ph[0]},
+              {name:data.jc[1], v1:data.jc[4], v2:data.jc[5], v3:data.jc[6], v4:data.jc[0]},
+              {name:data.bpq[1], v1:data.bpq[4], v2:data.bpq[5], v3:data.bpq[6], v4:data.bpq[0]},
+            ]
+          }
+        },
+      });
+    }
+  }
+};
+</script>
+
+<style lang="less">
+.health-7 {
+  // 电量健康情况
+  .power-info {
+    display: flex;
+    .info-tab {
+      flex: 0 0 156px;
+      display: flex;
+      flex-direction: column;
+      height: 350px;
+      margin-right: 1.4815vh;
+
+      .tab {
+        position: relative;
+        flex: 0 0 auto;
+        text-align: center;
+        line-height: 33px;
+        margin-right: 8px;
+        color: @gray-l;
+        font-size: 12px;
+        background: fade(@gray, 20);
+        border: 1px solid fade(@gray, 20);
+
+        display: flex;
+        align-items: center;
+
+        i {
+          margin: 0 1.4815vh;
+          svg use {
+            fill: @gray-l;
+          }
+        }
+
+        &:hover,
+        &.active {
+          background: fade(@green, 20);
+          border: 1px solid @green;
+          color: @green;
+          cursor: pointer;
+          i {
+            svg use {
+              fill: @green;
+            }
+          }
+        }
+
+        &.active::after {
+          box-sizing: content-box;
+          width: 0px;
+          height: 0px;
+          position: absolute;
+          right: -19px;
+          padding: 0;
+          border-bottom: 9px solid @green;
+          border-top: 9px solid transparent;
+          border-left: 9px solid transparent;
+          border-right: 9px solid transparent;
+          display: block;
+          content: "";
+          z-index: 10;
+          transform: rotate(90deg);
+        }
+
+        &.active::before {
+          box-sizing: content-box;
+          width: 0px;
+          height: 0px;
+          position: absolute;
+          right: -17px;
+          padding: 0;
+          border-bottom: 9px solid #063319;
+          border-top: 9px solid transparent;
+          border-left: 9px solid transparent;
+          border-right: 9px solid transparent;
+          display: block;
+          content: "";
+          z-index: 12;
+          transform: rotate(90deg);
+        }
+
+        & + .tab {
+          margin-top: 0.7407vh;
+        }
+
+        &:last-child {
+          text-align: center;
+          justify-content: center;
+        }
+      }
+
+      .empty {
+        flex: 1 0 auto;
+      }
+    }
+
+    .info-chart {
+      flex: 1 0 auto;
+    }
+  }
+
+  .data-list {
+    .dot {
+      width: 12px;
+      height: 12px;
+      margin: auto;
+
+      &.green {
+        background: @green;
+      }
+
+      &.purple {
+        background: @purple;
+      }
+
+      &.yellow {
+        background: @yellow;
+      }
+
+      &.orange {
+        background: @orange;
+      }
+    }
+  }
+}
+</style>