apexcharts / Blazor-ApexCharts

A blazor wrapper for ApexCharts.js
https://apexcharts.github.io/Blazor-ApexCharts
MIT License
788 stars 91 forks source link

Only one of multpile charts re renders #377

Closed Woutjeee closed 8 months ago

Woutjeee commented 8 months ago

I have a issue where I want to reload charts with certain filters, in my case I have 2 charts. When I apply the filters only one chart updates with the correct data, however the other chart does have the correct data but it just does not seem to update for some reason.

It does work after spamming the 'filter' button a couple of times.

Our component written upon the ApexChart component (Child Component)

<ApexChart @ref="Chart" TItem="AnalyticsData" Options="Options" Height="Height" Width="Width">
    <ApexPointSeries TItem="AnalyticsData"
                     Name="@(Name ?? "Value")"
                     Items="Items"
                     SeriesType="SeriesType"
                     XValue="XValue"
                     YValue="YValue"
                     YAggregate="YAggregate"
                     OrderBy="OrderBy"
                     OrderByDescending="OrderByDescending"
                     ShowDataLabels="ShowDataLabels" />
</ApexChart>

The update function in the component

public async Task UpdateChart() => await Chart.UpdateOptionsAsync(true, true, true);

How we defined the components (Parent Component)

<AnalyticsChart @ref="BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.FailedRequestDataProvider).ChartReference"
              Action="@Action"
              Item="BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.FailedRequestDataProvider)"
              Items="BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.FailedRequestDataProvider).AnalyticsData"
              SeriesType="(SeriesType)Enum.Parse(typeof(SeriesType), BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.FailedRequestDataProvider).ChartType)"
              XValue="context => context.DayMonth"
              YValue="context => context.RequestsCount ?? 0"
              ClassName="@BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.FailedRequestDataProvider).Type"
              ColClass="@BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.FailedRequestDataProvider).ColClass"
              Description="@BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.FailedRequestDataProvider).Description"
              Title="@BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.FailedRequestDataProvider).Title"/>

<AnalyticsChart @ref="BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.ServerRequestDataProvider).ChartReference"
              Action="@Action"
              Item="BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.ServerRequestDataProvider)"
              Items="BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.ServerRequestDataProvider).AnalyticsData"
              SeriesType="(SeriesType)Enum.Parse(typeof(SeriesType), BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.ServerRequestDataProvider).ChartType)"
              XValue="context => context.DayMonth"
              YValue="context => context.RequestsCount ?? 0"
              ClassName="@BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.ServerRequestDataProvider).Type"
              ColClass="@BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.ServerRequestDataProvider).ColClass"
              Description="@BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.ServerRequestDataProvider).Description"
              Title="@BasicCharts.FirstOrDefault(x => x.Type == WidgetTypes.ServerRequestDataProvider).Title" />

The apply filter function

protected async void ApplyFilter()
{
    var timeSpanFromDays = TimeSpan.FromDays(TimeRange);
    var filters = new AnalyticsFilters()
    {
        CustomFilters = new()
        {
            { "StartDate", StartDate.ToString() },
            { "EndDate", EndDate.ToString() },
            { "TimeRange", timeSpanFromDays.ToString() }
        }
    };

    foreach (var widget in BasicCharts)
    {
        await AnalyticsService.GetData(Action, ServiceObject, widget, filters);
        // This only updates 1 chart, and not both.
        await widget.ChartReference.UpdateChart();
    }
}

The reference property

public AnalyticsChart ChartReference { get; set; } = new();
joadan commented 8 months ago

Hi,

Do you think you can provide a minimal repo to reproduce the issue. My guess is that the @ref is not correct, also remember that each chart needs a separate options object

Woutjeee commented 8 months ago

I fixed it, the problem was that the razor render engine did not properly re render the component.