尝试完善图表更新 bug 图表无法显示

This commit is contained in:
zwb 2024-07-30 18:15:24 +08:00
parent 30ffdd1782
commit 0d801118cc
3 changed files with 76 additions and 148 deletions

View File

@ -52,50 +52,34 @@ public class ServerController(
[FromQuery] List<string?>? dataTypes = null, [FromQuery] int? startIndex = 0)
{
var userId = HttpContext.User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)!.Value;
//创建一个缓存
Dictionary<string, ServerMonitoringData?> temp = new();
//创建一个时间缓存
//创建查询 流式
var query = dbContext.ServerMonitoringData
.AsNoTracking() // 不追踪实体状态
.Where(x => x.ServerId == serverId) // 筛选服务器ID
.Where(x => dataTypes == null || dataTypes.Contains(x.DataType)) // 如果dataTypes不为空则进一步筛选
.OrderBy(x => x.Time)
.Skip(Math.Max(startIndex ?? 0, 0)) // 跳过指定数量的记录
.Take(1000)
.AsAsyncEnumerable(); // 启用流式查询
Dictionary<string, List<List<object>>> temp = new();
await foreach (var data in query)
{
//计算两者时间差 按秒分割
if (!temp.TryGetValue(data.DataType, out var tempData)) tempData = data;
temp[data.DataType] = data;
var time = tempData?.Time;
if (time == null || data.Time == null) continue;
var timeDifferenceInSeconds = (data.Time - time)?.TotalSeconds;
if (timeDifferenceInSeconds <= 0) continue;
var steps = (int)timeDifferenceInSeconds!;
var value = double.Parse(data.Data ?? "0");
var lastValue = double.Parse(tempData?.Data ?? "0");
//计算中间值 贝塞尔曲线
var controlPoint = (value + lastValue) / 2;
List<List<object>> values = [];
for (var i = 0; i < steps; i++)
if (!temp.TryGetValue(data.DataType, out var value))
{
var t = (double)i / (steps - 1);
var bezierValue = (1 - t) * (1 - t) * value + 2 * (1 - t) * t * controlPoint + t * t * lastValue;
var bezierTime = time.Value.AddSeconds(i);
var utcTime = bezierTime.ToUniversalTime();
var unixTimestamp = ((DateTimeOffset)utcTime).ToUnixTimeMilliseconds();
List<object> innerList =
[
unixTimestamp,
((int)bezierValue).ToString(CultureInfo.InvariantCulture)
];
values.Add(innerList);
value = new List<List<object>>();
temp[data.DataType] = value;
}
await hubContext.Clients.Groups(userId).SendAsync("ReceiveDataHistory", data.DataType, values);
var unixTimestamp = ((DateTimeOffset)data.Time?.ToUniversalTime()!).ToUnixTimeMilliseconds();
value.Add([unixTimestamp!, data.Data!]);
}
foreach (var entry in temp)
{
await hubContext.Clients.Groups(userId).SendAsync("ReceiveDataHistory", entry.Key, entry.Value, true);
}
return Ok();
}

View File

@ -95,13 +95,14 @@ const items = [
<template>
<div :id="`card_${id}`" ref="cardRef" class="card-layout ">
<div :id="'item' + id" class="card-title vue-draggable-handle">
<div></div>
<h3>{{ title ?? "默认标题" }}</h3>
</div>
<component :is="charts.find(x => x.id === chart)?.component" v-if="targetIsVisible&&!isSwitched"
:rangeNum="rangeNum"
:valueIds="valueIds"
:valueNames="valueNames"/>
<div class="card-content">
<component :is="charts.find(x => x.id === chart)?.component" v-if="targetIsVisible&&!isSwitched"
:rangeNum="rangeNum"
:valueIds="valueIds"
:valueNames="valueNames"/>
</div>
</div>
</template>
@ -109,46 +110,31 @@ const items = [
@import "base";
.card-layout {
width: 100%;
height: 100%;
width: 100%;
background: $light-bg-color;
border-radius: $radius;
box-shadow: 0 10px 30px 0 rgba(17, 38, 146, 0.05);
padding: $padding*1.5;
position: relative;
display: flex;
flex-direction: column;
gap: $gap;
will-change: scroll-position, contents;
border: $border;
display: grid;
grid-template-rows: 40px 1fr;
.dark-mode & {
background: $dark-bg-color;
}
}
.card-title {
display: flex;
justify-content: space-between;
align-items: center;
gap: $gap;
color: $light-text-color;
position: absolute;
z-index: 10;
&,
h3:hover {
cursor: move;
}
.dark-mode & {
color: $dark-text-color;
}
div {
width: 6px;
height: 20px;
border-radius: $radius;
background: $primary-color;
padding: 0 20px;
h3 {
font-size: 14px;
line-height: 24px;
text-align: left;
color: #333;
}
}
.card-content{
padding: 0 20px 20px;
}
</style>

View File

@ -4,17 +4,13 @@ import {useMainLayoutStore} from "~/strores/UseMainLayoutStore";
import type {PropType} from "vue";
import {ref} from 'vue';
import dayjs from "dayjs";
import VChart from 'vue-echarts';
import _ from "lodash";
import {useSessionSignalRStore} from "~/strores/HubStore";
const dataStore = useDataStore()
const hubStore=useSessionSignalRStore()
const hubStore = useSessionSignalRStore()
const mainLayoutStore = useMainLayoutStore()
type ArbitraryKeyValuePairs = {
[key: string]: (number | string)[];
};
const chartRef = ref<any>(null)
const isLoading = ref<boolean>(true)
const props = defineProps({
@ -33,7 +29,7 @@ const props = defineProps({
})
const option = computed(() => {
return {
backgroundColor:'',
backgroundColor: '',
//
// animation: false,
tooltip: {
@ -46,18 +42,19 @@ const option = computed(() => {
}
},
grid: {
left: '2%',
left: '0',
right: '50',
bottom: '10%',
bottom: '38',
top: '15',
containLabel: true
},
xAxis: [
{
type: 'time',
// boundaryGap: false
axisLabel:{
showMinLabel:true,
showMaxLabel:true,
boundaryGap: false,
axisLabel: {
showMinLabel: true,
showMaxLabel: true,
}
},
],
@ -66,15 +63,6 @@ const option = computed(() => {
type: 'value',
}
],
toolbox: {
feature: {
dataZoom: {
yAxisIndex: 'none'
},
saveAsImage: {}
}
},
dataZoom: [
{
type: 'inside',
@ -100,18 +88,18 @@ const option = computed(() => {
large: true,
smooth: true,
largeThreshold: 10000,
sampling:'lttb',
sampling: 'lttb',
emphasis: {
focus: 'series'
},
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' }
{type: 'max', name: 'Max'},
{type: 'min', name: 'Min'}
]
},
markLine: {
data: [{ type: 'average', name: 'Avg' }]
data: [{type: 'average', name: 'Avg'}]
},
data: [],
}
@ -122,19 +110,34 @@ let interval: NodeJS.Timeout;
onUnmounted(() => {
clearInterval(interval);
})
let maxValue = 100;
onMounted(() => {
setTimeout(()=>{
hubStore.connection?.on("ReceiveDataHistory",(type:string,values:string[][])=>{
isLoading.value = true;
chartRef.value.appendData({
seriesIndex: props.valueIds?.indexOf(type),
data:values
})
isLoading.value = false;
if (!chartRef.value) {
console.error('ECharts instance is not initialized');
return;
}
hubStore.connection?.on("ReceiveDataHistory", (type: string, values: [number,string][], done: boolean) => {
chartRef.value.appendData({
seriesIndex: props.valueIds?.indexOf(type),
data: values
})
},1000)
setTimeout(()=>{
if (done) {
//y140%
// const currentOption = chartRef.value.getOption();
// const maxData = Math.max(...values.map(item =>item[1]));
// if (maxData > maxValue) {
// maxValue = maxData
// currentOption.yAxis[0].max = maxData * 1.4;
// chartRef.value.setOption(currentOption);
// }
}
isLoading.value = false;
})
setTimeout(() => {
$fetch('/Api/Server/GetServerHistoryDate', {
method: 'GET',
headers: {
@ -147,53 +150,8 @@ onMounted(() => {
},
baseURL: useRuntimeConfig().public.baseUrl,
})
setTimeout(()=>{
interval = setInterval(() => {
const data = dataStore.data
const time=Date.now()
props.valueIds?.forEach((id, index) => {
const newData = data[id] ?? 0
chartRef.value.appendData({
seriesIndex: index,
data: [[time,newData]]
})
const currentOption = chartRef.value.getOption();
chartRef.value.setOption(currentOption)
})},1000)
})
},1000)
// let history = dataStore.dataHistory
// setTimeout(() => {
// isLoading.value = false;
// }, 5000)
// nextTick(() => {
// props.valueIds?.forEach((id, index) => {
// chartRet.value.appendData({
// seriesIndex: index,
// data: history.data[id]
// })
// })
// const currentOption = chartRet.value.getOption();
// currentOption.xAxis[0].data = history.times
// chartRet.value.setOption(currentOption)
// isLoading.value = false
// interval = setInterval(() => {
// const data = dataStore.data
// props.valueIds?.forEach((id, index) => {
// const newData = data[id] ?? 0
// if (!values.value[id]) {
// values.value[id] = []
// }
// chartRet.value.appendData({
// seriesIndex: index,
// data: [newData]
// })
// })
// const currentOption = chartRet.value.getOption();
// currentOption.xAxis[0].data.push(dayjs().format('MM-DD HH:mm:ss'))
// chartRet.value.setOption(currentOption)
// }, 4000 + 1000 * Math.random())
// })
}, 2000)
})
// let endIndex = dataStore.dataHistory.times ? dataStore.dataHistory.times.length : 0
// let startTemp = 0;
@ -256,7 +214,7 @@ onMounted(() => {
autoresize
:theme="$colorMode.value"
class="chart"
/>
/>
</template>
<style>