feat: 外观、撑杆、钩机监测模块的图表对接接口

dev
donghao 2 weeks ago
parent abbab281af
commit d364741783

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-07 15:09:18
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-14 11:14:15
* @LastEditTime: 2025-08-26 16:54:54
* @FilePath: \5G-Loading-Bay-Web\src\api\dashboard.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
@ -94,3 +94,14 @@ export const getVehiclManagementApi = (params: any) => {
export const getBeforeMonitorDetailApi = (params: any) => {
return request.get(`/api/v1/record/before_arrive_record_list/`, params);
};
// 图表统计1 type有appearance、pole、distance。dateType有day、hour分别对应日和时
export const getRecordAmountDataApi = (params: any) => {
return request.get(`/api/v1/record/get_record_amount_data/`, params);
};
// 图表统计2 ?type=pole&dateType=day 这个是日异常类型的接口
export const getRecordFaultTypeAmountDataApi = (params: any) => {
return request.get(`/api/v1/record/get_record_fault_type_amount_data/`, params);
};

@ -2,95 +2,145 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-08-14 10:33:46
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-08-20 14:35:52
* @LastEditTime: 2025-08-27 16:22:40
* @FilePath: \5G-Web\src\components\Charts\appearanceDailyAlertChart.vue
* @Description: 外观日告警统计
-->
<script lang="ts" setup>
import * as echarts from "echarts";
const props = defineProps({
datas: {
type: Object,
default: () => {},
},
});
function initChart() {
const chartDom = document.getElementById("appearanceDailyAlertChart");
const mainChart = echarts.init(chartDom);
const xAxisData = [
"1日",
"2日",
"3日",
"4日",
"5日",
"6日",
"7日",
"8日",
"9日",
"10日",
"11日",
"12日",
"13日",
"14日",
"15日",
"16日",
];
const mockData = [
// TODO
let xAxisData = [];
let typesData = [];
for (let key in props.datas) {
xAxisData.push(key + "日");
if (props.datas[key] && Object.keys(props.datas[key])?.length) {
typesData.push(...Object.keys(props.datas[key]));
}
}
typesData = Array.from(new Set(typesData));
console.log(typesData, "typesData");
const colorArrs = [
{
name: "搭扣未搭",
data: [
80, 30, 120, 80, 100, 60, 70, 50, 40, 60, 110, 30, 80, 100, 120, 150,
],
name: "搭扣未扣",
color: "rgba(212, 145, 20, 0.9)",
color1: "rgba(212, 145, 20, 0.3)",
},
{
name: "小门搭扣丢失",
data: [
100, 20, 220, 180, 120, 180, 100, 120, 100, 140, 160, 20, 180, 140, 80,
170,
],
name: "小门搭扣丢失",
color: "rgba(0, 157, 255, 0.9)",
color1: "rgba(0, 157, 255, 0.3)",
},
{
name: "门折页座脱落",
data: [
150, 180, 200, 190, 180, 50, 80, 100, 80, 140, 120, 190, 150, 60, 100,
120,
],
color: "rgba(44, 188, 204, 0.9)",
color1: "rgba(44, 188, 204, 0.3)",
},
{
name: "下侧门板缺失",
data: [
120, 140, 180, 170, 80, 140, 130, 110, 140, 100, 100, 140, 120, 80, 140,
140,
],
color: "rgba(13, 233, 138, 0.9)",
color1: "rgba(13, 233, 138, 0.3)",
},
{
name: "小门外胀",
data: [
100, 120, 80, 100, 50, 70, 150, 120, 100, 140, 60, 100, 60, 150, 120,
170,
],
name: "小门外胀",
color: "rgba(198, 81, 14, 0.9)",
color1: "rgba(198, 81, 14, 0.3)",
},
{
name: "小窗裂纹",
data: [
150, 160, 180, 170, 150, 80, 100, 140, 120, 80, 140, 80, 120, 80, 100,
150,
],
name: "小窗裂纹",
color: "rgba(255, 209, 92, 0.9)",
color1: "rgba(255, 209, 92, 0.3)",
},
];
// const startData = [
// {
// name: "",
// data: [
// 80, 30, 120, 80, 100, 60, 70, 50, 40, 60, 110, 30, 80, 100, 120, 150,
// ],
// color: "rgba(212, 145, 20, 0.9)",
// color1: "rgba(212, 145, 20, 0.3)",
// },
// {
// name: "",
// data: [
// 100, 20, 220, 180, 120, 180, 100, 120, 100, 140, 160, 20, 180, 140, 80,
// 170,
// ],
// color: "rgba(0, 157, 255, 0.9)",
// color1: "rgba(0, 157, 255, 0.3)",
// },
// {
// name: "",
// data: [
// 150, 180, 200, 190, 180, 50, 80, 100, 80, 140, 120, 190, 150, 60, 100,
// 120,
// ],
// color: "rgba(44, 188, 204, 0.9)",
// color1: "rgba(44, 188, 204, 0.3)",
// },
// {
// name: "",
// data: [
// 120, 140, 180, 170, 80, 140, 130, 110, 140, 100, 100, 140, 120, 80, 140,
// 140,
// ],
// color: "rgba(13, 233, 138, 0.9)",
// color1: "rgba(13, 233, 138, 0.3)",
// },
// {
// name: "",
// data: [
// 100, 120, 80, 100, 50, 70, 150, 120, 100, 140, 60, 100, 60, 150, 120,
// 170,
// ],
// color: "rgba(198, 81, 14, 0.9)",
// color1: "rgba(198, 81, 14, 0.3)",
// },
// {
// name: "",
// data: [
// 150, 160, 180, 170, 150, 80, 100, 140, 120, 80, 140, 80, 120, 80, 100,
// 150,
// ],
// color: "rgba(255, 209, 92, 0.9)",
// color1: "rgba(255, 209, 92, 0.3)",
// },
// ];
let finalData = [];
colorArrs.forEach((lineItem, lineIndex) => {
const currInitValues = new Array(xAxisData.length).fill(0);
Object.keys(props.datas).forEach((key, index) => {
if (
props.datas[key] &&
Object.keys(props.datas[key]).includes(lineItem.name)
) {
currInitValues[index] = props.datas[key][lineItem.name];
}
});
// for (let key in props.datas) {
// if(props.datas[key] && Object.keys(props.datas[key]).includes(lineItem.name)){
// currInitValues[Number(key)-1] = props.datas[key][lineItem.name];
// }
// }
finalData.push({
...lineItem,
data: currInitValues,
});
});
const seriesOptions = [];
const legendData = [];
mockData.forEach((item) => {
finalData.forEach((item) => {
legendData.push(item.name);
seriesOptions.push({
name: item.name,
@ -188,10 +238,18 @@ function initChart() {
};
mainChart.setOption(option);
}
onMounted(() => {
initChart();
});
watch(
() => props.datas,
(newVal) => {
if (newVal) {
initChart();
}
},
{
deep: true,
}
);
</script>
<template>
<div id="appearanceDailyAlertChart" style="width: 100%; height: 100%"></div>
<div id="appearanceDailyAlertChart" style="width: 960px; height: 100%"></div>
</template>

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-08-14 10:33:22
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-08-20 16:03:07
* @LastEditTime: 2025-08-26 17:09:24
* @FilePath: \5G-Web\src\components\Charts\appearanceDailyDetectionChart.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
@ -11,79 +11,88 @@ import * as echarts from "echarts";
const props = defineProps({
datas: {
type: Array as PropType<Record<string, any>[]>,
default: () => [],
type: Object,
default: () => {},
},
});
function initChart() {
const chartDom = document.getElementById("appearanceDailyDetectionChart");
const mainChart = echarts.init(chartDom);
const data1 = [
{
name: "1日",
value: 175,
},
{
name: "2日",
value: 148,
},
{
name: "3日",
value: 195,
},
{
name: "4日",
value: 115,
},
{
name: "5日",
value: 148,
},
{
name: "6日",
value: 95,
},
{
name: "7日",
value: 56,
},
{
name: "8日",
value: 45,
},
{
name: "9日",
value: 15,
},
{
name: "10日",
value: 48,
},
{
name: "11日",
value: 95,
},
{
name: "12日",
value: 128,
},
{
name: "13日",
value: 34,
},
{
name: "14日",
value: 123,
},
{
name: "15日",
value: 175,
},
{
name: "16日",
value: 148,
},
];
let finalData = [];
for (let key in props.datas) {
finalData.push({
name: key + "日",
value: props.datas[key],
});
}
// TODO mock
// const finalData = [
// {
// name: "1",
// value: 175,
// },
// {
// name: "2",
// value: 148,
// },
// {
// name: "3",
// value: 195,
// },
// {
// name: "4",
// value: 115,
// },
// {
// name: "5",
// value: 148,
// },
// {
// name: "6",
// value: 95,
// },
// {
// name: "7",
// value: 56,
// },
// {
// name: "8",
// value: 45,
// },
// {
// name: "9",
// value: 15,
// },
// {
// name: "10",
// value: 48,
// },
// {
// name: "11",
// value: 95,
// },
// {
// name: "12",
// value: 128,
// },
// {
// name: "13",
// value: 34,
// },
// {
// name: "14",
// value: 123,
// },
// {
// name: "15",
// value: 175,
// },
// {
// name: "16",
// value: 148,
// },
// ];
const createSvg = (shadowColor, shadowBlur) => `
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
x="0px" y="0px"
@ -111,7 +120,6 @@ function initChart() {
<path class="st2" d="M0 0 L32 0 L32 128 L0 128 Z" />
</svg>
`;
const svgString = createSvg("rgba(7, 131, 250, 1)", 8);
const svg = new Blob([svgString], { type: "image/svg+xml;charset=utf-8" });
const barWidth = 16;
@ -119,7 +127,7 @@ function initChart() {
const insetShadowUrl = DOMURL.createObjectURL(svg);
let xAxisData = [];
let seriesData1 = [];
data1.forEach((item) => {
finalData.forEach((item) => {
xAxisData.push(item.name);
seriesData1.push(item.value);
});
@ -211,9 +219,17 @@ function initChart() {
mainChart.setOption(option);
}
onMounted(() => {
initChart();
});
watch(
() => props.datas,
(newVal) => {
if (newVal) {
initChart();
}
},
{
deep: true,
}
);
</script>
<template>
@ -221,6 +237,6 @@ onMounted(() => {
class="main-chart"
ref="mainChartRef"
id="appearanceDailyDetectionChart"
style="width: 100%; height: 100%"
style="width: 862px; height: 100%"
></div>
</template>

@ -1,79 +1,92 @@
<script setup lang="ts">
import * as echarts from "echarts";
const props = defineProps({
datas: {
type: Object,
default: () => {},
},
});
function initChart() {
const chartDom = document.getElementById("diggerDailyDistanceChart");
const mainChart = echarts.init(chartDom);
let finalData = [];
let data1 = [
{
name: "1日",
value: 175,
},
{
name: "2日",
value: 148,
},
{
name: "3日",
value: 195,
},
{
name: "4日",
value: 115,
},
{
name: "5日",
value: 148,
},
{
name: "6日",
value: 95,
},
{
name: "7日",
value: 56,
},
{
name: "8日",
value: 45,
},
{
name: "9日",
value: 15,
},
{
name: "10日",
value: 48,
},
{
name: "11日",
value: 95,
},
{
name: "12日",
value: 128,
},
{
name: "13日",
value: 34,
},
{
name: "14日",
value: 123,
},
{
name: "15日",
value: 175,
},
{
name: "16日",
value: 148,
},
];
for (let key in props.datas) {
finalData.push({
name: key + "日",
value: props.datas[key],
});
}
// let finalData = [
// {
// name: "1",
// value: 175,
// },
// {
// name: "2",
// value: 148,
// },
// {
// name: "3",
// value: 195,
// },
// {
// name: "4",
// value: 115,
// },
// {
// name: "5",
// value: 148,
// },
// {
// name: "6",
// value: 95,
// },
// {
// name: "7",
// value: 56,
// },
// {
// name: "8",
// value: 45,
// },
// {
// name: "9",
// value: 15,
// },
// {
// name: "10",
// value: 48,
// },
// {
// name: "11",
// value: 95,
// },
// {
// name: "12",
// value: 128,
// },
// {
// name: "13",
// value: 34,
// },
// {
// name: "14",
// value: 123,
// },
// {
// name: "15",
// value: 175,
// },
// {
// name: "16",
// value: 148,
// },
// ];
let xAxisData = [];
let seriesData2 = [];
data1.forEach((item) => {
finalData.forEach((item) => {
xAxisData.push(item.name);
seriesData2.push(item.value);
});
@ -185,11 +198,19 @@ function initChart() {
mainChart.setOption(option);
}
onMounted(() => {
initChart();
});
watch(
() => props.datas,
(newVal) => {
if (newVal) {
initChart();
}
},
{
deep: true,
}
);
</script>
<template>
<div id="diggerDailyDistanceChart" style="width: 100%; height: 100%"></div>
<div id="diggerDailyDistanceChart" style="width: 960px; height: 100%"></div>
</template>

@ -1,5 +1,11 @@
<script setup lang="ts">
import * as echarts from "echarts";
const props = defineProps({
datas: {
type: Object,
default: () => {},
},
});
function generateData(totalNum, bigvalue, smallvalue, color) {
let dataArr = [];
for (var i = 0; i < totalNum; i++) {
@ -28,103 +34,100 @@ function generateData(totalNum, bigvalue, smallvalue, color) {
function initChart() {
const chartDom = document.getElementById("diggerHourlyDistanceChart");
const mainChart = echarts.init(chartDom);
let finalData = [];
let data1 = [
{
name: "05:00",
value: 175,
},
{
name: "06:00",
value: 148,
},
{
name: "07:00",
value: 95,
},
{
name: "08:00",
value: 175,
},
{
name: "09:00",
value: 148,
},
{
name: "10:00",
value: 95,
},
{
name: "11:00",
value: 56,
},
{
name: "12:00",
value: 45,
},
{
name: "13:00",
value: 34,
},
{
name: "14:00",
value: 123,
},
{
name: "15:00",
value: 175,
},
{
name: "16:00",
value: 148,
},
{
name: "17:00",
value: 95,
},
{
name: "18:00",
value: 123,
},
{
name: "19:00",
value: 175,
},
{
name: "20:00",
value: 148,
},
{
name: "21:00",
value: 95,
},
{
name: "22:00",
value: 148,
},
{
name: "23:00",
value: 95,
},
];
for (let key in props.datas) {
finalData.push({
name: key + ":00",
value: props.datas[key],
});
}
// let finalData = [
// {
// name: "05:00",
// value: 175,
// },
// {
// name: "06:00",
// value: 148,
// },
// {
// name: "07:00",
// value: 95,
// },
// {
// name: "08:00",
// value: 175,
// },
// {
// name: "09:00",
// value: 148,
// },
// {
// name: "10:00",
// value: 95,
// },
// {
// name: "11:00",
// value: 56,
// },
// {
// name: "12:00",
// value: 45,
// },
// {
// name: "13:00",
// value: 34,
// },
// {
// name: "14:00",
// value: 123,
// },
// {
// name: "15:00",
// value: 175,
// },
// {
// name: "16:00",
// value: 148,
// },
// {
// name: "17:00",
// value: 95,
// },
// {
// name: "18:00",
// value: 123,
// },
// {
// name: "19:00",
// value: 175,
// },
// {
// name: "20:00",
// value: 148,
// },
// {
// name: "21:00",
// value: 95,
// },
// {
// name: "22:00",
// value: 148,
// },
// {
// name: "23:00",
// value: 95,
// },
// ];
let xAxisData = [];
let seriesData1 = [];
data1.forEach((item) => {
finalData.forEach((item) => {
xAxisData.push(item.name);
seriesData1.push(item.value);
});
const yList = [80, 100, 100, 100];
const xList = ["寿命≤100", "100<寿命≤200", "200<寿命≤300", "寿命>300"];
const color = ["#00FEEE", "#2fd28d", "#c4742d", "#c42d2d"];
const xData = xList.map((item, index) => {
return {
value: item,
textStyle: {
color: color[index],
},
};
});
const dom = 200;
const barWidth = dom / 10;
const colors = [
@ -282,11 +285,19 @@ function initChart() {
mainChart.setOption(option);
}
onMounted(() => {
initChart();
});
watch(
() => props.datas,
(newVal) => {
if (newVal) {
initChart();
}
},
{
deep: true,
}
);
</script>
<template>
<div id="diggerHourlyDistanceChart" style="width: 100%; height: 100%"></div>
<div id="diggerHourlyDistanceChart" style="width: 862px; height: 100%"></div>
</template>

@ -0,0 +1,231 @@
<script setup lang="ts">
import * as echarts from "echarts";
function generateData(totalNum, bigvalue, smallvalue, color) {
let dataArr = [];
for (const i = 0; i < totalNum; i++) {
if (i % 2 === 0) {
dataArr.push({
name: (i + 1).toString(),
value: bigvalue,
itemStyle: {
color: color,
borderWidth: 0,
},
});
} else {
dataArr.push({
name: (i + 1).toString(),
value: smallvalue,
itemStyle: {
color: "rgba(0,0,0,0)",
borderWidth: 0,
},
});
}
}
return dataArr;
}
function initChart() {
const chartDom = document.getElementById("dvDeviceInfoChart");
const mainChart = echarts.init(chartDom);
const value = [965, 1155, 872];
const value1 = [0.65, 0.12, -0.33];
const max1 = Math.max.apply(null, value) * 1.2;
const data1 = [];
//data1for使value
for (let i = value.length - 1; i >= 0; i--) {
data1.push(max1);
}
const option = {
backgroundColor: "transparent",
grid: {
left: "5%",
top: "5%",
bottom: "5%",
right: "5%",
containLabel: true,
},
xAxis: {
type: "value",
max: max1,
splitLine: {
show: false,
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
show: false,
},
},
yAxis: {
type: "category",
splitLine: {
show: false,
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
show: true,
interval: 0,
margin: 0,
verticalAlign: "right",
align: "left",
padding: [-30, 0, 0, 0],
textStyle: {
color: "#ffffff",
fontSize: 16,
},
},
data: ["周一", "周二", "周三"],
},
series: [
{
//
name: "真实值",
type: "bar",
animation: false,
barWidth: "5%",
label: {
show: true,
position: "insideLeft",
padding: [50, 0, 0, -15],
distance: 15,
//color: co1,
formatter: function (params) {
//console.info(params);
if (value1[params.dataIndex] < 0) {
return (
"{a|较上年}{b|" +
(value1[params.dataIndex] * 100).toFixed(0) +
"%}"
);
} else {
return (
"{a|较上年}{c|+" +
(value1[params.dataIndex] * 100).toFixed(0) +
"%}"
);
}
},
rich: {
a: {
fontSize: 12,
color: "#fff",
//padding: [20, -30, 0, -30],
},
b: {
fontSize: 12,
color: "#13C2C2",
fontWeight: "bold",
padding: [0, 0, 0, 15],
},
c: {
fontSize: 12,
color: "#FF4242",
fontWeight: "bold",
padding: [0, 0, 0, 15],
},
},
},
itemStyle: {
normal: {
color: {
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [
{
offset: 0,
color: "rgba(2,50,147,1)", // 0%
},
{
offset: 1,
color: "rgba(36,237,255,1)", // 100%
},
],
},
},
},
data: value,
z: 1,
},
{
//1
name: "真实值圆点",
type: "scatter",
symbolOffset: ["10%", "0"],
symbolSize: 8,
itemStyle: {
borderWidth: 0,
color: "rgba(255,255,255,1)",
},
data: value,
z: 5,
},
{
//2
name: "真实值圆环",
type: "scatter",
symbolOffset: ["10%", "0"],
symbolSize: 15,
itemStyle: {
borderWidth: 1,
borderColor: "rgba(101,224,255,1)",
//shadowBlur: 15,
//shadowColor: 'rgba(101,224,255,1)',
color: "rgba(255,255,255,0.43)",
},
data: value,
z: 10,
},
{
//3
name: "背景条",
type: "bar",
animation: false,
barGap: "-100%",
barWidth: "5%",
label: {
show: true,
position: "insideRight",
verticalAlign: "right",
padding: [-30, -10, 0, 0],
distance: 15,
color: "#fff",
formatter: function (params) {
//console.info(params);
return " " + value[params.dataIndex].toFixed(0);
},
},
itemStyle: {
normal: {
color: "rgba(62,78,123,1)",
},
},
data: data1,
z: 0,
},
],
};
mainChart.setOption(option);
}
onMounted(() => {
initChart();
});
</script>
<template>
<div id="dvDeviceInfoChart" style="width: 100%; height: 100%"></div>
</template>

@ -1,139 +1,71 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-08-14 10:31:16
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-08-27 13:44:55
* @FilePath: \5G-Web\src\components\Charts\poleDailyAlertChart.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<script lang="ts" setup>
import * as echarts from "echarts";
const props = defineProps({
data: {
type: Array as PropType<Array<{ value: number; name: string }>>,
required: true,
datas: {
type: Object,
default: () => {},
},
});
// const propsData = {
// xAxisData: [
// "1",
// "2",
// "3",
// "4",
// "5",
// "6",
// "7",
// "8",
// "9",
// "10",
// "11",
// "12",
// "13",
// "14",
// "15",
// "16",
// ],
// legendData: ["", "", "穿"],
// seriesData: {
// : [
// 210, 80, 120, 100, 90, 120, 110, 140, 130, 120, 120, 125, 130, 160, 150,
// 100,
// ],
// : [
// 70, 110, 140, 120, 140, 70, 80, 170, 160, 140, 140, 130, 140, 120, 90,
// 110,
// ],
// 穿: [
// 80, 150, 180, 160, 80, 60, 70, 180, 190, 170, 160, 140, 130, 80, 100,
// 150,
// ],
// },
// };
const propsData = {
xData: [
"1日",
"2日",
"3日",
"4日",
"5日",
"6日",
"7日",
"8日",
"9日",
"10日",
"11日",
"12日",
"13日",
"14日",
"15日",
"16日",
],
legendData: ["撑杆断裂", "撑杆锈蚀", "撑杆穿孔"],
seriesData: {
撑杆断裂: [
210, 80, 120, 100, 90, 120, 110, 140, 130, 120, 120, 125, 130, 160, 150,
100,
],
撑杆锈蚀: [
70, 110, 140, 120, 140, 70, 80, 170, 160, 140, 140, 130, 140, 120, 90,
110,
],
撑杆穿孔: [
80, 150, 180, 160, 80, 60, 70, 180, 190, 170, 160, 140, 130, 80, 100, 150,
],
},
};
let xData = propsData.xData;
let legendData = propsData.legendData; //
const option = {
backgroundColor: "#061740",
grid: {
x: 0,
y: 0,
x2: 0,
y2: 0,
left: "1%",
right: "1%",
bottom: "5%",
top: "25%",
containLabel: true,
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
crossStyle: {
color: "#999",
},
},
},
legend: {
left: "right",
top: "1",
padding: [10, 0, 0, 0],
data: legendData,
//
// type: 'scroll',
//
textStyle: {
color: "#fff",
fontSize: "14px",
},
},
xAxis: [
{
type: "category",
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
color: "#B4C0CC",
},
data: xData,
},
],
yAxis: [
{
type: "value",
// interval: 50,
axisLabel: {
formatter: "{value} ",
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
color: "#B4C0CC",
},
//线
splitLine: {
show: true,
lineStyle: {
type: "solid", //solid线;dashed线
color: "rgba(36, 173, 254, 0.2)",
},
},
},
],
series: [
const initChart = () => {
const chartDom = document.getElementById("poleDailyAlertChart");
const mainChart = echarts.init(chartDom);
const seriesBaseData = [
{
name: "撑杆断裂",
data: propsData.seriesData["撑杆断裂"],
// name: "",
// data: propsData.seriesData[""],
type: "line",
smooth: true, //true线; false线
symbol: "none",
itemStyle: {
color: "#ffc600", //线
lineStyle: {
color: "#ffc600", //线
type: "solid",
},
color: "#ffc600", //线
lineStyle: {
color: "#ffc600", //线
type: "solid",
},
},
areaStyle: {
//线
@ -158,18 +90,18 @@ const option = {
},
},
{
name: "撑杆锈蚀",
data: propsData.seriesData["撑杆锈蚀"],
// name: "",
// data: propsData.seriesData[""],
type: "line",
smooth: true, //true线; false线
symbol: "none",
itemStyle: {
color: "#24adfe", //线
lineStyle: {
color: "#24adfe", //线
type: "solid",
},
lineStyle: {
color: "#24adfe", //线
type: "solid",
},
},
areaStyle: {
//线
@ -194,18 +126,18 @@ const option = {
},
},
{
name: "撑杆穿孔",
data: propsData.seriesData["撑杆穿孔"],
// name: "穿",
// data: propsData.seriesData["穿"],
type: "line",
smooth: true, //true线; false线
symbol: "none",
itemStyle: {
color: "#0DE98A", //线
lineStyle: {
color: "#0DE98A", //线
type: "solid",
},
lineStyle: {
color: "#0DE98A", //线
type: "solid",
},
},
areaStyle: {
//线
@ -229,19 +161,125 @@ const option = {
},
},
},
],
};
];
const maxTypesLength = seriesBaseData.length;
const initChart = () => {
const chartDom = document.getElementById("poleDailyAlertChart");
const mainChart = echarts.init(chartDom);
let xAxisData = [];
let typesData = [];
for (let key in props.datas) {
xAxisData.push(key + "日");
if (props.datas[key] && Object.keys(props.datas[key])?.length) {
typesData.push(...Object.keys(props.datas[key]));
}
}
const legendData = Array.from(new Set(typesData)).slice(0, maxTypesLength);
let finalSeriesData = [];
legendData.forEach((v, vIndex) => {
const currInitValues = new Array(xAxisData.length).fill(0);
Object.keys(props.datas).forEach((key, index) => {
if (props.datas[key] && Object.keys(props.datas[key]).includes(v)) {
currInitValues[index] = props.datas[key][v];
}
});
finalSeriesData.push({
...seriesBaseData[vIndex],
name: v,
data: currInitValues,
});
});
const option = {
backgroundColor: "#061740",
grid: {
x: 0,
y: 0,
x2: 0,
y2: 0,
left: "1%",
right: "1%",
bottom: "5%",
top: "25%",
containLabel: true,
},
tooltip: {
trigger: "axis",
},
legend: {
left: "right",
top: "1",
padding: [10, 0, 0, 0],
data: legendData,
//
// type: 'scroll',
//
textStyle: {
color: "#fff",
fontSize: "14px",
},
},
xAxis: [
{
type: "category",
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
color: "#B4C0CC",
},
data: xAxisData,
},
],
yAxis: [
{
type: "value",
interval: 1,
axisLabel: {
formatter: "{value} ",
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
color: "#B4C0CC",
},
//线
splitLine: {
show: true,
lineStyle: {
type: "solid", //solid线;dashed线
color: "rgba(36, 173, 254, 0.2)",
},
},
},
],
series: finalSeriesData,
};
mainChart.setOption(option);
};
onMounted(() => {
initChart();
});
watch(
() => props.datas,
(newVal) => {
if (newVal) {
initChart();
}
},
{
deep: true,
}
);
</script>
<template>
<div id="poleDailyAlertChart" style="width: 100%; height: 100%"></div>
<div id="poleDailyAlertChart" style="width: 960px; height: 100%"></div>
</template>

@ -1,206 +1,222 @@
<script lang="ts" setup>
import * as echarts from "echarts";
const props = defineProps({
data: {
type: Array as PropType<Array<{ value: number; name: string }>>,
required: true,
datas: {
type: Object,
default: () => {},
},
});
const data1 = [
{
name: "1日",
value: 220,
},
{
name: "2日",
value: 148,
},
{
name: "3日",
value: 195,
},
{
name: "4日",
value: 245,
},
{
name: "5日",
value: 148,
},
{
name: "6日",
value: 95,
},
{
name: "7日",
value: 56,
},
{
name: "8日",
value: 45,
},
{
name: "9日",
value: 250,
},
{
name: "10日",
value: 48,
},
{
name: "11日",
value: 95,
},
{
name: "12日",
value: 128,
},
{
name: "13日",
value: 34,
},
{
name: "14日",
value: 123,
},
{
name: "15日",
value: 175,
},
{
name: "16日",
value: 148,
},
];
let xAxisData = [];
let seriesData1 = [];
data1.forEach((item) => {
xAxisData.push(item.name);
seriesData1.push(item.value);
});
var barWidth = 16;
var barWidthBg = 25;
const color = [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 1,
color: "rgba(16, 53, 41, 0.10)",
},
{
offset: 0,
color: "rgba(57, 161, 59, 1)",
},
],
},
];
const seriesData = xAxisData.map((item, index) => {
return {
value: seriesData1[index],
itemStyle: {
borderRadius: [2, 2, 0, 0],
color: color[0],
},
};
});
const option = {
grid: {
left: "1%",
right: "1%",
bottom: "5%",
top: "15%",
containLabel: true,
},
xAxis: {
data: xAxisData,
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
show: true,
color: "#B4C0CC",
fontSize: 12,
const initChart = () => {
const chartDom = document.getElementById("poleDailyDetectionChart");
const mainChart = echarts.init(chartDom);
let finalData = [];
for (let key in props.datas) {
finalData.push({
name: key + "日",
value: props.datas[key],
});
}
// const data1 = [
// {
// name: "1",
// value: 220,
// },
// {
// name: "2",
// value: 148,
// },
// {
// name: "3",
// value: 195,
// },
// {
// name: "4",
// value: 245,
// },
// {
// name: "5",
// value: 148,
// },
// {
// name: "6",
// value: 95,
// },
// {
// name: "7",
// value: 56,
// },
// {
// name: "8",
// value: 45,
// },
// {
// name: "9",
// value: 250,
// },
// {
// name: "10",
// value: 48,
// },
// {
// name: "11",
// value: 95,
// },
// {
// name: "12",
// value: 128,
// },
// {
// name: "13",
// value: 34,
// },
// {
// name: "14",
// value: 123,
// },
// {
// name: "15",
// value: 175,
// },
// {
// name: "16",
// value: 148,
// },
// ];
let xAxisData = [];
let seriesData1 = [];
finalData.forEach((item) => {
xAxisData.push(item.name);
seriesData1.push(item.value);
});
var barWidth = 16;
var barWidthBg = 25;
const color = [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 1,
color: "rgba(16, 53, 41, 0.10)",
},
{
offset: 0,
color: "rgba(57, 161, 59, 1)",
},
],
},
},
yAxis: {
axisLine: {
show: true,
lineStyle: {
color: "#B4C0CC",
];
const seriesData = xAxisData.map((item, index) => {
return {
value: seriesData1[index],
itemStyle: {
borderRadius: [2, 2, 0, 0],
color: color[0],
},
};
});
const option = {
grid: {
left: "1%",
right: "1%",
bottom: "5%",
top: "15%",
containLabel: true,
},
axisLabel: {
show: true,
color: "#B4C0CC",
fontSize: 12,
},
splitLine: {
lineStyle: {
xAxis: {
data: xAxisData,
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
show: true,
color: "#B4C0CC",
opacity: 0.2,
fontSize: 12,
},
},
},
series: [
{
type: "bar",
data: seriesData,
barWidth: barWidth,
},
{
type: "bar",
data: seriesData,
barWidth: barWidthBg,
barGap: "-120%",
itemStyle: {
opacity: 0.2,
yAxis: {
axisLine: {
show: true,
lineStyle: {
color: "#B4C0CC",
},
},
},
{
type: "pictorialBar",
data: seriesData,
symbolPosition: "end",
symbolSize: [barWidth, 7],
z: 12,
symbolOffset: [-3, -3],
label: {
axisLabel: {
show: true,
position: "top",
color: "#B4C0CC",
fontSize: 12,
},
},
{
type: "pictorialBar",
data: seriesData,
symbolPosition: "end",
symbolSize: [barWidthBg, 6],
itemStyle: {
opacity: 0.2,
splitLine: {
lineStyle: {
color: "#B4C0CC",
opacity: 0.2,
},
},
z: 11,
symbolOffset: [-3, -3],
},
],
};
const initChart = () => {
const chartDom = document.getElementById("poleDailyDetectionChart");
const mainChart = echarts.init(chartDom);
series: [
{
type: "bar",
data: seriesData,
barWidth: barWidth,
},
{
type: "bar",
data: seriesData,
barWidth: barWidthBg,
barGap: "-120%",
itemStyle: {
opacity: 0.2,
},
},
{
type: "pictorialBar",
data: seriesData,
symbolPosition: "end",
symbolSize: [barWidth, 7],
z: 12,
symbolOffset: [-3, -3],
label: {
show: true,
position: "top",
},
},
{
type: "pictorialBar",
data: seriesData,
symbolPosition: "end",
symbolSize: [barWidthBg, 6],
itemStyle: {
opacity: 0.2,
},
z: 11,
symbolOffset: [-3, -3],
},
],
};
mainChart.setOption(option);
};
onMounted(() => {
initChart();
});
watch(
() => props.datas,
(newVal) => {
if (newVal) {
initChart();
}
},
{
deep: true,
}
);
</script>
<template>
<div id="poleDailyDetectionChart" style="width: 100%; height: 100%"></div>
<div id="poleDailyDetectionChart" style="width: 862px; height: 100%"></div>
</template>

@ -233,7 +233,7 @@
padding-bottom: 1px;
}
.fg-footer-charts-content {
overflow: hidden;
// overflow: hidden;
max-width: 100%;
height: 195px;
// background-color: red;

@ -11,6 +11,8 @@ import {
getAppearanceMonitorApi,
getAppearanceMonitorDetailApi,
getBeforeMonitorDetailApi,
getRecordAmountDataApi,
getRecordFaultTypeAmountDataApi
} from "@/api/dashboard";
import { isSuccessApi } from "@/utils/forApi";
import { useWebSocketStore } from "@/stores/websocketStore";
@ -19,6 +21,8 @@ import { useWebSocketStore } from "@/stores/websocketStore";
const isAlarmOpen = ref<Boolean>(false); //
const isDeleteOpen = ref<Boolean>(false); //
const websocketStore = useWebSocketStore();
// messages
watch(
() => websocketStore.messages,
@ -97,6 +101,10 @@ const searchForm = reactive({
});
const dataLoading = ref(true);
const recordAmountData = ref({}); //
const recordFaultData = ref({}); //
//
const getFileList = async () => {
try {
@ -173,6 +181,36 @@ const getList = async () => {
console.error("获取数据失败:", error);
}
};
// 1
const fetchRecordAmountData = async () => {
try {
const res = await getRecordAmountDataApi({
type: "appearance",
dateType: "day",
});
console.log(res.data, "fetchRecordAmountData_data");
if (isSuccessApi(res)) {
recordAmountData.value = res.data;
}
} catch (error) {
console.error("获取数据失败:", error);
}
}
// 2
const fetchRecordFaultTypeAmountData = async () => {
try {
const res = await getRecordFaultTypeAmountDataApi({
type: "appearance",
dateType: "day",
});
console.log(res.data, "fetchRecordFaultTypeAmountData_data");
if (isSuccessApi(res)) {
recordFaultData.value = res.data;
}
} catch (error) {
console.error("获取数据失败:", error);
}
}
//
const handleQuery = () => {
@ -231,6 +269,8 @@ onBeforeRouteLeave(() => {
onMounted(() => {
getList();
fetchRecordAmountData()
fetchRecordFaultTypeAmountData()
});
</script>
<template>
@ -341,13 +381,13 @@ onMounted(() => {
<li>
<div class="fg-footer-charts-title">日检出量</div>
<div class="fg-footer-charts-content">
<AppearanceDailyDetectionChart :datas="[]" />
<AppearanceDailyDetectionChart :datas="recordAmountData" />
</div>
</li>
<li>
<div class="fg-footer-charts-title">日告警分类</div>
<div class="fg-footer-charts-content">
<AppearanceDailyAlertChart :data="[]" />
<AppearanceDailyAlertChart :datas="recordFaultData" />
</div>
</li>
</ul>

@ -11,6 +11,7 @@ import {
getAppearanceMonitorDetailApi,
getBeforeMonitorDetailApi,
deleteAppearanceMonitorApi,
getRecordAmountDataApi,
} from "@/api/dashboard";
import { isSuccessApi } from "@/utils/forApi";
import { useWebSocketStore } from "@/stores/websocketStore";
@ -18,6 +19,9 @@ import { useWebSocketStore } from "@/stores/websocketStore";
const isAlarmOpen = ref<Boolean>(false); //
const isDeleteOpen = ref<Boolean>(false); //
const websocketStore = useWebSocketStore();
const recordDistanceHourData = ref({}); //
const recordDistanceDayData = ref({}); //
// messages
watch(
() => websocketStore.messages,
@ -147,6 +151,36 @@ const getList = async () => {
console.error("获取数据失败:", error);
}
};
// 1
const fetchRecordHourData = async () => {
try {
const res = await getRecordAmountDataApi({
type: "distance",
dateType: "hour",
});
console.log(res.data, "fetchRecordHourData_data");
if (isSuccessApi(res)) {
recordDistanceHourData.value = res.data;
}
} catch (error) {
console.error("获取数据失败:", error);
}
};
// 2
const fetchRecordDayData = async () => {
try {
const res = await getRecordAmountDataApi({
type: "distance",
dateType: "day",
});
console.log(res.data, "fetchRecordDayData_data");
if (isSuccessApi(res)) {
recordDistanceDayData.value = res.data;
}
} catch (error) {
console.error("获取数据失败:", error);
}
};
//
const handleQuery = () => {
@ -217,6 +251,8 @@ onBeforeRouteLeave(() => {
onMounted(() => {
getList();
fetchRecordHourData();
fetchRecordDayData();
});
</script>
<template>
@ -345,13 +381,13 @@ onMounted(() => {
<li>
<div class="fg-footer-charts-title">分时距离报警</div>
<div class="fg-footer-charts-content">
<DiggerHourlyDistanceChart :data="[]" />
<DiggerHourlyDistanceChart :datas="recordDistanceHourData" />
</div>
</li>
<li>
<div class="fg-footer-charts-title">日距离告警</div>
<div class="fg-footer-charts-content">
<DiggerDailyDistanceChart :data="[]" />
<DiggerDailyDistanceChart :datas="recordDistanceDayData" />
</div>
</li>
</ul>

@ -12,6 +12,8 @@ import VideoExport from "./components/VideoExport.vue";
import {
getAppearanceMonitorApi,
getAppearanceMonitorDetailApi,
getRecordAmountDataApi,
getRecordFaultTypeAmountDataApi
} from "@/api/dashboard";
import { isSuccessApi } from "@/utils/forApi";
import { useWebSocketStore } from "@/stores/websocketStore";
@ -83,7 +85,9 @@ const isPointOpen = ref<Boolean>(false); //点云弹窗
const isAlarmOpen = ref<Boolean>(false); //
const isDeleteOpen = ref<Boolean>(false); //
const websocketStore = useWebSocketStore();
const dailyDetectionData = ref<Record<string, any>[]>([]); // ;
const recordAmountData = ref({}); //
const recordFaultData = ref({}); //
// messages
watch(
() => websocketStore.messages,
@ -158,6 +162,36 @@ const getList = async () => {
console.error("获取数据失败:", error);
}
};
// 1
const fetchRecordAmountData = async () => {
try {
const res = await getRecordAmountDataApi({
type: "pole",
dateType: "day",
});
console.log(res.data, "fetchRecordAmountData_data");
if (isSuccessApi(res)) {
recordAmountData.value = res.data;
}
} catch (error) {
console.error("获取数据失败:", error);
}
}
// 2
const fetchRecordFaultTypeAmountData = async () => {
try {
const res = await getRecordFaultTypeAmountDataApi({
type: "pole",
dateType: "day",
});
console.log(res.data, "fetchRecordFaultTypeAmountData_data");
if (isSuccessApi(res)) {
recordFaultData.value = res.data;
}
} catch (error) {
console.error("获取数据失败:", error);
}
}
//
const handleQuery = () => {
@ -215,6 +249,8 @@ onBeforeRouteLeave(() => {
});
onMounted(() => {
getList();
fetchRecordAmountData()
fetchRecordFaultTypeAmountData()
});
</script>
<template>
@ -325,13 +361,13 @@ onMounted(() => {
<li>
<div class="fg-footer-charts-title">日检出量</div>
<div class="fg-footer-charts-content">
<PoleDailyDetectionChart :data="dailyDetectionData" />
<PoleDailyDetectionChart :datas="recordAmountData" />
</div>
</li>
<li>
<div class="fg-footer-charts-title">日告警分类</div>
<div class="fg-footer-charts-content">
<PoleDailyAlertChart :data="dailyDetectionData" />
<PoleDailyAlertChart :datas="recordFaultData" />
</div>
</li>
</ul>

@ -57,7 +57,9 @@ const deviceStatusOptions = ref<Record<string, any>[]>([
<el-progress
:show-text="false"
:stroke-width="4"
:percentage="100"
:percentage="Math.floor(
(deviceStatus?.[v.valueKey] / deviceStatus?.total) * 100
) || 0"
:color="v.bgColor"
/>
</div>

@ -0,0 +1,92 @@
<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch } from "vue";
import * as echarts from "echarts";
const props = defineProps({
data: {
type: Array as PropType<Array<{ value: number; name: string }>>,
required: true,
},
colors: { type: Array as PropType<Array<string>>, default: () => [] },
});
const chartContainer = ref<HTMLDivElement | null>(null);
let chartInstance: echarts.ECharts | null = null;
const colorsArr = ['#FFCC4A','#028FF5','#06EA7C','#8500FF','#FF7D05','#00D1FF']
//
const initChart = () => {
if (!chartContainer.value) return;
chartInstance = echarts.init(chartContainer.value);
setTimeout(() => {
chartInstance?.resize();
updateChart();
}, 500);
};
//
const updateChart = () => {
if (!chartInstance) return;
chartInstance.setOption({
legend: {
type: "scroll",
orient: "vertical",
left: "70%",
align: "left",
top: "middle",
itemWidth: 16, //
itemHeight: 8,
textStyle: { color: "#FFF" },
},
series: [
{
type: "pie",
radius: ["30%", "80%"],
center: ["35%", "50%"],
label: { show: false },
itemStyle: {
color: (params) =>
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: props.colors[params.dataIndex] },
{ offset: 1, color: colorsArr[params.dataIndex] },
]),
},
data: props.data,
},
],
});
};
//
onMounted(() => {
initChart();
});
onUnmounted(() => {
if (chartInstance) {
chartInstance.dispose();
chartInstance = null;
}
});
//
watch(
() => props.data,
async () => {
await nextTick();
updateChart();
}
);
//
// onMounted(() => {
// window.addEventListener("resize", () => chartInstance?.resize());
// });
// onUnmounted(() => {
// window.removeEventListener("resize", () => chartInstance?.resize());
// });
</script>
<template>
<div ref="chartContainer" style="width: 100%; height: 100%" />
</template>

@ -0,0 +1,92 @@
<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch } from "vue";
import * as echarts from "echarts";
const props = defineProps({
data: {
type: Array as PropType<Array<{ value: number; name: string }>>,
required: true,
},
colors: { type: Array as PropType<Array<string>>, default: () => [] },
});
const chartContainer = ref<HTMLDivElement | null>(null);
let chartInstance: echarts.ECharts | null = null;
const colorsArr = ['#3FE3FA','#FF4D00']
//
const initChart = () => {
if (!chartContainer.value) return;
chartInstance = echarts.init(chartContainer.value);
setTimeout(() => {
chartInstance?.resize();
updateChart();
}, 500);
};
//
const updateChart = () => {
if (!chartInstance) return;
chartInstance.setOption({
legend: {
type: "scroll",
orient: "vertical",
left: "70%",
align: "left",
top: "middle",
itemWidth: 16, //
itemHeight: 8,
textStyle: { color: "#FFF" },
},
series: [
{
type: "pie",
radius: ["40%", "80%"],
center: ["35%", "50%"],
label: { show: false },
itemStyle: {
color: (params) =>
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: props.colors[params.dataIndex] },
{ offset: 1, color: colorsArr[params.dataIndex] },
]),
},
data: props.data,
},
],
});
};
//
onMounted(() => {
initChart();
});
onUnmounted(() => {
if (chartInstance) {
chartInstance.dispose();
chartInstance = null;
}
});
//
watch(
() => props.data,
async () => {
await nextTick();
updateChart();
}
);
//
// onMounted(() => {
// window.addEventListener("resize", () => chartInstance?.resize());
// });
// onUnmounted(() => {
// window.removeEventListener("resize", () => chartInstance?.resize());
// });
</script>
<template>
<div ref="chartContainer" style="width: 100%; height: 100%" />
</template>
Loading…
Cancel
Save