Skip to content

New Chart: HeatMap#10263

Merged
henon merged 35 commits intoMudBlazor:devfrom
versile2:heatmap
Nov 28, 2024
Merged

New Chart: HeatMap#10263
henon merged 35 commits intoMudBlazor:devfrom
versile2:heatmap

Conversation

@versile2
Copy link
Contributor

@versile2 versile2 commented Nov 18, 2024

Description

Created a new HeatMap chart type

From new Docs
heatmap

How Has This Been Tested?

Visual tests, unit tests coming, will create example docs as well

Type of Changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation (fix or improvement to the website or code docs)

Checklist

  • The PR is submitted to the correct branch (dev).
  • My code follows the code style of this project.
  • I've added relevant tests.

@github-actions github-actions bot added docs Updates/improvements to project documentation that do not affect core library logic enhancement Adds a new feature or enhances existing functionality (not fixing a defect) in the main library labels Nov 18, 2024
@ScarletKuro ScarletKuro requested a review from henon November 18, 2024 15:56
@codecov
Copy link

codecov bot commented Nov 18, 2024

Codecov Report

Attention: Patch coverage is 87.43169% with 23 lines in your changes missing coverage. Please review.

Project coverage is 91.43%. Comparing base (ac1d69c) to head (5816574).
Report is 7 commits behind head on dev.

Files with missing lines Patch % Lines
...MudBlazor/Components/Chart/Charts/HeatMap.razor.cs 87.50% 6 Missing and 10 partials ⚠️
...rc/MudBlazor/Components/Chart/Charts/HeatMap.razor 86.53% 0 Missing and 7 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev   #10263      +/-   ##
==========================================
- Coverage   91.54%   91.43%   -0.12%     
==========================================
  Files         415      417       +2     
  Lines       13017    13233     +216     
  Branches     2457     2535      +78     
==========================================
+ Hits        11917    12100     +183     
- Misses        549      554       +5     
- Partials      551      579      +28     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ScarletKuro ScarletKuro mentioned this pull request Nov 19, 2024
7 tasks
@ScarletKuro
Copy link
Member

Probably the lerp with be added to the core: #10275

@henon
Copy link
Contributor

henon commented Nov 25, 2024

I'm open to suggestions. I would like to get this closed out and do that as a PR but I'm also constrained by using the ChartSeries, I would have to think or look at a good example of using Render Fragments with dynamic data like that.

Sure, it doesn't have to be in this PR. Without knowing the details of your implementation, basically you'd use a RenderFragment<HeatMapCell> where HeatMapCell would pass all the data to the render fragment which is needed to render the cell content.

@ScarletKuro
Copy link
Member

If you tag me in an issue or something I can make a PR for that. Would def qualify as breaking change though.

I might look at it as well later. It's for sure a breaking change, just hope it won't make all tests red etc.

@versile2
Copy link
Contributor Author

I'm open to suggestions. I would like to get this closed out and do that as a PR but I'm also constrained by using the ChartSeries, I would have to think or look at a good example of using Render Fragments with dynamic data like that.

Sure, it doesn't have to be in this PR. Without knowing the details of your implementation, basically you'd use a RenderFragment<HeatMapCell> where HeatMapCell would pass all the data to the render fragment which is needed to render the cell content.

Any components that have something similar?

@henon
Copy link
Contributor

henon commented Nov 25, 2024

Yes, for instance MudStepper:

    /// <summary>
    /// Space for all the MudSteps
    /// </summary>
    [Parameter]
    [Category(CategoryTypes.List.Appearance)]
    public RenderFragment? ChildContent { get; set; }

    [Parameter]
    [Category(CategoryTypes.List.Appearance)]
    public RenderFragment<MudStep>? TitleTemplate { get; set; }

    [Parameter]
    [Category(CategoryTypes.List.Appearance)]
    public RenderFragment<MudStep>? LabelTemplate { get; set; }

    [Parameter]
    [Category(CategoryTypes.List.Appearance)]
    public RenderFragment<MudStep>? ConnectorTemplate { get; set; }

As you can see the first parameterless render fragment is for the content of the stepper itself (where the steps are placed). The others are for customizing different parts of each individual step. You can also check out the stepper docs for a nice example that puts them to the test.

@henon
Copy link
Contributor

henon commented Nov 25, 2024

Oh and I forgot to add, the rule with optional RenderFragments in MudBlazor is that they only override the default appearance if they are not null.

@versile2
Copy link
Contributor Author

versile2 commented Nov 27, 2024

ok I've got the logic for RenderFragments, which apparently using multiple (like MudStep) was not as easy as I'd hoped lol. But I don't want to push it as part of this PR, Is anything else missing on this one?

Also any suggestions on how to properly center CustomFragment in a cell? I've tried about 100 variations of this and I'm trying not to "rely on the user" to create the right size item especially since the grid resizes dynamically.

                    @if (_options is { ShowLabels: true } && cell is { Value: not null } && cell is { CustomFragment: null })
                    {
                        @((MarkupString)@$"<text font-size='{_dynamicFontSize}' x='{x + cellWidth / 2}' y='{y + cellHeight / 2}' dominant-baseline='middle' text-anchor='middle'>{FormatValueForDisplay(cell?.Value)}</text>")
                    }
                    else if (cell is { CustomFragment: not null })
                    {
                        <svg x="@(x)" y="@(y)" width="@(cellWidth)" height="@(cellHeight)"
                             preserveAspectRatio="xMidYMid meet">
                            @cell.CustomFragment
                        </svg>
                    }

The only solution that I think is near 100% is making a component, rendering and using JS to resize.

@henon
Copy link
Contributor

henon commented Nov 27, 2024

What if you pass the x, y, with and height into the render fragment? The user would then be responsible for defining an appropriate content that fits into the dimensions. Forgive me if I got anything wrong here, I am not a front-end expert.

                    else if (cell is { CustomFragment: not null })
                    {
                            @cell.CustomFragment(new HeatMapCellData { X=x, Y=y, W=cellWidth, H=cellHeight});
                    }

So the user would need to do this themselves in their template:

                        <svg x="@content.x" y="@(y)" width="@(cellWidth)" height="@(cellHeight)"
                             preserveAspectRatio="xMidYMid meet">
                                  ....
                        </svg>

An example would make that clear.

Or if we hit major roadblocks with this we can also give up on customization.

@versile2
Copy link
Contributor Author

hrmm. There's nothing wrong with letting them only pass svg items with the right height (docs could demonstrate) and that's how the others do it I just think it should be more elegant lol. MudHeatMapCell could also have a width and height property so the user could provide approximate width / height and code can resize appropriately.

@versile2
Copy link
Contributor Author

Oh and I forgot to add, the rule with optional RenderFragments in MudBlazor is that they only override the default appearance if they are not null.

also do you have any changes that need to be made? I think it's still pending your review.

Copy link
Contributor

@henon henon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than the experimental notice it looks good to me.

@henon henon merged commit e2d791c into MudBlazor:dev Nov 28, 2024
@henon
Copy link
Contributor

henon commented Nov 28, 2024

The docs of this component are insane. That's why I added the honorable label epic to this PR. Thanks a lot!

@versile2 versile2 deleted the heatmap branch November 30, 2024 20:15
LLauter pushed a commit to cannellamedia/MudBlazor that referenced this pull request Dec 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Adds a new feature or enhances existing functionality (not fixing a defect) in the main library epic Multiple related tasks/issues that are summarized in one issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants