You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor ApexCharts折线图切换日期后数据更新但图表未重绘的问题

Blazor ApexCharts折线图切换日期后数据更新但图表未重绘的问题

我之前在Blazor项目里用ApexCharts也遇到过几乎一模一样的问题,折腾了好一阵才找到几个关键的修复点,你可以照着下面的步骤调整你的代码:

问题根源分析

出现这种情况主要有几个常见原因:

  • Blazor的状态检测机制没捕捉到数据/图表配置的变化
  • 数据集合只是修改了内容而非替换实例,ApexCharts无法感知
  • 异步加载数据后没有主动通知Blazor更新组件
  • 组件初始化逻辑的时序问题导致状态标记异常

具体修复步骤

1. 补全组件初始化逻辑,修正_isInitialized的设置

你的OnInitializedAsync代码没写完,需要确保初始加载完成后再标记组件已初始化,避免属性setter在初始化阶段重复触发数据加载:

protected override async Task OnInitializedAsync()
{
    PageTitleService.SetTitle("Zakkenmachine's • Dagrapport");
    // 加载机器列表
    machines = await Http.GetFromJsonAsync<List<Oee_Alg_Machines>>("DagRapport/Machine");
    // 设置默认选中的机器ID
    if (machines != null && machines.Any())
    {
        _selectedMachineId = machines.FirstOrDefault()?.Id ?? 10;
    }
    // 初始化图表配置
    InitializeChartOptions();
    // 加载初始数据
    await LoadDataAsync(false);
    // 标记组件已完成初始化
    _isInitialized = true;
}

2. 确保数据集合每次都是新实例,而非修改现有集合

ApexCharts是通过检测集合的引用变化来更新的,所以加载数据时必须替换整个List,不能只修改原有集合的内容:

private async Task LoadDataAsync(bool isFilterChange)
{
    if (!Dag.HasValue) return;
    
    try
    {
        // 注意:每次都创建新的List实例,而不是Add/Remove现有List的元素
        GraphVroege = await Http.GetFromJsonAsync<List<spGetGraphPloegen>>(
            $"DagRapport/GraphVroege?dag={Dag.Value:yyyy-MM-dd}&machineId={SelectedMachineId}");
        GraphLate = await Http.GetFromJsonAsync<List<spGetGraphPloegen>>(
            $"DagRapport/GraphLate?dag={Dag.Value:yyyy-MM-dd}&machineId={SelectedMachineId}");
        GraphNacht = await Http.GetFromJsonAsync<List<spGetGraphPloegen>>(
            $"DagRapport/GraphNacht?dag={Dag.Value:yyyy-MM-dd}&machineId={SelectedMachineId}");
    }
    catch (Exception ex)
    {
        // 这里可以添加异常日志或用户提示
        Console.WriteLine($"加载数据失败:{ex.Message}");
    }
    // 强制通知Blazor更新组件,确保图表感知到变化
    await InvokeAsync(StateHasChanged);
}

3. 在日期切换时主动触发状态更新

修改Dag属性的setter,确保图表配置变化后Blazor能及时更新:

private DateTime? Dag { 
    get => _dag; 
    set { 
        if (_dag != value) { 
            _dag = value; 
            InitializeChartOptions();
            // 使用await确保异步操作的上下文正确,避免火并忘记导致的状态丢失
            _ = LoadDataAsync(true);
            // 主动触发状态更新
            await InvokeAsync(StateHasChanged);
        } 
    } 
}

4. (可选)手动调用图表的更新方法

如果以上修改后仍有问题,可以尝试获取ApexChart的组件引用,强制触发图表更新:
首先在Razor模板里给每个图表添加@ref:

<ApexChart TItem="spGetGraphPloegen" 
           Options="@chartOptionsVroege" 
           Series="@GraphVroege"
           @ref="vroegeChart">
    <ApexPointSeries XValue="@(e => e.DatumTijd)" YValue="@(e => e.Cap_Act)" Name="Vroege Ploeg" />
</ApexChart>

<ApexChart TItem="spGetGraphPloegen" 
           Options="@chartOptionsLate" 
           Series="@GraphLate"
           @ref="lateChart">
    <ApexPointSeries XValue="@(e => e.DatumTijd)" YValue="@(e => e.Cap_Act)" Name="Late Ploeg" />
</ApexChart>

<!-- 夜班图表同理 -->

然后在代码里定义引用并在LoadDataAsync最后调用更新:

private ApexChart<spGetGraphPloegen> vroegeChart;
private ApexChart<spGetGraphPloegen> lateChart;
private ApexChart<spGetGraphPloegen> nachtChart;

private async Task LoadDataAsync(bool isFilterChange)
{
    // ...... 现有加载数据的逻辑 ......
    
    // 强制更新每个图表
    if (vroegeChart != null) await vroegeChart.UpdateAsync();
    if (lateChart != null) await lateChart.UpdateAsync();
    if (nachtChart != null) await nachtChart.UpdateAsync();
    
    await InvokeAsync(StateHasChanged);
}

这些修改应该能解决你遇到的“数据更新但图表不重绘”的问题,核心就是确保Blazor和ApexCharts都能感知到数据或配置的变化。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 10:33:06