Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LineChart inside a GridDetailView #908

Open
ymoona opened this issue Oct 17, 2024 · 2 comments
Open

LineChart inside a GridDetailView #908

ymoona opened this issue Oct 17, 2024 · 2 comments

Comments

@ymoona
Copy link

ymoona commented Oct 17, 2024

Describe the bug
I have a LineChart that I would like to show in the GridDetailView of a Grid.
When placing this LineChart just above the grid (with some test data) it is rendered just fine.
But placing the LineChart inside GridDetailView it does not render, and the area stays blank.

The code is based on this example.

Versions (please complete the following information):

  • .NET Version: [ .NET 8]
  • BlazorBootstrap: [3.0.0]
  • Blazor WebAssembly
  • Blazor Interactive Render Mode: WebAssembly
  • Blazor Interactivity Location: [component]

Sample code
Sample code to reproduce the issue.
<GridDetailView TItem="TheObject"> <Button Type="ButtonType.Button" Class="mb-2" Color="ButtonColor.Primary" Size="ButtonSize.Small" @onclick="async () => await Init()"> Init </Button> <Button Type="ButtonType.Button" Class="mb-2" Color="ButtonColor.Primary" Size="ButtonSize.Small" @onclick="async () => await Update()"> Update </Button> <LineChart @ref="lineChart" Width="800" Class="mb-4" /> </GridDetailView>

I based the code on this example:
https://demos.blazorbootstrap.com/charts/line-chart#how-it-works

GitHub repo
GitHub repo with minimal code to reproduce the issue.

Desktop (please complete the following information):

  • OS: Windows 11
  • Browser [Edge]

Additional context
Is what I am trying supported? I was expecting the rendering issue to be in the initialization, so I created button to init and update the LineChart. They work fine when the LineChart is rendered outside the Grid.

@gvreddy04
Copy link
Contributor

@ymoona Thank you for using BlazorBootstrap. I'll check this scenario and get back to you.

@ymoona
Copy link
Author

ymoona commented Oct 18, 2024

@gvreddy04 I spend a bit more time this morning trying to figure out what is going on, and I found why it won't work.
The issue is that a grid has multiple items and therefor multiple reference to the same chart.

I fix that by referencing from a dictionary based on the key. Then I had the issue that I could the right moment to initialize the chart as "OnAfterRenderAsync" is too early (not sure why, but it does not work). So I now do that on the OnRowClick, that fires anyway when GridDetailView is requested by the user.

@page "/"

<PageTitle>Home</PageTitle>

<h1>Hello, world!</h1>
<Grid TItem="Employee1"
      Class="table table-hover border-top"
      Data="employees"
      AllowDetailView="true"
      AllowRowClick="true"
      OnRowClick="OnRowClick">

    <GridColumns>
        <GridColumn TItem="Employee1" HeaderText="Id" PropertyName="Id">
            @context.Id
        </GridColumn>
        <GridColumn TItem="Employee1" HeaderText="Employee Name" PropertyName="Name">
            @context.Name
        </GridColumn>
        <GridColumn TItem="Employee1" HeaderText="Designation" PropertyName="Designation">
            @context.Designation
        </GridColumn>
        <GridColumn TItem="Employee1" HeaderText="DOJ" PropertyName="DOJ">
            @context.DOJ
        </GridColumn>
        <GridColumn TItem="Employee1" HeaderText="Active" PropertyName="IsActive">
            @context.IsActive
        </GridColumn>
    </GridColumns>

    <GridDetailView TItem="Employee1" >
        <div class="row">
            <div class="col-2 fw-bold">Id</div>
            <div class="col">@context.Id</div>
        </div>
        <div class="row">
            <div class="col-2 fw-bold">Name</div>
            <div class="col">@context.Name</div>
        </div>
        <div class="row">
            <div class="col-2 fw-bold">Designation</div>
            <div class="col">@context.Designation</div>
        </div>
        <div class="row">
            <div class="col-2 fw-bold">DOJ</div>
            <div class="col">@context.DOJ</div>
        </div>
        <div class="row">
            <div class="col-2 fw-bold">IsActive</div>
            <div class="col">@context.IsActive</div>
        </div>
        <LineChart @ref="@_charts[context.Id]" Width="800" Class="mb-4" />
    </GridDetailView>

</Grid>


@code {
    private readonly Dictionary<int, LineChart> _charts = new();
    private LineChart _lineChart = default!;
    private LineChartOptions _lineChartOptions = default!;
    private ChartData _chartData = default!;

    protected override void OnInitialized()
    {
        var colors = ColorUtility.CategoricalTwelveColors; // This is not correct in the examples

        var labels = new List<string> { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
        var datasets = new List<IChartDataset>();

        var dataset1 = new LineChartDataset
            {
                Label = "Windows",
                Data = [7265791, 5899643, 6317759, 6315641, 5338211, 8496306, 7568556, 8538933, 8274297, 8657298, 7548388, 7764845],
                BackgroundColor = colors[0],
                BorderColor = colors[0],
                BorderWidth = 2,
                HoverBorderWidth = 4,
                PointBackgroundColor = [colors[0]],
                PointRadius = [0], // hide points
                PointHoverRadius = [4],
            };
        datasets.Add(dataset1);

        var dataset2 = new LineChartDataset
            {
                Label = "macOS",
                Data = [1809499, 1816642, 2122410, 1809499, 1850793, 1846743, 1954797, 2391313, 1983430, 2469918, 2633303, 2821149],
                BackgroundColor = colors[1],
                BorderColor = colors[1],
                BorderWidth = 2,
                HoverBorderWidth = 4,
                PointBackgroundColor = [colors[1]],
                PointRadius = [0], // hide points
                PointHoverRadius = [4],
            };
        datasets.Add(dataset2);

        var dataset3 = new LineChartDataset
            {
                Label = "Other",
                Data = [1081241, 1100363, 1118136, 1073255, 1120315, 1395736, 1488788, 1489466, 1489947, 1414739, 1735811, 1820171],
                BackgroundColor = colors[2],
                BorderColor = colors[2],
                BorderWidth = 2,
                HoverBorderWidth = 4,
                PointBackgroundColor = [colors[2]],
                PointRadius = [0], // hide points
                PointHoverRadius = [4],
            };
        datasets.Add(dataset3);

        _chartData = new ChartData
            {
                Labels = labels,
                Datasets = datasets
            };

        _lineChartOptions = new()
            {
                Responsive = true,
                Interaction = new Interaction { Mode = InteractionMode.Index }
            };

        if (_lineChartOptions.Scales.X != null)
        {
            _lineChartOptions.Scales.X.Title = new ChartAxesTitle(); // Needed to initialize this myself
            if (_lineChartOptions.Scales.X.Title != null)
            {
                _lineChartOptions.Scales.X.Title.Text = "2019";
                _lineChartOptions.Scales.X.Title.Display = true;
            }
        }

        if (_lineChartOptions.Scales.Y != null)
        {
            _lineChartOptions.Scales.Y.Title = new ChartAxesTitle(); // Needed to initialize this myself 
            if (_lineChartOptions.Scales.Y.Title != null)
            {
                _lineChartOptions.Scales.Y.Title.Text = "Visitors";
                _lineChartOptions.Scales.Y.Title.Display = true;
            }
        }

        if (_lineChartOptions.Plugins.Title != null)
        {
            _lineChartOptions.Plugins.Title.Text = "Operating system";
            _lineChartOptions.Plugins.Title.Display = true;
        }
    }

    private List<Employee1> employees = new List<Employee1> {
        new Employee1 { Id = 107, Name = "Alice", Designation = "AI Engineer", DOJ = new DateOnly(1998, 11, 17), IsActive = true },
        new Employee1 { Id = 103, Name = "Bob", Designation = "Senior DevOps Engineer", DOJ = new DateOnly(1985, 1, 5), IsActive = true },
        new Employee1 { Id = 106, Name = "John", Designation = "Data Engineer", DOJ = new DateOnly(1995, 4, 17), IsActive = true },
        new Employee1 { Id = 104, Name = "Pop", Designation = "Associate Architect", DOJ = new DateOnly(1985, 6, 8), IsActive = false },
        new Employee1 { Id = 105, Name = "Ronald", Designation = "Senior Data Engineer", DOJ = new DateOnly(1991, 8, 23), IsActive = true }
    };

    public record class Employee1
    {
        public int Id { get; set; }
        public string? Name { get; set; }
        public string? Designation { get; set; }
        public DateOnly DOJ { get; set; }
        public bool IsActive { get; set; }
    }

    private async Task OnRowClick(GridRowEventArgs<Employee1> args)
    {
        if (_charts.ContainsKey(args.Item.Id))
        {
            _lineChartOptions.Plugins.Title.Text = $"Id:{args.Item.Id}";
            await _charts[args.Item.Id].InitializeAsync(_chartData, _lineChartOptions);
        }
    }
}

The result looks like this:
{5E10FD14-89EE-4B37-B404-957D8EF464A7}

What are your thoughts on this implementation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants