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>
This commit is contained in:
Maxim Becker
2024-10-28 09:01:13 +01:00
committed by GitHub
parent 293a871db4
commit 13326879f0
19 changed files with 401 additions and 102 deletions

View File

@@ -3,6 +3,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Bunit;
using Microsoft.Extensions.DependencyInjection;
using Radzen.Blazor.Rendering;
using Xunit;
using Xunit.Abstractions;
@@ -23,6 +24,9 @@ public class ChartTests
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.JSInterop.Setup<Rect>("Radzen.createChart", _ => true).SetResult(new Rect {Left = 0, Top = 0, Width = 200, Height = 200});
ctx.Services.AddScoped<TooltipService>();
ctx.JSInterop.SetupVoid("Radzen.openChartTooltip", _ => true);
ctx.RenderComponent<RadzenChartTooltip>();
var seriesData = Enumerable.Range(0, 5000).Select(i => new Point { X = i, Y = i });
var chart = ctx.RenderComponent<RadzenChart>(chartParameters =>
@@ -42,12 +46,12 @@ public class ChartTests
})));
var stopwatch = Stopwatch.StartNew();
foreach (var _ in Enumerable.Range(0, 10))
foreach (var invocation in Enumerable.Range(0, 10))
{
await chart.InvokeAsync(() => chart.Instance.MouseMove(100, 80));
Assert.Contains("<div class=\"rz-chart-tooltip", chart.Markup);
Assert.Equal((invocation + 1) * 2, ctx.JSInterop.Invocations.Count(x => x.Identifier == "Radzen.openChartTooltip"));
await chart.InvokeAsync(() => chart.Instance.MouseMove(0, 0));
Assert.DoesNotContain("<div class=\"rz-chart-tooltip", chart.Markup);
Assert.Equal(invocation + 1, ctx.JSInterop.Invocations.Count(x => x.Identifier == "Radzen.closeTooltip"));
}
output.WriteLine($"Time took: {stopwatch.Elapsed}");
}

View File

@@ -478,38 +478,30 @@ namespace Radzen.Blazor
}
/// <inheritdoc />
public virtual RenderFragment RenderTooltip(object data, double marginLeft, double marginTop, double chartHeight)
public virtual RenderFragment RenderTooltip(object data)
{
var item = (TItem)data;
var x = TooltipX(item);
var y = TooltipY(item);
return builder =>
{
if (Chart.Tooltip.Shared)
{
var category = PropertyAccess.GetValue(item, CategoryProperty);
builder.OpenComponent<ChartSharedTooltip>(0);
builder.AddAttribute(1, nameof(ChartSharedTooltip.X), x + marginLeft);
builder.AddAttribute(2, nameof(ChartSharedTooltip.Y), y + marginTop);
builder.AddAttribute(3, nameof(ChartSharedTooltip.Class), TooltipClass(item));
builder.AddAttribute(4, nameof(ChartSharedTooltip.Title), TooltipTitle(item));
builder.AddAttribute(4, nameof(ChartSharedTooltip.ChildContent), RenderSharedTooltipItems(category));
builder.AddAttribute(1, nameof(ChartSharedTooltip.Class), TooltipClass(item));
builder.AddAttribute(2, nameof(ChartSharedTooltip.Title), TooltipTitle(item));
builder.AddAttribute(3, nameof(ChartSharedTooltip.ChildContent), RenderSharedTooltipItems(category));
builder.CloseComponent();
}
else
{
builder.OpenComponent<ChartTooltip>(0);
builder.AddAttribute(1, nameof(ChartTooltip.X), x + marginLeft);
builder.AddAttribute(2, nameof(ChartTooltip.Y), y + marginTop);
builder.AddAttribute(3, nameof(ChartTooltip.ChildContent), TooltipTemplate?.Invoke(item));
builder.AddAttribute(4, nameof(ChartTooltip.Title), TooltipTitle(item));
builder.AddAttribute(5, nameof(ChartTooltip.Label), TooltipLabel(item));
builder.AddAttribute(6, nameof(ChartTooltip.Value), TooltipValue(item));
builder.AddAttribute(7, nameof(ChartTooltip.Class), TooltipClass(item));
builder.AddAttribute(8, nameof(ChartTooltip.Style), TooltipStyle(item));
builder.AddAttribute(1, nameof(ChartTooltip.ChildContent), TooltipTemplate?.Invoke(item));
builder.AddAttribute(2, nameof(ChartTooltip.Title), TooltipTitle(item));
builder.AddAttribute(3, nameof(ChartTooltip.Label), TooltipLabel(item));
builder.AddAttribute(4, nameof(ChartTooltip.Value), TooltipValue(item));
builder.AddAttribute(5, nameof(ChartTooltip.Class), TooltipClass(item));
builder.AddAttribute(6, nameof(ChartTooltip.Style), TooltipStyle(item));
builder.CloseComponent();
}
};
@@ -546,6 +538,16 @@ namespace Radzen.Blazor
};
}
/// <inheritdoc />
public Point GetTooltipPosition(object data)
{
var item = (TItem)data;
var x = TooltipX(item);
var y = TooltipY(item);
return new Point { X = x, Y = y };
}
/// <summary>
/// Gets the tooltip inline style.
/// </summary>

View File

@@ -50,20 +50,24 @@ namespace Radzen.Blazor
/// <param name="valueScale">The value scale.</param>
/// <returns>RenderFragment.</returns>
RenderFragment RenderOverlays(ScaleBase categoryScale, ScaleBase valueScale);
/// <summary>
/// Renders the series tooltip.
/// </summary>
/// <param name="data">The data.</param>
/// <param name="marginLeft">The left margin.</param>
/// <param name="marginTop">The right margin.</param>
/// <param name="chartHeight">Height of the whole char area.</param>
/// <returns>RenderFragment.</returns>
RenderFragment RenderTooltip(object data, double marginLeft, double marginTop, double chartHeight);
RenderFragment RenderTooltip(object data);
/// <summary>
/// Renders a tooltip item with the specified data to be displayed in a shared tooltip
/// </summary>
RenderFragment RenderSharedTooltipItem(object category);
/// <summary>
/// Get position of the series tooltip.
/// </summary>
/// <param name="data">The data.</param>
/// <returns>Position.</returns>
Point GetTooltipPosition(object data);
/// <summary>
/// Renders the legend item.
/// </summary>
/// <returns>RenderFragment.</returns>

View File

@@ -28,6 +28,12 @@ namespace Radzen.Blazor
/// <summary>
/// Renders tooltip
/// </summary>
RenderFragment RenderTooltip(double mouseX, double mouseY, double marginLeft, double marginTop);
RenderFragment RenderTooltip(double mouseX, double mouseY);
/// <summary>
/// Get position of the overlay tooltip.
/// </summary>
/// <returns>Position.</returns>
Point GetTooltipPosition(double mouseX, double mouseY);
}
}

View File

@@ -38,12 +38,6 @@
@donut.RenderTitle(MarginLeft, MarginTop)
}
}
<ChartTooltipContainer @ref="@chartTooltipContainer">
@if (tooltip != null)
{
@tooltip
}
</ChartTooltipContainer>
</CascadingValue>
}

View File

@@ -52,6 +52,9 @@ namespace Radzen.Blazor
/// </summary>
[Parameter]
public EventCallback<LegendClickEventArgs> LegendClick { get; set; }
[Inject]
TooltipService TooltipService { get; set; }
/// <summary>
/// Gets the runtime width of the chart.
@@ -276,7 +279,6 @@ namespace Radzen.Blazor
}
}
ChartTooltipContainer chartTooltipContainer;
RenderFragment tooltip;
object tooltipData;
double mouseX;
@@ -367,11 +369,15 @@ namespace Radzen.Blazor
{
foreach (var overlay in series.Overlays.Reverse())
{
if (overlay.Visible && overlay.Contains(mouseX - MarginLeft, mouseY - MarginTop, TooltipTolerance))
if (overlay.Visible && overlay.Contains(queryX, queryY, TooltipTolerance))
{
tooltipData = null;
tooltip = overlay.RenderTooltip(mouseX, mouseY, MarginLeft, MarginTop);
chartTooltipContainer.Refresh();
tooltip = overlay.RenderTooltip(queryX, queryY);
var tooltipPosition = overlay.GetTooltipPosition(queryX, queryY);
TooltipService.OpenChartTooltip(Element, tooltipPosition.X + MarginLeft, tooltipPosition.Y + MarginTop, _ => tooltip, new ChartTooltipOptions
{
ColorScheme = ColorScheme
});
await Task.Yield();
return;
@@ -399,21 +405,25 @@ namespace Radzen.Blazor
if (closestSeriesData != tooltipData)
{
tooltipData = closestSeriesData;
tooltip = closestSeries.RenderTooltip(closestSeriesData, MarginLeft, MarginTop, Height ?? 0);
chartTooltipContainer.Refresh();
tooltip = closestSeries.RenderTooltip(closestSeriesData);
var tooltipPosition = closestSeries.GetTooltipPosition(closestSeriesData);
TooltipService.OpenChartTooltip(Element, tooltipPosition.X + MarginLeft, tooltipPosition.Y + MarginTop, _ => tooltip, new ChartTooltipOptions
{
ColorScheme = ColorScheme
});
await Task.Yield();
}
return;
}
}
if (tooltip != null)
{
tooltipData = null;
tooltip = null;
if (tooltip != null)
{
tooltipData = null;
tooltip = null;
chartTooltipContainer.Refresh();
await Task.Yield();
}
TooltipService.Close();
await Task.Yield();
}
}

View File

@@ -0,0 +1,184 @@
@implements IAsyncDisposable
@using Microsoft.JSInterop
@inject IJSRuntime JSRuntime
@foreach (var tooltip in tooltips)
{
<div id="@UniqueID"
style="display: none; top: 0; left: 0; z-index: 1001; position: absolute;"
class="@($"rz-scheme-{tooltip.Options.ColorScheme.ToString().ToLowerInvariant()}")">
@tooltip.Options.ChildContent(Service)
</div>
}
@code {
public string UniqueID { get; set; }
[Inject] private TooltipService Service { get; set; }
List<ChartTooltip> tooltips = new List<ChartTooltip>();
async Task Open(ElementReference chart, double x, double y, ChartTooltipOptions options)
{
tooltips.Clear();
tooltips.Add(new ChartTooltip { Options = options, Chart = chart, X = x, Y = y });
await InvokeAsync(StateHasChanged);
var tooltip = tooltips.LastOrDefault();
if (tooltip != null)
{
await JSRuntime.InvokeVoidAsync("Radzen.openChartTooltip",
tooltip.Chart,
x,
y,
UniqueID);
}
}
bool IsJSRuntimeAvailable { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
IsJSRuntimeAvailable = true;
var tooltip = tooltips.LastOrDefault();
if (tooltip != null)
{
await JSRuntime.InvokeVoidAsync("Radzen.openChartTooltip",
tooltip.Chart,
tooltip.X,
tooltip.Y,
UniqueID,
Reference,
"RadzenChartTooltip.CloseTooltip");
}
}
private DotNetObjectReference<RadzenChartTooltip> reference;
/// <summary>
/// Gets the reference for the current component.
/// </summary>
/// <value>The reference.</value>
protected DotNetObjectReference<RadzenChartTooltip> Reference
{
get
{
if (reference == null)
{
reference = DotNetObjectReference.Create(this);
}
return reference;
}
}
/// <summary>
/// Closes this instance.
/// </summary>
[JSInvokable("RadzenChartTooltip.CloseTooltip")]
public void CloseTooltip()
{
Service.Close();
}
public async Task Close()
{
var lastTooltip = tooltips.LastOrDefault();
if (lastTooltip != null)
{
if (IsJSRuntimeAvailable)
{
try
{
tooltips.Remove(lastTooltip);
await JSRuntime.InvokeVoidAsync("Radzen.closeTooltip", UniqueID);
}
catch
{
// ignored
}
}
}
await InvokeAsync(StateHasChanged);
}
public async ValueTask DisposeAsync()
{
while (tooltips.Count != 0)
{
await Close();
}
reference?.Dispose();
reference = null;
if (IsJSRuntimeAvailable)
{
try
{
await JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", UniqueID);
}
catch
{
// ignored
}
}
Service.OnOpenChartTooltip -= OnOpen;
Service.OnClose -= OnClose;
Service.OnNavigate -= OnNavigate;
}
protected override void OnInitialized()
{
UniqueID = Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Replace("/", "-").Replace("+", "-").Substring(0, 10);
Service.OnOpenChartTooltip += OnOpen;
Service.OnClose += OnClose;
Service.OnNavigate += OnNavigate;
}
void OnOpen(ElementReference element, double x, double y, ChartTooltipOptions options)
{
Open(element, x, y, options).ConfigureAwait(false);
}
void OnClose()
{
Close().ConfigureAwait(false);
}
void OnNavigate()
{
JSRuntime.InvokeVoidAsync("Radzen.closePopup", UniqueID);
}
private sealed class ChartTooltip
{
/// <summary>
/// Gets or sets the owning chart.
/// </summary>
/// <value>The chart.</value>
public ElementReference Chart { get; set; }
/// <summary>
/// Gets or sets the horizontal position of the tooltip.
/// </summary>
/// <value>The position.</value>
public double X { get; set; }
/// <summary>
/// Gets or sets the vertical position of the tooltip.
/// </summary>
/// <value>The position.</value>
public double Y { get; set; }
/// <summary>
/// Gets or sets the options.
/// </summary>
/// <value>The options.</value>
public ChartTooltipOptions Options { get; set; }
}
}

View File

@@ -2,6 +2,7 @@
<RadzenNotification @attributes="Attributes" />
<RadzenContextMenu @attributes="Attributes" />
<RadzenTooltip @attributes="Attributes" />
<RadzenChartTooltip @attributes="Attributes" />
@code {
/// <summary>

View File

@@ -152,11 +152,17 @@ namespace Radzen.Blazor
}
/// <inheritdoc/>
public RenderFragment RenderTooltip(double mouseX, double mouseY, double marginLeft, double marginTop)
public RenderFragment RenderTooltip(double mouseX, double mouseY)
{
return null;
}
/// <inheritdoc />
public Point GetTooltipPosition(double mouseX, double mouseY)
{
return new Point { X = mouseX, Y = mouseY };
}
/// <inheritdoc/>
public void Dispose() => series?.Overlays.Remove(this);
}

View File

@@ -54,10 +54,16 @@
return false;
}
public RenderFragment RenderTooltip(double mouseX, double mouseY, double marginLeft, double marginTop)
public RenderFragment RenderTooltip(double mouseX, double mouseY)
{
return null;
}
/// <inheritdoc />
public Point GetTooltipPosition(double mouseX, double mouseY)
{
return new Point { X = mouseX, Y = mouseY };
}
public void Dispose() => series?.Overlays.Remove(this);
}

View File

@@ -73,10 +73,16 @@
return false;
}
public RenderFragment RenderTooltip(double mouseX, double mouseY, double marginLeft, double marginTop)
public RenderFragment RenderTooltip(double mouseX, double mouseY)
{
return null;
}
/// <inheritdoc />
public Point GetTooltipPosition(double mouseX, double mouseY)
{
return new Point { X = mouseX, Y = mouseY };
}
public void Dispose() => series?.Overlays.Remove(this);
}

View File

@@ -88,19 +88,15 @@
}
}
public RenderFragment RenderTooltip(double mouseX, double mouseY, double marginLeft, double marginTop)
public RenderFragment RenderTooltip(double mouseX, double mouseY)
{
string text;
if (Chart.ShouldInvertAxes())
{
mouseX = Chart.CategoryScale.Scale(Value) + marginLeft;
mouseY = Math.Max(marginTop, Math.Min(Chart.ValueScale.OutputSize + marginTop, mouseY));
text = Chart.ValueAxis.Format(Chart.CategoryScale, Value);
}
else
{
mouseY = Chart.ValueScale.Scale(Value) + marginTop;
mouseX = Math.Max(marginLeft, Math.Min(Chart.CategoryScale.OutputSize + marginLeft, mouseX));
text = Chart.ValueAxis.Format(Chart.ValueScale, Value);
}
@@ -108,20 +104,35 @@
{
builder.OpenComponent<ChartTooltip>(0);
builder.AddAttribute(1, nameof(ChartTooltip.X), mouseX);
builder.AddAttribute(2, nameof(ChartTooltip.Y), mouseY);
builder.AddAttribute(1, nameof(ChartTooltip.ChildContent), TooltipTemplate?.Invoke(Value));
builder.AddAttribute(3, nameof(ChartTooltip.ChildContent), TooltipTemplate == null ? null : TooltipTemplate(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(8, nameof(ChartTooltip.Title), series.GetTitle());
builder.AddAttribute(4, nameof(ChartTooltip.Label), Name);
builder.AddAttribute(5, nameof(ChartTooltip.Value), text);
builder.AddAttribute(6, nameof(ChartTooltip.Style), $"border: 1px solid {Stroke};");
builder.AddAttribute(7, nameof(ChartTooltip.Class), "");
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);
}

View File

@@ -1,4 +1,4 @@
<div class="rz-chart-tooltip rz-chart-shared-tooltip @Class" style="left: @(X.ToInvariantString())px; top: @(Y.ToInvariantString())px">
<div class="rz-chart-tooltip rz-chart-shared-tooltip @Class">
<div class="rz-chart-tooltip-content">
<div class="rz-chart-tooltip-title">@Title</div>
@ChildContent
@@ -9,12 +9,6 @@
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public double X { get; set; }
[Parameter]
public double Y { get; set; }
[Parameter]
public string Class { get; set; }

View File

@@ -1,4 +1,4 @@
<div class="rz-chart-tooltip @Class" style="left: @(X.ToInvariantString())px; top: @(Y.ToInvariantString())px">
<div class="rz-chart-tooltip @Class">
<div class="rz-chart-tooltip-content" style="@Style">
@if (ChildContent != null)
{
@@ -21,12 +21,6 @@
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public double X { get; set; }
[Parameter]
public double Y { get; set; }
[Parameter]
public string Title { get; set; }

View File

@@ -1,12 +0,0 @@
@ChildContent
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
internal void Refresh()
{
StateHasChanged();
}
}

View File

@@ -3,11 +3,12 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Radzen.Blazor;
namespace Radzen
{
/// <summary>
/// Class TooltipService. Contains various methods with options to open and close tooltips.
/// Class TooltipService. Contains various methods with options to open and close tooltips.
/// Should be added as scoped service in the application services and RadzenTooltip should be added in application main layout.
/// Implements the <see cref="IDisposable" />
/// </summary>
@@ -75,6 +76,11 @@ namespace Radzen
/// </summary>
public event Action<ElementReference, Type, TooltipOptions> OnOpen;
/// <summary>
/// Occurs when [on open chart tooltip].
/// </summary>
internal event Action<ElementReference, double, double, ChartTooltipOptions> OnOpenChartTooltip;
/// <summary>
/// Opens the specified element.
/// </summary>
@@ -169,6 +175,23 @@ namespace Radzen
OpenTooltip<object>(element, options);
}
/// <summary>
/// Opens the specified chart tooltip.
/// </summary>
/// <param name="element">The chart element.</param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="childContent">Content of the chart tooltip.</param>
/// <param name="o">The options of the chart tooltip.</param>
internal void OpenChartTooltip(ElementReference element, double x, double y, RenderFragment<TooltipService> childContent, ChartTooltipOptions o = null)
{
var options = o ?? new ChartTooltipOptions();
options.ChildContent = childContent;
OnOpenChartTooltip?.Invoke(element, x, y, options);
}
/// <summary>
/// Opens the tooltip.
/// </summary>
@@ -288,4 +311,18 @@ namespace Radzen
/// <value>The element.</value>
public ElementReference Element { get; set; }
}
internal class ChartTooltipOptions
{
/// <summary>
/// Gets or sets the color scheme used to render the tooltip.
/// </summary>
/// <value>The color scheme.</value>
public ColorScheme ColorScheme { get; set; }
/// <summary>
/// Gets or sets the child content.
/// </summary>
/// <value>The child content.</value>
public RenderFragment<TooltipService> ChildContent { get; set; }
}
}

View File

@@ -234,12 +234,18 @@ $chart-color-schemes: (
.rz-chart-tooltip {
position: absolute;
transform: translate(-50%, -100%);
transition: top 0.2s, left 0.2s;
top: 0;
left: 0;
}
.rz-top-chart-tooltip {
transform: translate(-50%, -100%);
}
.rz-bottom-chart-tooltip {
transform: translate(-50%, 0);
}
.rz-chart-tooltip-content {
background: var(--rz-chart-tooltip-background);
color: var(--rz-chart-tooltip-color);
@@ -253,16 +259,25 @@ $chart-color-schemes: (
.rz-chart-tooltip {
&:not(.rz-pie-tooltip) {
.rz-chart-tooltip-content {
margin-bottom: 15px;
&:after {
content: ' ';
position: absolute;
width: 8px;
height: 8px;
left: 50%;
bottom: 0;
background-color: inherit;
transform-origin: center;
}
}
}
}
.rz-top-chart-tooltip {
&:not(.rz-pie-tooltip) {
.rz-chart-tooltip-content {
margin-bottom: 15px;
&:after {
left: 50%;
bottom: 0;
transform: translate(-50%, -11px) rotate(45deg);
border-bottom: inherit;
border-right: inherit;
@@ -271,6 +286,21 @@ $chart-color-schemes: (
}
}
.rz-bottom-chart-tooltip {
&:not(.rz-pie-tooltip) {
.rz-chart-tooltip-content {
margin-top: 15px;
&:after {
left: 50%;
top: 0;
transform: translate(-50%, 11px) rotate(45deg);
border-top: inherit;
border-left: inherit;
}
}
}
}
.rz-chart-tooltip-title {
font-weight: 700;
}
@@ -299,7 +329,7 @@ $chart-color-schemes: (
justify-content: space-between;
gap: 1rem;
padding: 0.125rem 0.5rem;
border-radius: var( --rz-chart-tooltip-item-border-radius);
border-radius: var(--rz-chart-tooltip-item-border-radius);
&:hover {
background-color: var(--rz-chart-tooltip-item-hover-background-color);

View File

@@ -1746,9 +1746,6 @@ window.Radzen = {
var inside = false;
ref.mouseMoveHandler = this.throttle(function (e) {
if (inside) {
if (e.target.matches('.rz-chart-tooltip-content') || e.target.closest('.rz-chart-tooltip-content')) {
return
}
var rect = ref.getBoundingClientRect();
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;
@@ -1758,7 +1755,10 @@ window.Radzen = {
ref.mouseEnterHandler = function () {
inside = true;
};
ref.mouseLeaveHandler = function () {
ref.mouseLeaveHandler = function (e) {
if (e.relatedTarget && (e.relatedTarget.matches('.rz-chart-tooltip') || e.relatedTarget.closest('.rz-chart-tooltip'))) {
return;
}
inside = false;
instance.invokeMethodAsync('MouseMove', -1, -1);
};
@@ -2440,5 +2440,27 @@ window.Radzen = {
} else {
start();
}
},
openChartTooltip: function (chart, x, y, id, instance, callback) {
Radzen.closeTooltip(id);
var chartRect = chart.getBoundingClientRect();
x = Math.max(2, chartRect.left + x);
y = Math.max(2, chartRect.top + y);
Radzen.openPopup(chart, id, false, null, x, y, instance, callback, true, false, false);
var popup = document.getElementById(id);
if (!popup) {
return;
}
var tooltipContent = popup.children[0];
var tooltipContentRect = tooltipContent.getBoundingClientRect();
var tooltipContentClassName = 'rz-top-chart-tooltip';
if (y - tooltipContentRect.height < 0) {
tooltipContentClassName = 'rz-bottom-chart-tooltip';
}
tooltipContent.classList.remove('rz-top-chart-tooltip');
tooltipContent.classList.remove('rz-bottom-chart-tooltip');
tooltipContent.classList.add(tooltipContentClassName);
}
};

View File

@@ -176,9 +176,9 @@ The Radzen Blazor components are distributed via the <a href="">Radzen.Blazor</a
}
</code>
</pre>
<h3 id="outlets"><a href="#outlets">Dialog, context menu, tooltip and notification</a></h3>
<h3 id="outlets"><a href="#outlets">Dialog, context menu, tooltip, chart tooltip and notification</a></h3>
<p>
To use RadzenDialog, RadzenContextMenu, RadzenTooltip and RadzenNotification you need to perform a few additional steps.
To use RadzenDialog, RadzenContextMenu, RadzenTooltip, RadzenChartTooltip and RadzenNotification you need to perform a few additional steps.
</p>
<ol>
<li>Open <code>MainLayout.razor</code> and add this code