Skip to content

Commit 7fa11b7

Browse files
authored
Merge pull request #83 from apexcharts/custom-tooltip
Custom tooltip
2 parents 46de30b + f7df618 commit 7fa11b7

File tree

11 files changed

+290
-12
lines changed

11 files changed

+290
-12
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<Row>
2+
<RowCol Md=12 Lg=6>
3+
<ApexChart TItem="Order"
4+
Title="Order Net Value"
5+
OnDataPointEnter="DataPointEnter"
6+
OnDataPointLeave=DataPointLeave>
7+
8+
<ApexPointSeries TItem="Order"
9+
Items="Orders"
10+
Name="Net Value"
11+
SeriesType="SeriesType.Line"
12+
XValue="@(e => e.Country)"
13+
YAggregate="@(e => e.Sum(e => e.NetValue))"
14+
OrderByDescending="e=>e.X" />
15+
16+
<ApexPointSeries TItem="Order"
17+
Items="Orders"
18+
Name="Gross Value"
19+
SeriesType="SeriesType.Bar"
20+
XValue="@(e => e.Country)"
21+
YAggregate="@(e => e.Sum(e => e.GrossValue))"
22+
OrderByDescending="e=>e.X" />
23+
</ApexChart>
24+
</RowCol>
25+
<RowCol Md=12 Lg=6>
26+
@if (hoverData != null)
27+
{
28+
<Row>
29+
<RowCol Auto>
30+
<div class=p-3>
31+
@{
32+
var dataPoint = (DataPoint<Order>)hoverData.DataPoint;
33+
<h1>@hoverData.DataPoint.X</h1>
34+
<div>Name: @hoverData.Series.Name</div>
35+
<div>Value: @dataPoint.Y?.ToString("N0")</div>
36+
}
37+
</div>
38+
</RowCol>
39+
</Row>
40+
}
41+
</RowCol>
42+
</Row>
43+
44+
@code {
45+
private List<Order> Orders { get; set; } = SampleData.GetOrders();
46+
private HoverData<Order> hoverData;
47+
48+
public void DataPointEnter(HoverData<Order> hoverData)
49+
{
50+
this.hoverData = hoverData;
51+
}
52+
53+
public void DataPointLeave(HoverData<Order> hoverData)
54+
{
55+
this.hoverData = null;
56+
}
57+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
@page "/events/data-point-hover"
2+
3+
<DocExamples Title="Data Point Hover">
4+
5+
<Description>
6+
Move the mouse over an datapoint to trigger an event
7+
</Description>
8+
9+
<ChildContent>
10+
<CodeSnippet Title="Basic" ClassName=@typeof(Basic).ToString()>
11+
<Snippet>
12+
<Basic />
13+
</Snippet>
14+
</CodeSnippet>
15+
</ChildContent>
16+
17+
18+
</DocExamples>

docs/BlazorApexCharts.Docs/Components/Features/Formatters/FormatterSamples.razor

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
@page "/features/formatters"
22

33
<DocExamples Title="Formatters">
4-
54

65
<CodeSnippet Title="Use javascript" ClassName=@typeof(UseJavascript).ToString()>
76
<Snippet>
@@ -37,5 +36,4 @@
3736

3837

3938

40-
4139
</DocExamples>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<DemoContainer>
2+
<ApexChart TItem="Order"
3+
Title="Order Net Value"
4+
Options=options>
5+
6+
<ApexPointTooltip>
7+
<div class="p-1">
8+
@{
9+
var dataPoint = (DataPoint<Order>)context.DataPoint;
10+
<h3>@context.DataPoint.X</h3>
11+
12+
<Row class="mb-2">
13+
<RowCol Auto>
14+
<Badge style="background-color:#FF0000">Gross Value</Badge>
15+
</RowCol>
16+
<RowCol Auto>
17+
<span class="@(context.SeriesIndex == 0 ? "strong": "")">
18+
@dataPoint.Items.Sum(e=> e.GrossValue).ToString("n0")
19+
</span>
20+
</RowCol>
21+
</Row>
22+
23+
<Row>
24+
<RowCol Auto>
25+
<Badge style="background-color:#000080">Net Value</Badge>
26+
</RowCol>
27+
<RowCol Auto>
28+
<span class="@(context.SeriesIndex == 1 ? "strong": "")">
29+
@dataPoint.Items.Sum(e=> e.NetValue).ToString("n0")
30+
</span>
31+
</RowCol>
32+
</Row>
33+
}
34+
</div>
35+
</ApexPointTooltip>
36+
37+
<ChildContent>
38+
<ApexPointSeries TItem="Order"
39+
Items="Orders"
40+
Name="Gross Value"
41+
SeriesType="SeriesType.Line"
42+
XValue="@(e => e.Country)"
43+
YAggregate="@(e => e.Sum(e => e.GrossValue))"
44+
OrderByDescending="e=>e.Y"
45+
Stroke="@(new SeriesStroke { Color = "#FF0000", Width=4})" />
46+
47+
<ApexPointSeries TItem="Order"
48+
Items="Orders"
49+
Name="Net Value"
50+
SeriesType="SeriesType.Line"
51+
XValue="@(e => e.Country)"
52+
YAggregate="@(e => e.Sum(e => e.NetValue))"
53+
OrderByDescending="e=>e.Y"
54+
Stroke="@(new SeriesStroke { Color = "#000080", Width=4})" />
55+
</ChildContent>
56+
</ApexChart>
57+
58+
</DemoContainer>
59+
60+
@code {
61+
private List<Order> Orders { get; set; } = SampleData.GetOrders();
62+
private ApexChartOptions<Order> options { get; set; } = new ApexChartOptions<Order>();
63+
64+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@page "/features/tooltip"
2+
3+
<DocExamples Title="Tooltip">
4+
5+
<CodeSnippet Title="Custom" ClassName=@typeof(CustomTooltip).ToString()>
6+
<Snippet>
7+
<CustomTooltip />
8+
</Snippet>
9+
</CodeSnippet>
10+
11+
12+
</DocExamples>

docs/BlazorApexCharts.Docs/Shared/MainNavigation.razor

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,10 @@
9999
<Icon class="icon" IconType="@Icons.Bolt" />
100100
</MenuItemIcon>
101101
<SubMenu>
102+
<NavbarMenuItem Text="Data Point Hover" Href="events/data-point-hover" />
102103
<NavbarMenuItem Text="Data Point Selection" Href="events/data-point-selection" />
103104
<NavbarMenuItem Text="Legend Click" Href="events/legend-click" />
104105

105-
106106
</SubMenu>
107107
</NavbarMenuItem>
108108

@@ -118,6 +118,7 @@
118118
<NavbarMenuItem Text="Legend" Href="features/legend" />
119119
<NavbarMenuItem Text="Performance" Href="features/performance" />
120120
<NavbarMenuItem Text="Syncronized charts" Href="features/syncronized" />
121+
<NavbarMenuItem Text="Tooltip" Href="features/tooltip" />
121122
</SubMenu>
122123

123124
</NavbarMenuItem>

src/Blazor-ApexCharts/ApexChart.razor

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1-
2-
@typeparam TItem
1+
@typeparam TItem
32
@namespace ApexCharts
43

54
<div @ref=ChartContainer id="@chartId" />
65
<CascadingValue Value="(ApexChart<TItem>)this" Name="Chart">
76
@ChildContent
7+
8+
@if (ApexPointTooltip != null)
9+
{
10+
<div style="display:none" id="apex-tooltip-@ChartId">
11+
@if (tooltipData != null)
12+
{
13+
@ApexPointTooltip(tooltipData)
14+
}
15+
</div>
16+
}
17+
818
</CascadingValue>

src/Blazor-ApexCharts/ApexChart.razor.cs

Lines changed: 87 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@ public partial class ApexChart<TItem> : IDisposable where TItem : class
1515
[Inject] private IServiceProvider ServiceProvider { get; set; }
1616
[Inject] private IJSRuntime JSRuntime { get; set; }
1717
[Parameter] public RenderFragment ChildContent { get; set; }
18+
[Parameter] public RenderFragment<HoverData<TItem>> ApexPointTooltip { get; set; }
1819
[Parameter] public ApexChartOptions<TItem> Options { get; set; } = new ApexChartOptions<TItem>();
1920
[Parameter] public string Title { get; set; }
2021
[Parameter] public XAxisType? XAxisType { get; set; }
2122
[Parameter] public bool Debug { get; set; }
2223
[Parameter] public object Width { get; set; }
2324
[Parameter] public object Height { get; set; }
2425
[Parameter] public EventCallback<SelectedData<TItem>> OnDataPointSelection { get; set; }
26+
[Parameter] public EventCallback<HoverData<TItem>> OnDataPointEnter { get; set; }
27+
[Parameter] public EventCallback<HoverData<TItem>> OnDataPointLeave { get; set; }
2528
[Parameter] public EventCallback<LegendClicked<TItem>> OnLegendClicked { get; set; }
2629

2730
[Parameter] public EventCallback OnRendered { get; set; }
@@ -36,7 +39,9 @@ public partial class ApexChart<TItem> : IDisposable where TItem : class
3639
private bool isReady;
3740
private bool forceRender = true;
3841
private string chartId;
39-
public string ChartId => ChartId;
42+
private HoverData<TItem> tooltipData;
43+
44+
public string ChartId => chartId;
4045

4146
protected override async Task OnAfterRenderAsync(bool firstRender)
4247
{
@@ -214,8 +219,8 @@ private void UpdateDataForNoAxisCharts()
214219
var noAxisSeries = Options.Series.First();
215220
Options.Labels = noAxisSeries.Data.Select(e => e.X?.ToString()).ToList();
216221

217-
var colors = noAxisSeries.Data.Where(e=> !string.IsNullOrWhiteSpace(e.FillColor)).Select(e => e.FillColor).ToList();
218-
if(colors.Any())
222+
var colors = noAxisSeries.Data.Where(e => !string.IsNullOrWhiteSpace(e.FillColor)).Select(e => e.FillColor).ToList();
223+
if (colors.Any())
219224
{
220225
Options.Colors = colors;
221226
}
@@ -224,14 +229,15 @@ private void UpdateDataForNoAxisCharts()
224229

225230
private bool ShouldFixDataSelection()
226231
{
227-
if (!OnDataPointSelection.HasDelegate || !Options.Series.Any()) { return false; }
232+
if ((!OnDataPointSelection.HasDelegate && !OnDataPointEnter.HasDelegate && ApexPointTooltip == null) || !Options.Series.Any()) { return false; }
228233

229-
if(Options.Chart?.Type != null && Options.Chart.Type == ChartType.Line || Options.Chart.Type == ChartType.Area || Options.Chart.Type == ChartType.Radar)
234+
if (Options.Chart?.Type != null && Options.Chart.Type == ChartType.Line || Options.Chart.Type == ChartType.Area || Options.Chart.Type == ChartType.Radar)
230235
{
231236
return true;
232237
}
233238

234-
if(Options.Series.Any(e=> e.Type == MixedType.Line || e.Type == MixedType.Area)) {
239+
if (Options.Series.Any(e => e.Type == MixedType.Line || e.Type == MixedType.Area))
240+
{
235241
return true;
236242
}
237243

@@ -406,11 +412,31 @@ private void PrepareChart()
406412
UpdateDataForNoAxisCharts();
407413
SetDotNetFormatters();
408414
SetEvents();
415+
SetCustomTooltip();
416+
}
417+
418+
private void SetCustomTooltip()
419+
{
420+
if (ApexPointTooltip == null) { return; }
421+
if (Options.Tooltip == null) { Options.Tooltip = new Tooltip(); }
422+
var customTooltip = @"function({series, seriesIndex, dataPointIndex, w}) {
423+
var sourceId = 'apex-tooltip-' + w.globals.chartID;
424+
var source = document.getElementById(sourceId);
425+
if (source) {
426+
return source.innerHTML;
427+
}
428+
return '...'
429+
}";
430+
431+
Options.Tooltip.Custom = customTooltip;
432+
409433
}
410434

411435
private void SetEvents()
412436
{
413437
Options.HasDataPointSelection = OnDataPointSelection.HasDelegate;
438+
Options.HasDataPointEnter = OnDataPointEnter.HasDelegate || ApexPointTooltip != null;
439+
Options.HasDataPointLeave = OnDataPointLeave.HasDelegate;
414440
Options.HasLegendClick = OnLegendClicked.HasDelegate;
415441

416442
}
@@ -559,13 +585,68 @@ public void DataPointSelected(JSDataPointSelection selectedDataPoints)
559585

560586
var selection = new SelectedData<TItem>
561587
{
588+
Chart = this,
562589
Series = series,
563590
DataPoint = dataPoint,
564591
IsSelected = selectedDataPoints.SelectedDataPoints.Any(e => e != null && e.Any(e => e != null && e.HasValue)),
592+
DataPointIndex = selectedDataPoints.DataPointIndex,
593+
SeriesIndex = selectedDataPoints.SeriesIndex
565594
};
566595

567596
OnDataPointSelection.InvokeAsync(selection);
568597
}
569598
}
599+
600+
[JSInvokable]
601+
public void DataPointEnter(JSDataPointSelection selectedDataPoints)
602+
{
603+
if (OnDataPointEnter.HasDelegate || ApexPointTooltip != null)
604+
{
605+
var series = Options.Series.ElementAt(selectedDataPoints.SeriesIndex);
606+
var dataPoint = series.Data.ElementAt(selectedDataPoints.DataPointIndex);
607+
608+
var hoverData = new HoverData<TItem>
609+
{
610+
Chart = this,
611+
Series = series,
612+
DataPoint = dataPoint,
613+
DataPointIndex = selectedDataPoints.DataPointIndex,
614+
SeriesIndex = selectedDataPoints.SeriesIndex
615+
};
616+
617+
OnDataPointEnter.InvokeAsync(hoverData);
618+
619+
if (ApexPointTooltip != null)
620+
{
621+
tooltipData = hoverData;
622+
StateHasChanged();
623+
}
624+
625+
626+
627+
}
628+
}
629+
630+
[JSInvokable]
631+
public void DataPointLeave(JSDataPointSelection selectedDataPoints)
632+
{
633+
if (OnDataPointLeave.HasDelegate)
634+
{
635+
var series = Options.Series.ElementAt(selectedDataPoints.SeriesIndex);
636+
var dataPoint = series.Data.ElementAt(selectedDataPoints.DataPointIndex);
637+
638+
var hoverData = new HoverData<TItem>
639+
{
640+
Chart = this,
641+
Series = series,
642+
DataPoint = dataPoint,
643+
DataPointIndex = selectedDataPoints.DataPointIndex,
644+
SeriesIndex = selectedDataPoints.SeriesIndex
645+
};
646+
647+
OnDataPointLeave.InvokeAsync(hoverData);
648+
}
649+
}
650+
570651
}
571652
}

src/Blazor-ApexCharts/Models/ApexChartOptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ public class ApexChartOptions<TItem> where TItem : class
88
{
99
public bool Debug { get; set; }
1010
public bool HasDataPointSelection { get; internal set; }
11+
public bool HasDataPointEnter { get; internal set; }
12+
public bool HasDataPointLeave { get; internal set; }
1113
public bool HasLegendClick { get; internal set; }
1214

1315
/// <summary>

0 commit comments

Comments
 (0)