included the heatmap and time series block to the chart rendering; specific chart logic

This commit is contained in:
Nils Kruthoff 2026-08-10 14:10:21 +02:00
parent e6ed912960
commit b22174b6d9
No known key found for this signature in database
GPG Key ID: A5C0151B4DDB172C
2 changed files with 80 additions and 3 deletions

View File

@ -7,7 +7,20 @@
<div class="chart-block-shell my-3">
<MudPaper Class="chart-block" Outlined="true">
<MudText Typo="Typo.h6" Class="chart-block-title">@chart.Title</MudText>
@if (chart.Type is ChartDefinitionType.PIE or ChartDefinitionType.DONUT)
@if (chart.Type is ChartDefinitionType.TIME_SERIES)
{
<div class="chart-block-plot chart-block-plot-axis">
<MudTimeSeriesChart ChartSeries="@this.TimeSeriesChartSeries"
ChartOptions="@this.ChartOptions"
AxisChartOptions="@this.AxisChartOptions"
TimeLabelSpacing="@this.TimeLabelSpacing"
TimeLabelFormat="@this.TimeLabelFormat"
DataMarkerTooltipTimeLabelFormat="dd-MM-yyyy HH:mm:ss 'UTC'"
Width="100%"
Height="350px" />
</div>
}
else if (chart.Type is ChartDefinitionType.PIE or ChartDefinitionType.DONUT)
{
<div class="chart-block-plot chart-block-plot-circular">
<MudChart ChartType="@this.ChartType"
@ -24,7 +37,7 @@
<MudChart ChartType="@this.ChartType"
ChartSeries="@this.ChartSeries"
XAxisLabels="@chart.Categories.ToArray()"
ChartOptions="@this.ChartOptions"
ChartOptions="@this.CategoryChartOptions"
AxisChartOptions="@this.AxisChartOptions"
Width="100%"
Height="350px" />

View File

@ -1,4 +1,6 @@
using AIStudio.Components;
using System.Globalization;
using AIStudio.Components;
using Microsoft.AspNetCore.Components;
namespace AIStudio.Chat;
@ -16,6 +18,14 @@ public partial class ChartBlock : MSGComponentBase
],
};
private ChartOptions HeatMapChartOptions { get; } = new()
{
ChartPalette = ["#236A50", "#79AE90", "#F2D264", "#C97857", "#6A233D"],
EnableSmoothGradient = true,
YAxisLabelPosition = YAxisLabelPosition.Right,
};
[Parameter]
public ChartBlockParseResult Result { get; set; } = ChartBlockParseResult.Invalid(string.Empty, string.Empty);
@ -26,10 +36,64 @@ public partial class ChartBlock : MSGComponentBase
ChartDefinitionType.LINE => ChartType.Line,
ChartDefinitionType.PIE => ChartType.Pie,
ChartDefinitionType.DONUT => ChartType.Donut,
ChartDefinitionType.HEATMAP => ChartType.HeatMap,
_ => ChartType.Bar,
};
private List<ChartSeries> ChartSeries => this.Result.Chart?.Series
.Select(series => new ChartSeries { Name = series.Name, Data = series.Values.ToArray() })
.ToList() ?? [];
private ChartOptions CategoryChartOptions => this.Result.Chart?.Type is ChartDefinitionType.HEATMAP
? this.HeatMapChartOptions
: this.ChartOptions;
private List<TimeSeriesChartSeries> TimeSeriesChartSeries => this.Result.Chart is not { } chart
? []
: chart.Series
.Select(series => new TimeSeriesChartSeries
{
Name = series.Name,
Data = chart.Categories
.Select((category, index) => new TimeSeriesChartSeries.TimeValue(
DateTimeOffset.Parse(category, CultureInfo.InvariantCulture).UtcDateTime,
series.Values[index]))
.ToList(),
IsVisible = true,
})
.ToList();
private TimeSpan TimeLabelSpacing
{
get
{
var timestamps = this.GetTimeSeriesTimestamps();
if (timestamps.Count < 2)
return TimeSpan.FromSeconds(1);
var range = timestamps[^1] - timestamps[0];
var intervalCount = Math.Min(timestamps.Count - 1, 8);
return TimeSpan.FromTicks(Math.Max(TimeSpan.TicksPerSecond, range.Ticks / intervalCount));
}
}
private string TimeLabelFormat
{
get
{
var timestamps = this.GetTimeSeriesTimestamps();
if (timestamps.Count < 2)
return "yyyy-MM-dd HH:mm";
var range = timestamps[^1] - timestamps[0];
if (range <= TimeSpan.FromDays(2))
return "MM-dd HH:mm";
return range <= TimeSpan.FromDays(730) ? "yyyy-MM-dd" : "yyyy";
}
}
private List<DateTimeOffset> GetTimeSeriesTimestamps() => this.Result.Chart?.Categories
.Select(category => DateTimeOffset.Parse(category, CultureInfo.InvariantCulture).ToUniversalTime())
.ToList() ?? [];
}