Pie Chart Tool Tip Problem

Very very sorry but this turned into a long post, just wanted as many details as possible in.

Firstly, I am unsure if this issue effects other charts as well but I do know it effects the pie chart's tool tip.

Problem:

The default ColorScheme for the pie chart will repeat a single color for the majority of the chart if there are too many items. This would be fine if it alternated colors but it does not.
Example picture (100 different sections with all randomly generated sizes):

image

In order to fix this behavior you have to set your own scheme through the Fills property, which will alternate colors even if there are less colors than sections.
Picture (same generation method as before):

image

This works.. for the most part.
If you receive your data through a getter that uses a .ConvertAll() for some reason, the tool tip does not work.

On Radzen version 3.5.0 it would crash with an exception:

System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   at System.Linq.Enumerable.ElementAt[TSource](IEnumerable`1 source, Int32 index)
   at Radzen.Blazor.CartesianSeries`1.PickColor(Int32 index, IEnumerable`1 colors, String defaultValue)
   at Radzen.Blazor.RadzenPieSeries`1.TooltipStyle(TItem item)
   at Radzen.Blazor.CartesianSeries`1.<>c__DisplayClass67_0.<RenderTooltip>b__0(RenderTreeBuilder builder)
   at Radzen.Blazor.RadzenChart.<BuildRenderTree>b__0_2(RenderTreeBuilder __builder2)
   at Microsoft.AspNetCore.Components.CascadingValue`1.Render(RenderTreeBuilder builder)
   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch(RenderQueueEntry renderQueueEntry)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()

With the latest version (3.7.3 currently), it does not through an exception it just does not show the tool tip.

Important to note that the tool tip in the new Radzen version (3.7.3) does not work even with the default Fills while version 3.5.0, it does work with the default fills

Code to reproduce (the first row are the ones that do not work but the second one in the first row will work in 3.5.0):

<div class="justify-content-md-center">

    <div class="row">
        <RadzenChart Style="height: 400px; width: 750px;">

            <RadzenPieSeries Data="this.processedData" Title="Sections 1" CategoryProperty="Name" ValueProperty="Amount" Radius="150" Fills="this.fills" />

        </RadzenChart>

        <RadzenChart Style="height: 400px; width: 750px;">

            <RadzenPieSeries Data="this.processedData" Title="Sections 2" CategoryProperty="Name" ValueProperty="Amount" Radius="150" />

        </RadzenChart>
    </div>

    <div class="row">
       

        <RadzenChart Style="height: 400px; width: 750px;">

            <RadzenPieSeries Data="this.inventories" Title="Sections 3" CategoryProperty="Name" ValueProperty="Amount" Radius="150" Fills="this.fills" />

        </RadzenChart>
    </div>
</div>

@code {

    //If you do not use your own fills property then the majority of the graph will be the same color next to one another.
    private List<string> fills = new List<string>() { "#F78989","#89F798","#A889F7","#F7B589","#89F7C2","#D289F7","#F5D66B","#6BF5EA"};

    private List<TestClass> processedData
    {
        get
        {

            var list = new List<TestClass>();
            foreach (var item in this.inventories)
            {
                list.Add(new TestClass(item.Name, item.Amount));
            }
            return list;
            //Both of these break the tooltip
            //return this.inventories.ConvertAll(c => new TestClass(c.Name, c.Amount));
        }
    }

    private List<TestClass> inventories = new();

    protected override void OnInitialized()
    {
        Random random = new();
        for (var i = 0; i < 100; i++)
        {
            this.inventories.Add(new TestClass() { Name = $"Name {i}", Amount = random.NextDouble() });
        }

        //Does not work even if the fills were padded out to same size as inventory or more.
        //var numberToAdd = this.inventories.Count - this.fills.Count;

        //for (var i = 0; i < numberToAdd; i++)
        //{
        //    this.fills.Add(this.fills[i]);
        //}

    }

    private class TestClass
    {
        public TestClass() { }
        public TestClass(string name, double amount)
        {
            this.Name = name;
            this.Amount = amount;
        }

        public string Name { get; set; }
        public double Amount { get; set; }
    }

}

Some additional notes:

  • For my purposes I can avoid using a .ConvertAll() so this problem does not directly affect me (aside from the hours of trying to fix what was wrong with it).
  • I am unsure if there are any other methods that would reproduce this issue.
  • Only really posting to hopefully help someone from spending time if found in the same situation / give them a place to start from.
  • While typing this I figured I should test if I did a manual .ConvertAll() to see if it would work and it still breaks the tool tip (Code is above for it).

Tl;dr
Getting your data from a getter which employs a temporary list breaks the tool tip all together in the latest Radzen (3.7.3), but to break the 3.5.0 Radzen tool tip you have to do that + manually set a Fills property. Also the Fills property if default does not cycle the colors as would be the expected behavior but does cycle it if you manually set the Fills property.

The problem is the definition of the processedData property - it returns completely new data every time it is accessed. As a return none of the checks performed by Blazor and the RadzenChart work as items are different every time. If you change your code to this everything will work as expected (and perform times better):

    private List<TestClass> processedData; // make this a field and assign it in OnItinitialized and whenever your data changes

    protected override void OnInitialized()
    {
        Random random = new();
        for (var i = 0; i < 100; i++)
        {
            this.inventories.Add(new TestClass() { Name = $"Name {i}", Amount = random.NextDouble() });
        }

        var list = new List<TestClass>();
        foreach (var item in this.inventories)
        {
            list.Add(new TestClass(item.Name, item.Amount));
        }
        // Initialize processedData once
        processedData = list;
        //Does not work even if the fills were padded out to same size as inventory or more.
        //var numberToAdd = this.inventories.Count - this.fills.Count;

        //for (var i = 0; i < numberToAdd; i++)
        //{
        //    this.fills.Add(this.fills[i]);
        //}

    }

Figured that was the cause so I already fixed it. What really threw me off was that I was using version 3.5.0 which allows this until you add a Fills property but when updating to 3.7.3 and it didn't work at all is what helped me find the issue.

Also, is there a reason why the default ColorScheme stops alternating the colors but when supplying a Fills property it makes it alternate colors?