Files
radzen-blazor/Radzen.Blazor/RadzenSeriesValueLine.razor
Maxim Becker 13326879f0 Render chart tooltips in the same way as standard tooltips (#1745)
* Render chart tooltips in the same way as standard tooltips

* Move OpenChartTooltip method to TooltipService to avoid code duplications

* Avoid partially hiding of chart tooltip near top of page

* Make some of the types internal.

---------

Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2024-10-28 10:01:13 +02:00

138 lines
4.0 KiB
Plaintext

@using Radzen.Blazor.Rendering
@inherits RadzenGridLines
@implements IChartSeriesOverlay
@implements IDisposable
@code {
public RadzenSeriesValueLine()
{
Visible = true;
}
[Parameter]
public virtual double Value { get; set; }
[Parameter]
public RenderFragment<double> TooltipTemplate { get; set; }
IChartSeries series;
[CascadingParameter]
protected IChartSeries Series
{
get
{
return series;
}
set
{
if (value.CoordinateSystem != CoordinateSystem.Cartesian)
{
throw new ArgumentException($"Series must use Cartesian coordinate system");
}
series = value;
if (!series.Overlays.Contains(this))
{
series.Overlays.Add(this);
}
}
}
protected virtual string Name => "Value";
public RenderFragment Render(ScaleBase categoryScale, ScaleBase valueScale)
{
double x1, x2, y1, y2;
if (Chart.ShouldInvertAxes())
{
x1 = x2 = categoryScale.Scale(Value);
if (x1 < 0 || x1 > Chart.CategoryScale.OutputSize)
{
return null;
}
y1 = 0; y2 = Chart.ValueScale.OutputSize;
}
else
{
y1 = y2 = valueScale.Scale(Value);
if (y1 < 0 || y1 > Chart.ValueScale.OutputSize)
{
return null;
}
x1 = 0; x2 = Chart.CategoryScale.OutputSize;
}
var path = $"M{x1.ToInvariantString()} {y1.ToInvariantString()} L{x2.ToInvariantString()} {y2.ToInvariantString()}";
return
@<g>
<Path @key="@($"{path}-{Chart.Series.IndexOf(series)}")" D="@path" Stroke="@Stroke" StrokeWidth="@StrokeWidth" LineType="@LineType" />
</g>
;
}
public bool Contains(double mouseX, double mouseY, int tolerance)
{
if (double.IsNaN(Value))
{
return false;
}
if (Chart.ShouldInvertAxes())
{
var a = Chart.CategoryScale.Scale(Value);
return (mouseY >= -tolerance && mouseY <= Chart.ValueScale.OutputSize + tolerance) && (a >= mouseX - tolerance && a <= mouseX + tolerance);
}
else
{
var a = Chart.ValueScale.Scale(Value);
return (mouseX >= -tolerance && mouseX <= Chart.CategoryScale.OutputSize + tolerance) && (a >= mouseY - tolerance && a <= mouseY + tolerance);
}
}
public RenderFragment RenderTooltip(double mouseX, double mouseY)
{
string text;
if (Chart.ShouldInvertAxes())
{
text = Chart.ValueAxis.Format(Chart.CategoryScale, Value);
}
else
{
text = Chart.ValueAxis.Format(Chart.ValueScale, Value);
}
return builder =>
{
builder.OpenComponent<ChartTooltip>(0);
builder.AddAttribute(1, nameof(ChartTooltip.ChildContent), TooltipTemplate?.Invoke(Value));
builder.AddAttribute(6, nameof(ChartTooltip.Title), series.GetTitle());
builder.AddAttribute(2, nameof(ChartTooltip.Label), Name);
builder.AddAttribute(3, nameof(ChartTooltip.Value), text);
builder.AddAttribute(4, nameof(ChartTooltip.Style), $"border: 1px solid {Stroke};");
builder.AddAttribute(5, nameof(ChartTooltip.Class), "");
builder.CloseComponent();
};
}
/// <inheritdoc />
public Point GetTooltipPosition(double mouseX, double mouseY)
{
if (Chart.ShouldInvertAxes())
{
mouseX = Chart.CategoryScale.Scale(Value);
mouseY = Math.Max(0, Math.Min(Chart.ValueScale.OutputSize, mouseY));
}
else
{
mouseY = Chart.ValueScale.Scale(Value);
mouseX = Math.Max(0, Math.Min(Chart.CategoryScale.OutputSize, mouseX));
}
return new Point { X = mouseX, Y = mouseY };
}
public void Dispose() => series?.Overlays.Remove(this);
}