Blazor示例 之 通用定时器 TimerComponent.razor

@implements IDisposable
@using System.Timers

@code {
    private Timer? _timer;
    [Parameter] public double Interval { get; set; } = 2000;
    [Parameter] public EventCallback<ElapsedEventArgs> OnElapsed { get; set; }

    protected override void OnInitialized()
    {
        base.OnInitialized();

        if (_timer == null)
        {
            _timer = new Timer
            {
                Interval = Interval
            };

            _timer.Elapsed += async (sender, args) => await OnElapsed.InvokeAsync(args);

            _timer.Start();
        }
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }
}

使用 TimerComponent

@page "/example"
@inject SensorParamService sensorParamService

<TimerComponent Interval="2000" OnElapsed="TimerOnElapsed" />

<MECharts Option="_option" Height="400" IncludeFunctionsInOption></MECharts>

@code {
    private object _option = GenOption(0);

    private void TimerOnElapsed(ElapsedEventArgs e)
    {
        InvokeAsync(() =>
        {
            var res = sensorParamService.SensorParamDic.FirstOrDefault(it => it.Value.Name == "电器房_风向");
            _option = GenOption(res.Value.DiffValue);
            StateHasChanged();
        });
    }

    private static object GenOption(double value)
    {
        return new
        {
            Tooltip = new
            {
                Formatter = "{a} <br/>{b}: {c}°"
            },
            Series = new[]
            {
                new
                {
                    Name = "风向",
                    Type = "gauge",
                    StartAngle = 90,
                    EndAngle = -269.9999,
                    AxisLine = new
                    {
                        LineStyle = new
                        {
                            Width = 10
                        }
                    },
                    Pointer = new
                    {
                        Length = "70%",
                        Width = 6
                    },
                    SplitLine = new
                    {
                        Length = 15,
                        LineStyle = new
                        {
                            Width = 2
                        }
                    },
                    AxisLabel = new
                    {
                        Distance = 20,
                        Formatter = "(value) => { const directions = ['北', '东北', '东', '东南', '南', '西南', '西', '西北']; return directions[Math.floor(value / 45) % 8]; }"
                    },
                    AxisTick = new
                    {
                        SplitNumber = 4
                    },
                    Detail = new
                    {
                        Formatter = "{value}°"
                    },
                    Data = new[]
                    {
                        new { Value = value, Name = "风向" }
                    }
                }
            }
        };
    }
}

然后二次封装

@inject SensorParamService SensorParamService
@implements IDisposable
@using System.Timers

@code {
    private Timer? _timer;
    [Parameter] public double Interval { get; set; } = 2000;
    [Parameter] public Func<IDictionary<string, SensorParam>, IEnumerable<SensorParam>> QueryExpression { get; set; }
    [Parameter] public EventCallback<IEnumerable<SensorParam>> OnDataFetched { get; set; }

    protected override void OnInitialized()
    {
        base.OnInitialized();

        if (_timer == null)
        {
            _timer = new Timer
            {
                Interval = Interval
            };

            _timer.Elapsed += async (sender, args) => await FetchData();

            _timer.Start();
        }
    }

    private async Task FetchData()
    {
        var results = QueryExpression(SensorParamService.SensorParamDic);
        await InvokeAsync(() => OnDataFetched.InvokeAsync(results));
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }
}

调用,(这样linq在前端的,网络压力大,最好还是后端servser有委托方法)

@page "/example"

<TimerComponent Interval="2000" 
                QueryExpression="GetSensorParams" 
                OnDataFetched="HandleDataFetched" />

<MECharts Option="_option" Height="400" IncludeFunctionsInOption></MECharts>

@code {
    private object _option = GenOption(0);

    private IEnumerable<SensorParam> GetSensorParams(IDictionary<string, SensorParam> sensorParamDic)
    {
        // 完整的 LINQ 查询逻辑在这里定义
        return sensorParamDic.Values.Where(it => it.Name.Contains("风向"));
    }

    private void HandleDataFetched(IEnumerable<SensorParam> sensorParams)
    {
        InvokeAsync(() =>
        {
            // 处理多个传感器参数,例如更新图表数据
            var firstParam = sensorParams.FirstOrDefault();
            if (firstParam != null)
            {
                _option = GenOption(firstParam.DiffValue);
            }
            else
            {
                // 处理结果为空的情况
                Console.WriteLine("未找到匹配的传感器参数。");
            }
            StateHasChanged();
        });
    }

    private static object GenOption(double value)
    {
        return new
        {
            Tooltip = new
            {
                Formatter = "{a} <br/>{b}: {c}°"
            },
            Series = new[]
            {
                new
                {
                    Name = "风向",
                    Type = "gauge",
                    StartAngle = 90,
                    EndAngle = -269.9999,
                    AxisLine = new
                    {
                        LineStyle = new
                        {
                            Width = 10
                        }
                    },
                    Pointer = new
                    {
                        Length = "70%",
                        Width = 6
                    },
                    SplitLine = new
                    {
                        Length = 15,
                        LineStyle = new
                        {
                            Width = 2
                        }
                    },
                    AxisLabel = new
                    {
                        Distance = 20,
                        Formatter = "(value) => { const directions = ['北', '东北', '东', '东南', '南', '西南', '西', '西北']; return directions[Math.floor(value / 45) % 8]; }"
                    },
                    AxisTick = new
                    {
                        SplitNumber = 4
                    },
                    Detail = new
                    {
                        Formatter = "{value}°"
                    },
                    Data = new[]
                    {
                        new { Value = value, Name = "风向" }
                    }
                }
            }
        };
    }
}