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> </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