LayTec-AG / Plotly.Blazor

This library packages the well-known charting library plotly.js into a razor component that can be used in a Blazor project.
MIT License
340 stars 48 forks source link

4.2.0 and 4.3.0 Exception is thrown if plot is de-rendered while still lazy loading #428

Open OliverWingY opened 3 months ago

OliverWingY commented 3 months ago

Using the following two components, clicking the button twice in quick succession will throw the following exception: ,"Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] Unhandled exception rendering component: No DOM element with id 'PlotlyChart-1695005480' exists on the page. Error: No DOM element with id 'PlotlyChart-1695005480' exists on the page."

This can also occur if you navigate away from the page while a plot is lazy loading, although I was able to work around that by intercepting the OnLocationChanging event from the NavigationManager and waiting for the chart to finish loading before navigating away.

This causes a lot of issues if you want to embed a plotly chart in an expandable components, like a tree or grid.

Home.razor

@page "/"

<button @onclick="TogglePlot">Toggle graph</button>

@if (_plotVisible)
{
    <Plot></Plot>
}

@code
{

    private bool _plotVisible = false;

    private void TogglePlot()
    {
        _plotVisible = !_plotVisible;
        StateHasChanged();
    }
}

Plot.razor:

@using Plotly.Blazor
@using Layout = Plotly.Blazor.Layout
@using Plotly.Blazor.Traces.ScatterLib
@using Plotly.Blazor.Traces
@using Line = Plotly.Blazor.Traces.ScatterLib.Line
@using System.Drawing

<div style="height: 50%; width: 50%;">
    <PlotlyChart @bind-Config="@_config" @bind-Layout="_layout" @bind-Data="_data" @ref="_chart"></PlotlyChart>
</div>

@code {
    protected Config _config = new Config();
    protected Layout _layout = new Layout();
    protected PlotlyChart _chart;

    private IList<ITrace> _data = new List<ITrace>();

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await AddData();
            await _chart.React();
        }
        await base.OnAfterRenderAsync(firstRender);
    }

    public async Task AddData()
    {
        _data.Add(new Scatter()
            {
                Name = "Test",
                Mode = ModeFlag.Lines,
                Line = new Line() { Dash = "dash", Color = Color.Blue.ToString() },
                X = new List<object>() { 1.0, 2.0, 3.0 },
                Y = new List<object>() { 1.0, 2.0, 3.0 },
                ShowLegend = false
            });

    }
}
sean-mcl commented 2 months ago

Will check it out next week. :)

sean-mcl commented 2 months ago

Should be fixed by https://github.com/LayTec-AG/Plotly.Blazor/pull/432

OliverWingY commented 1 month ago

Looks like the bug still present in 5.0.0 and 5.1.1