mirror of
https://github.com/radzenhq/radzen-blazor.git
synced 2026-07-08 18:16:08 +00:00
Add RTL-aware Start/End legend positions and default to End
This commit is contained in:
@@ -35,6 +35,76 @@ namespace Radzen.Blazor.Tests
|
||||
return double.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
private static RenderFragment LegendWithSeries(LegendPosition position) => builder =>
|
||||
{
|
||||
builder.OpenComponent<RadzenLegend>(0);
|
||||
builder.AddAttribute(1, nameof(RadzenLegend.Position), position);
|
||||
builder.CloseComponent();
|
||||
|
||||
builder.OpenComponent<RadzenLineSeries<DataItem>>(2);
|
||||
builder.AddAttribute(3, nameof(RadzenLineSeries<DataItem>.CategoryProperty), nameof(DataItem.Category));
|
||||
builder.AddAttribute(4, nameof(RadzenLineSeries<DataItem>.ValueProperty), nameof(DataItem.Value));
|
||||
builder.AddAttribute(5, nameof(RadzenLineSeries<DataItem>.Title), "Series");
|
||||
builder.AddAttribute(6, nameof(RadzenLineSeries<DataItem>.Data), (IEnumerable<DataItem>)SampleData);
|
||||
builder.CloseComponent();
|
||||
};
|
||||
|
||||
[Theory]
|
||||
[InlineData(LegendPosition.Start, "rz-legend-left")]
|
||||
[InlineData(LegendPosition.End, "rz-legend-right")]
|
||||
public async Task StartEndLegend_InLtr_ResolvesToPhysicalSide(LegendPosition position, string expectedClass)
|
||||
{
|
||||
using var ctx = CreateChartContext();
|
||||
|
||||
var chart = ctx.RenderComponent<RadzenChart>(p => p.Add(c => c.ChildContent, LegendWithSeries(position)));
|
||||
await chart.InvokeAsync(() => chart.Instance.Resize(400, 300));
|
||||
|
||||
Assert.Contains(expectedClass, chart.Markup);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(LegendPosition.Start, "rz-legend-right")]
|
||||
[InlineData(LegendPosition.End, "rz-legend-left")]
|
||||
public async Task StartEndLegend_InRtl_FlipsToOppositeSide(LegendPosition position, string expectedClass)
|
||||
{
|
||||
using var ctx = CreateChartContext();
|
||||
|
||||
var chart = ctx.RenderComponent<RadzenChart>(p => p.Add(c => c.ChildContent, LegendWithSeries(position)));
|
||||
await chart.InvokeAsync(() => chart.Instance.Resize(400, 300));
|
||||
await chart.InvokeAsync(() => chart.Instance.SetRTL(true));
|
||||
|
||||
Assert.Contains(expectedClass, chart.Markup);
|
||||
}
|
||||
|
||||
private static RenderFragment DefaultLegendWithSeries() => builder =>
|
||||
{
|
||||
builder.OpenComponent<RadzenLegend>(0);
|
||||
builder.CloseComponent();
|
||||
|
||||
builder.OpenComponent<RadzenLineSeries<DataItem>>(1);
|
||||
builder.AddAttribute(2, nameof(RadzenLineSeries<DataItem>.CategoryProperty), nameof(DataItem.Category));
|
||||
builder.AddAttribute(3, nameof(RadzenLineSeries<DataItem>.ValueProperty), nameof(DataItem.Value));
|
||||
builder.AddAttribute(4, nameof(RadzenLineSeries<DataItem>.Title), "Series");
|
||||
builder.AddAttribute(5, nameof(RadzenLineSeries<DataItem>.Data), (IEnumerable<DataItem>)SampleData);
|
||||
builder.CloseComponent();
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public async Task DefaultLegend_RendersOnRightInLtr_AndFlipsToLeftInRtl()
|
||||
{
|
||||
using var ctx = CreateChartContext();
|
||||
|
||||
// No Position set -> defaults to LegendPosition.End.
|
||||
var chart = ctx.RenderComponent<RadzenChart>(p => p.Add(c => c.ChildContent, DefaultLegendWithSeries()));
|
||||
await chart.InvokeAsync(() => chart.Instance.Resize(400, 300));
|
||||
|
||||
Assert.Contains("rz-legend-right", chart.Markup);
|
||||
|
||||
await chart.InvokeAsync(() => chart.Instance.SetRTL(true));
|
||||
|
||||
Assert.Contains("rz-legend-left", chart.Markup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TopLegend_WithManyWrappingSeries_ReservesMoreSpaceThanSingleRow()
|
||||
{
|
||||
|
||||
@@ -20,6 +20,14 @@ namespace Radzen.Blazor
|
||||
/// <summary>
|
||||
/// The legend is below the series.
|
||||
/// </summary>
|
||||
Bottom
|
||||
Bottom,
|
||||
/// <summary>
|
||||
/// The legend is at the inline-start side of the series — left in left-to-right mode, right in right-to-left mode.
|
||||
/// </summary>
|
||||
Start,
|
||||
/// <summary>
|
||||
/// The legend is at the inline-end side of the series — right in left-to-right mode, left in right-to-left mode.
|
||||
/// </summary>
|
||||
End
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,6 +242,18 @@ namespace Radzen.Blazor
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the legend position to a concrete side, mapping the direction-aware
|
||||
/// <see cref="LegendPosition.Start"/> / <see cref="LegendPosition.End"/> values to
|
||||
/// <see cref="LegendPosition.Left"/> / <see cref="LegendPosition.Right"/> based on <see cref="IsRTL"/>.
|
||||
/// </summary>
|
||||
internal LegendPosition EffectiveLegendPosition => (Legend?.Position ?? LegendPosition.Right) switch
|
||||
{
|
||||
LegendPosition.Start => IsRTL ? LegendPosition.Right : LegendPosition.Left,
|
||||
LegendPosition.End => IsRTL ? LegendPosition.Left : LegendPosition.Right,
|
||||
var position => position
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the callback invoked when a user clicks on a data point or segment in a chart series.
|
||||
/// Provides information about the clicked series, data item, and value in the event arguments.
|
||||
@@ -717,9 +729,11 @@ namespace Radzen.Blazor
|
||||
|
||||
if (Legend.Visible)
|
||||
{
|
||||
if (Legend.Position == LegendPosition.Right || Legend.Position == LegendPosition.Left)
|
||||
var legendPosition = EffectiveLegendPosition;
|
||||
|
||||
if (legendPosition == LegendPosition.Right || legendPosition == LegendPosition.Left)
|
||||
{
|
||||
if (Legend.Position == LegendPosition.Right)
|
||||
if (legendPosition == LegendPosition.Right)
|
||||
{
|
||||
MarginRight = legendSize + 16 + (IsRTL ? valueAxisSize : additionalAxesWidth);
|
||||
}
|
||||
@@ -728,9 +742,9 @@ namespace Radzen.Blazor
|
||||
MarginLeft = legendSize + 16 + (IsRTL ? additionalAxesWidth : valueAxisSize);
|
||||
}
|
||||
}
|
||||
else if (Legend.Position == LegendPosition.Top || Legend.Position == LegendPosition.Bottom)
|
||||
else if (legendPosition == LegendPosition.Top || legendPosition == LegendPosition.Bottom)
|
||||
{
|
||||
if (Legend.Position == LegendPosition.Top)
|
||||
if (legendPosition == LegendPosition.Top)
|
||||
{
|
||||
MarginTop = legendSize + 16;
|
||||
}
|
||||
|
||||
@@ -11,9 +11,10 @@ namespace Radzen.Blazor
|
||||
/// <summary>
|
||||
/// Gets or sets the position.
|
||||
/// </summary>
|
||||
/// <value>The position.</value>
|
||||
/// <value>The position. Default is <see cref="LegendPosition.End"/>, which renders on the right
|
||||
/// in left-to-right mode and automatically flips to the left in right-to-left mode.</value>
|
||||
[Parameter]
|
||||
public LegendPosition Position { get; set; }
|
||||
public LegendPosition Position { get; set; } = LegendPosition.End;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="RadzenLegend"/> is visible.
|
||||
@@ -33,7 +34,8 @@ namespace Radzen.Blazor
|
||||
|
||||
var size = 16 * 0.875;
|
||||
|
||||
if (Position == LegendPosition.Right || Position == LegendPosition.Left)
|
||||
if (Position == LegendPosition.Right || Position == LegendPosition.Left
|
||||
|| Position == LegendPosition.Start || Position == LegendPosition.End)
|
||||
{
|
||||
if (chart.Series.Any())
|
||||
{
|
||||
|
||||
@@ -21,6 +21,6 @@
|
||||
public RadzenChart? Chart { get; set; }
|
||||
|
||||
string Class => ClassList.Create("rz-legend")
|
||||
.Add($"rz-legend-{Chart?.Legend?.Position ?? LegendPosition.Right}".ToLowerInvariant())
|
||||
.Add($"rz-legend-{Chart?.EffectiveLegendPosition ?? LegendPosition.Right}".ToLowerInvariant())
|
||||
.ToString();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user