Open ymoona opened 1 month ago
@ymoona Thank you for using BlazorBootstrap. I'll check this scenario and get back to you.
@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:
What are your thoughts on this implementation?
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):
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):
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.