From e1c28921470ca2a82403ef5a7bc07f1c48619b36 Mon Sep 17 00:00:00 2001
From: 刘嘉威 <daidaibg@163.com>
Date: 星期三, 26 十月 2022 16:51:43 +0800
Subject: [PATCH] feat: 增加右上 右中图表

---
 src/components/datav/capsule-chart/index.d.ts        |    6 
 src/views/HomeView.vue                               |   14 
 src/views/setting.vue                                |    2 
 src/views/index/right-center.vue                     |   36 +++
 src/views/index/right-top.vue                        |  232 +++++++++++++++++++++++++
 components.d.ts                                      |    1 
 src/api/modules/index.ts                             |    4 
 src/views/index/center-bottom.vue                    |    4 
 src/components/datav/capsule-chart/capsule-chart.vue |  186 ++++++++++++++++++++
 src/components/datav/capsule-chart/index.ts          |    3 
 src/utils/query-param.ts                             |    2 
 src/mock/mock-index.ts                               |   44 ++++
 src/utils/public.ts                                  |    0 
 src/plugins/echarts.ts                               |    6 
 14 files changed, 513 insertions(+), 27 deletions(-)

diff --git a/components.d.ts b/components.d.ts
index 835eb88..fba7b29 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -7,6 +7,7 @@
 
 declare module '@vue/runtime-core' {
   export interface GlobalComponents {
+    CapsuleChart: typeof import('./src/components/datav/capsule-chart/capsule-chart.vue')['default']
     CountUp: typeof import('./src/components/count-up/count-up.vue')['default']
     ElDrawer: typeof import('element-plus/es')['ElDrawer']
     ElRadio: typeof import('element-plus/es')['ElRadio']
diff --git a/src/api/modules/index.ts b/src/api/modules/index.ts
index 66db6bd..7cff390 100644
--- a/src/api/modules/index.ts
+++ b/src/api/modules/index.ts
@@ -5,7 +5,7 @@
     "centerBottom":"/bigscreen/installationPlan",
 
     // 'big3':"/bigscreen/sbtx", //璁惧鎻愰啋
-    // 'big4':"/bigscreen/alarmNum", //鎶ヨ娆℃暟
+    'rightTop':"/bigscreen/alarmNum", //鎶ヨ娆℃暟
     // 'big5':'/bigscreen/ssyj',//瀹炴椂棰勮 
-    // 'big7':'/bigscreen/ranking',// 鎶ヨ鎺掑悕
+    'rightCenter':'/bigscreen/ranking',// 鎶ヨ鎺掑悕
 }
\ No newline at end of file
diff --git a/src/components/datav/capsule-chart/capsule-chart.vue b/src/components/datav/capsule-chart/capsule-chart.vue
new file mode 100644
index 0000000..cb81015
--- /dev/null
+++ b/src/components/datav/capsule-chart/capsule-chart.vue
@@ -0,0 +1,186 @@
+<script setup lang="ts">
+import { onMounted, reactive, ref, watch } from "vue";
+import type { DefaultConfigType } from "./index.d";
+import cloneDeep from "lodash/cloneDeep";
+import merge from "lodash/merge";
+const mergedConfig = ref<any>(null);
+const capsuleLength = ref<any>([]);
+const capsuleValue = ref<any>([]);
+const labelData = ref<any>([]);
+// const labelDataLength = ref<any>([]);
+
+const defaultConfig = reactive<DefaultConfigType>({
+    // Colors (hex|rgb|rgba|color keywords) ['#000', 'rgb(0, 0, 0)', 'rgba(0, 0, 0, 1)', 'red']
+    colors: [
+        "#37a2da",
+        "#32c5e9",
+        "#67e0e3",
+        "#9fe6b8",
+        "#ffdb5c",
+        "#ff9f7f",
+        "#fb7293",
+    ],
+    unit: "",
+    showValue: false, // Show item value
+});
+const props = withDefaults(
+    defineProps<{
+        config: object | any;
+        data: Array<{
+            name: string;
+            value: string | number;
+        }>;
+    }>(),
+    {
+        config: () => { },
+        data: () => [],
+    }
+);
+const calcData = () => {
+    mergeConfig();
+    calcCapsuleLengthAndLabelData();
+};
+const mergeConfig = () => {
+    mergedConfig.value = merge(cloneDeep(defaultConfig), props.config || {});
+};
+const calcCapsuleLengthAndLabelData = () => {
+    if (!props.data.length) return;
+    const newcapsuleValue = props.data.map((item: any) => item.value);
+    const maxValue = Math.max(...newcapsuleValue);
+    capsuleValue.value = newcapsuleValue;
+    capsuleLength.value = newcapsuleValue.map((v: any) =>
+        maxValue ? v / maxValue : 0
+    );
+    const oneFifth = maxValue / 5;
+    const newlabelData = Array.from(
+        new Set(new Array(6).fill(0).map((v, i) => Math.ceil(i * oneFifth)))
+    );
+    labelData.value = newlabelData;
+    // labelDataLength.value = Array.from(newlabelData).map((v) =>
+    //     maxValue ? v / maxValue : 0
+    // );
+    // console.log(labelDataLength.value);
+};
+watch(
+    () => props.data,
+    (newval: any) => {
+        calcData();
+    },
+);
+watch(
+    () => props.config,
+    (newval: any) => {
+        calcData();
+    },
+);
+onMounted(() => {
+    calcData();
+});
+</script>
+
+<template>
+    <div class="dv-capsule-chart">
+        <template v-if="mergedConfig">
+            <div class="label-column">
+                <div v-for="item in data" :key="item.name">
+                    {{ item.name }}
+                </div>
+                <div>&nbsp;</div>
+            </div>
+            <div class="capsule-container">
+                <div class="capsule-item" v-for="(capsule, index) in capsuleLength" :key="index">
+                    <div class="capsule-item-column" :style="`width: ${capsule * 100}%; background-color: ${mergedConfig.colors[index % mergedConfig.colors.length]
+                    };`">
+                        <div v-if="mergedConfig.showValue" class="capsule-item-value">
+                            {{ capsuleValue[index] }}
+                        </div>
+                    </div>
+                </div>
+
+                <div class="unit-label">
+                    <div v-for="(label, index) in labelData" :key="label + index">
+                        {{ label }}
+                    </div>
+                </div>
+            </div>
+
+            <div class="unit-text" v-if="mergedConfig.unit">
+                {{ mergedConfig.unit }}
+            </div>
+        </template>
+    </div>
+</template>
+
+<style scoped lang="scss">
+.dv-capsule-chart {
+    position: relative;
+    display: flex;
+    flex-direction: row;
+    box-sizing: border-box;
+    padding: 10px;
+    color: #fff;
+
+    .label-column {
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+        box-sizing: border-box;
+        padding-right: 10px;
+        text-align: right;
+        font-size: 12px;
+
+        div {
+            height: 20px;
+            line-height: 20px;
+        }
+    }
+
+    .capsule-container {
+        flex: 1;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+    }
+
+    .capsule-item {
+        box-shadow: 0 0 3px #999;
+        height: 10px;
+        margin: 5px 0px;
+        border-radius: 5px;
+
+        .capsule-item-column {
+            position: relative;
+            height: 8px;
+            margin-top: 1px;
+            border-radius: 5px;
+            transition: all 0.3s;
+            display: flex;
+            justify-content: flex-end;
+            align-items: center;
+
+            .capsule-item-value {
+                font-size: 12px;
+                transform: translateX(100%);
+            }
+        }
+    }
+
+    .unit-label {
+        height: 20px;
+        font-size: 12px;
+        position: relative;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+    }
+
+    .unit-text {
+        text-align: right;
+        display: flex;
+        align-items: flex-end;
+        font-size: 12px;
+        line-height: 20px;
+        margin-left: 10px;
+    }
+}
+</style>
diff --git a/src/components/datav/capsule-chart/index.d.ts b/src/components/datav/capsule-chart/index.d.ts
new file mode 100644
index 0000000..82277e8
--- /dev/null
+++ b/src/components/datav/capsule-chart/index.d.ts
@@ -0,0 +1,6 @@
+export interface DefaultConfigType {
+  
+    colors: Array<String>;
+      unit:string,
+      showValue:Boolean
+  }
\ No newline at end of file
diff --git a/src/components/datav/capsule-chart/index.ts b/src/components/datav/capsule-chart/index.ts
new file mode 100644
index 0000000..5b874c0
--- /dev/null
+++ b/src/components/datav/capsule-chart/index.ts
@@ -0,0 +1,3 @@
+import CapsuleChart from "./capsule-chart.vue"
+export * from "./index.d"
+export default CapsuleChart
\ No newline at end of file
diff --git a/src/mock/mock-index.ts b/src/mock/mock-index.ts
index 82e78c5..72f33fb 100644
--- a/src/mock/mock-index.ts
+++ b/src/mock/mock-index.ts
@@ -57,6 +57,50 @@
             return a
         }
     },
+    //鍙充笂
+    {
+        url: "/bigscreen/alarmNum",
+        type: "get",
+        response: () => {
+            const a = Mock.mock({
+                success: true,
+                data: {
+                    dateList: ['2021-11', '2021-12', '2022-01', '2022-02', '2022-03', "2022-04"],
+                    "numList|6": [
+                        '@integer(0, 1000)'
+                    ],
+                    "numList2|6": [
+                        '@integer(0, 1000)'
+                    ]
+                }
+            })
+            return a
+        }
+    },
+    //鍙充腑
+    {
+        url: "/bigscreen/ranking",
+        type: "get",
+        response: () => {
+            let num =Mock.mock({"list|80":[{ value:"@integer(50,1000)",name:"@city()"}]}).list
+            //   console.log("ranking",num);
+              let newNum:any =[],numObj:any ={}
+              num.map((item:any )=>{
+                if(!numObj[item.name] && newNum.length<8){
+                    numObj[item.name] =true
+                    newNum.push(item)
+                }
+              })
+              let arr = newNum.sort((a:any ,b:any )=>{
+                return b.value-a.value
+              })
+              let a ={
+                  success:true,
+                  data:arr
+              }
+              return a
+        }
+    },
     //瀹夎璁″垝
     {
         url: "/bigscreen/installationPlan",
diff --git a/src/plugins/echarts.ts b/src/plugins/echarts.ts
index 25fe485..9103847 100644
--- a/src/plugins/echarts.ts
+++ b/src/plugins/echarts.ts
@@ -14,7 +14,8 @@
     LegendComponent,
     DatasetComponent,
     VisualMapComponent,
-    GeoComponent
+    GeoComponent,
+    MarkPointComponent
   } from 'echarts/components'
 
   use([
@@ -26,7 +27,8 @@
     TitleComponent,
     DatasetComponent,
     VisualMapComponent,
-    GeoComponent
+    GeoComponent,
+    MarkPointComponent
   ])
 
   export const registerEcharts= (app:any)=>{
diff --git a/src/utils/public.ts b/src/utils/public.ts
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/utils/public.ts
diff --git a/src/utils/query-param.ts b/src/utils/query-param.ts
index 7defb3a..a0cdf6e 100644
--- a/src/utils/query-param.ts
+++ b/src/utils/query-param.ts
@@ -11,7 +11,7 @@
         for (var i = 0; i < urlArray.length; i++) {
             var urlItem = urlArray[i];
             var item = urlItem.split("=");
-            console.log(item);
+            // console.log(item);
             json[item[0]] = item[1];
         }
         return json;
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index 35e6317..dd0535d 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -3,15 +3,14 @@
 import { RouterView } from "vue-router";
 import ScaleScreen from "@/components/scale-screen";
 import Headers from "./header.vue";
-import Setting from "./setting.vue"
+import Setting from "./setting.vue";
 import { useSettingStore } from "@/stores/index";
-import { storeToRefs } from 'pinia';
-import  MessageContent  from '@/components/Plugins/MessageContent'
+import { storeToRefs } from "pinia";
+import MessageContent from "@/components/Plugins/MessageContent";
 
 const settingStore = useSettingStore();
-const {isScale} =storeToRefs(settingStore)
+const { isScale } = storeToRefs(settingStore);
 const wrapperStyle = {};
-
 </script>
 
 <template>
@@ -30,11 +29,10 @@
     <div class="content_wrap">
       <Headers />
       <RouterView />
-  <MessageContent/>
-
+      <MessageContent />
     </div>
   </scale-screen>
-  <Setting/>
+  <Setting />
 </template>
 <style lang="scss" scoped>
 .content_wrap {
diff --git a/src/views/index/center-bottom.vue b/src/views/index/center-bottom.vue
index c047996..b0ee361 100644
--- a/src/views/index/center-bottom.vue
+++ b/src/views/index/center-bottom.vue
@@ -17,7 +17,6 @@
   });
 };
 const setOption =async (newData: any) => {
-  await nextTick()
   option.value = {
     tooltip: {
       trigger: "axis",
@@ -150,7 +149,10 @@
     ],
   };
 };
+onMounted(()=>{
 getData();
+
+})
 </script>
 
 <template>
diff --git a/src/views/index/right-center.vue b/src/views/index/right-center.vue
index 7df5872..6f7af97 100644
--- a/src/views/index/right-center.vue
+++ b/src/views/index/right-center.vue
@@ -1,13 +1,39 @@
-<script setup lang='ts'>
+<script setup lang="ts">
+import { ref, reactive } from "vue";
+import CapsuleChart from "@/components/datav/capsule-chart";
+import { currentGET } from "@/api";
 
+const config = ref({
+  showValue: true,
+  unit: "娆�",
+});
+const data= ref([])
+const getData = () => {
+  currentGET("rightCenter").then((res) => {
+    console.log("鎶ヨ鎺掑悕", res);
+    if (res.success) {
+      data.value =res.data;
+    } else {
+      window["$message"]({
+        text: res.msg,
+        type: "warning",
+      });
+    }
+  });
+};
+getData();
 </script>
 
 <template>
-  <div class=''>
-
+  <div class="right_bottom">
+    <CapsuleChart :config="config" style="width: 100%; height: 260px" :data="data"/>
   </div>
 </template>
 
-<style scoped lang='scss'>
+<style scoped lang="scss">
 
-</style>
\ No newline at end of file
+.right_bottom {
+  box-sizing: border-box;
+  padding: 0 16px;
+}
+</style>
diff --git a/src/views/index/right-top.vue b/src/views/index/right-top.vue
index 7df5872..d0e33eb 100644
--- a/src/views/index/right-top.vue
+++ b/src/views/index/right-top.vue
@@ -1,13 +1,231 @@
-<script setup lang='ts'>
+<script setup lang="ts">
+import { ref,onMounted} from "vue";
+import { currentGET } from "@/api";
+import {graphic} from "echarts/core"
+const option = ref({});
+const getData = () => {
+  currentGET("rightTop", {}).then((res) => {
+    console.log("鎶ヨ娆℃暟 ", res);
+    if (res.success) {
+      setOption(res.data.dateList, res.data.numList, res.data.numList2);
+    } else {
+      window["$message"]({
+        text: res.msg,
+        type: "warning",
+      });
+    }
+  });
+};
+const setOption =async (xData:any[], yData:any[], yData2:any[]) => {
+  option.value = {
+        xAxis: {
+          type: "category",
+          data: xData,
+          boundaryGap: false, // 涓嶇暀鐧斤紝浠庡師鐐瑰紑濮�
+          splitLine: {
+            show: true,
+            lineStyle: {
+              color: "rgba(31,99,163,.2)",
+            },
+          },
+          axisLine: {
+            // show:false,
+            lineStyle: {
+              color: "rgba(31,99,163,.1)",
+            },
+          },
+          axisLabel: {
+            color: "#7EB7FD",
+            fontWeight: "500",
+          },
+        },
+        yAxis: {
+          type: "value",
+          splitLine: {
+            show: true,
+            lineStyle: {
+              color: "rgba(31,99,163,.2)",
+            },
+          },
+          axisLine: {
+            lineStyle: {
+              color: "rgba(31,99,163,.1)",
+            },
+          },
+          axisLabel: {
+            color: "#7EB7FD",
+            fontWeight: "500",
+          },
+        },
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: "rgba(0,0,0,.6)",
+          borderColor: "rgba(147, 235, 248, .8)",
+          textStyle: {
+            color: "#FFF",
+          },
+        },
+        grid: {
+          //甯冨眬
+          show: true,
+          left: "10px",
+          right: "30px",
+          bottom: "10px",
+          top: "32px",
+          containLabel: true,
+          borderColor: "#1F63A3",
+        },
+        series: [
+          {
+            data: yData,
+            type: "line",
+            smooth: true,
+            symbol: "none", //鍘婚櫎鐐�
+            name: "鎶ヨ1娆℃暟",
+            color: "rgba(252,144,16,.7)",
+            areaStyle: {
+                //鍙筹紝涓嬶紝宸︼紝涓�
+                color: new graphic.LinearGradient(
+                  0,
+                  0,
+                  0,
+                  1,
+                  [
+                    {
+                      offset: 0,
+                      color: "rgba(252,144,16,.7)",
+                    },
+                    {
+                      offset: 1,
+                      color: "rgba(252,144,16,.0)",
+                    },
+                  ],
+                  false
+                ),
+            },
+            markPoint: {
+              data: [
+                {
+                  name: "鏈�澶у��",
+                  type: "max",
+                  valueDim: "y",
+                  symbol: "rect",
+                  symbolSize: [60, 26],
+                  symbolOffset: [0, -20],
+                  itemStyle: {
+                    color: "rgba(0,0,0,0)",
+                  },
+                  label: {
+                    color: "#FC9010",
+                    backgroundColor: "rgba(252,144,16,0.1)",
+                    borderRadius: 6,
+                    padding: [7, 14],
+                    borderWidth: 0.5,
+                    borderColor: "rgba(252,144,16,.5)",
+                    formatter: "鎶ヨ1锛歿c}",
+                  },
+                },
+                {
+                  name: "鏈�澶у��",
+                  type: "max",
+                  valueDim: "y",
+                  symbol: "circle",
+                  symbolSize: 6,
+                  itemStyle: {
+                    color: "#FC9010",
+                    shadowColor: "#FC9010",
+                    shadowBlur: 8,
+                  },
+                  label: {
+                    formatter: "",
+                  },
+                },
+              ],
+            },
+          },
+          {
+            data: yData2,
+            type: "line",
+            smooth: true,
+            symbol: "none", //鍘婚櫎鐐�
+            name: "鎶ヨ2娆℃暟",
+            color: "rgba(9,202,243,.7)",
+            areaStyle: {
+                //鍙筹紝涓嬶紝宸︼紝涓�
+                color: new graphic.LinearGradient(
+                  0,
+                  0,
+                  0,
+                  1,
+                  [
+                    {
+                      offset: 0,
+                      color: "rgba(9,202,243,.7)",
+                    },
+                    {
+                      offset: 1,
+                      color: "rgba(9,202,243,.0)",
+                    },
+                  ],
+                  false
+                ),
+            },
+            markPoint: {
+              data: [
+                {
+                  name: "鏈�澶у��",
+                  type: "max",
+                  valueDim: "y",
+                  symbol: "rect",
+                  symbolSize: [60, 26],
+                  symbolOffset: [0, -20],
+                  itemStyle: {
+                    color: "rgba(0,0,0,0)",
+                  },
+                  label: {
+                    color: "#09CAF3",
+                    backgroundColor: "rgba(9,202,243,0.1)",
 
+                    borderRadius: 6,
+                    borderColor: "rgba(9,202,243,.5)",
+                    padding: [7, 14],
+                    formatter: "鎶ヨ2锛歿c}",
+                    borderWidth: 0.5,
+                  },
+                },
+                {
+                  name: "鏈�澶у��",
+                  type: "max",
+                  valueDim: "y",
+                  symbol: "circle",
+                  symbolSize: 6,
+                  itemStyle: {
+                    color: "#09CAF3",
+                    shadowColor: "#09CAF3",
+                    shadowBlur: 8,
+                  },
+                  label: {
+                    formatter: "",
+                  },
+                },
+              ],
+            },
+          },
+        ],
+      };
+}
+onMounted(()=>{
+    getData();
+
+})
 </script>
 
 <template>
-  <div class=''>
-
-  </div>
+  <v-chart
+    class="chart"
+    :option="option"
+    v-if="JSON.stringify(option) != '{}'"
+  />
 </template>
 
-<style scoped lang='scss'>
-
-</style>
\ No newline at end of file
+<style scoped lang="scss"></style>
diff --git a/src/views/setting.vue b/src/views/setting.vue
index 92e0d99..1302013 100644
--- a/src/views/setting.vue
+++ b/src/views/setting.vue
@@ -26,7 +26,7 @@
 </script>
 
 <template>
-  <el-drawer v-model="settingStore.settingShow" direction="rtl">
+  <el-drawer v-model="settingStore.settingShow" direction="rtl" size="360px">
     <template #header>
       <h2 class="setting-title">璁剧疆</h2>
     </template>

--
Gitblit v1.8.0