Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features/relayout event #284

Merged
merged 2 commits into from
Feb 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions Plotly.Blazor.Examples/Components/Relayout.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
@using Plotly.Blazor.LayoutLib
@using Plotly.Blazor.Traces.ScatterLib
@using Plotly.Blazor.Interop
@using System.Text.Json


<PlotlyChart style="height: 60vh; min-height: 350px"
@bind-Config="config" @bind-Layout="layout" @bind-Data="data" @ref="chart"
RelayoutAction="RelayoutAction" AfterRender="async () => await SubscribeEvents()" />

@if(relayoutData?.XRange?.Count() == 2)
{
<MudText>X: @relayoutData.XRange[0], @relayoutData.XRange[1]</MudText>
}

@if (relayoutData?.YRange?.Count() == 2)
{
<MudText>Y: @relayoutData.YRange[0], @relayoutData.YRange[1]</MudText>
}

@code {
RelayoutEventData relayoutData;

PlotlyChart chart;
private Config config = new()
{
Responsive = true
};

private IList<ITrace> data = new List<ITrace>
{
new Scatter
{
Name = "ScatterTrace",
Mode = ModeFlag.Lines | ModeFlag.Markers,
X = new List<object>(),
Y = new List<object>()
}
};
private Layout layout = new()
{
Title = new Title { Text = "Scatter with Relayout Event" },
YAxis = new List<YAxis>
{
new()
{
Title = new LayoutLib.YAxisLib.Title { Text = "Scatter Unit" }
}
}
};

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await ExtendData();
}
}

private async Task ExtendData(int count = 100)
{
if (!(chart.Data.FirstOrDefault() is Scatter scatter))
{
return;
}

var max = (int?)scatter.X?.Max();
var (x, y) = Helper.GenerateData(max + 1 ?? 0, max + 1 + count ?? count);
if (!scatter.X.Any() || !scatter.Y.Any())
{
scatter.X.AddRange(x);
scatter.Y.AddRange(y);
await chart.React();
}
else
{
await chart.ExtendTrace(x, y, data.IndexOf(scatter));
}
}

public void RelayoutAction(RelayoutEventData data)
{
relayoutData = data;
StateHasChanged();
}

public async Task SubscribeEvents()
{
await chart.SubscribeRelayoutEvent();
}
}
5 changes: 5 additions & 0 deletions Plotly.Blazor.Examples/Pages/RelayoutPage.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@page "/relayout"

<Example Title="Scatter Chart with Relayout-Event" Url="Plotly.Blazor.Examples/Components/Relayout.razor">
<Relayout />
</Example>
1 change: 1 addition & 0 deletions Plotly.Blazor.Examples/Shared/NavMenu.razor
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@
<MudNavLink Match="NavLinkMatch.All" Href="/indicator">Indicator</MudNavLink>
<MudNavLink Match="NavLinkMatch.All" Href="/smith">Smith</MudNavLink>
<MudNavLink Match="NavLinkMatch.All" Href="/hover">HoverEvent</MudNavLink>
<MudNavLink Match="NavLinkMatch.All" Href="/relayout">RelayoutEvent</MudNavLink>
</MudNavMenu>
</MudDrawer>
33 changes: 33 additions & 0 deletions Plotly.Blazor/Interop/RelayoutEventData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Plotly.Blazor.LayoutLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Plotly.Blazor.Interop
{

/// <summary>
/// This class is used to parse the event data from the relayout jsinterop action.
/// </summary>
public class RelayoutEventData
{
/// <summary>
/// The x-axis of the layout. [x0, x1]
/// </summary>
/// <remarks>
/// In some cases this may be not be set.
/// </remarks>
public double[] XRange { get; set; }


/// <summary>
/// The y-axis of the layout. [y0, y1].
/// </summary>
/// <remarks>
/// In some cases this may be not be set.
/// </remarks>
public double[] YRange { get; set; }
}
}
42 changes: 42 additions & 0 deletions Plotly.Blazor/Plotly.Blazor.xml
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,27 @@
Has to be casted manually.
</summary>
</member>
<member name="T:Plotly.Blazor.Interop.RelayoutEventData">
<summary>
This class is used to parse the event data from the relayout jsinterop action.
</summary>
</member>
<member name="P:Plotly.Blazor.Interop.RelayoutEventData.XRange">
<summary>
The x-axis of the layout. [x0, x1]
</summary>
<remarks>
In some cases this may be not be set.
</remarks>
</member>
<member name="P:Plotly.Blazor.Interop.RelayoutEventData.YRange">
<summary>
The y-axis of the layout. [y0, y1].
</summary>
<remarks>
In some cases this may be not be set.
</remarks>
</member>
<member name="T:Plotly.Blazor.ITrace">
<summary>
The trace interface.
Expand Down Expand Up @@ -18666,6 +18687,14 @@
<param name="objectReference">The object reference.</param>
<param name="cancellationToken">CancellationToken</param>
</member>
<member name="M:Plotly.Blazor.PlotlyJsInterop.SubscribeRelayoutEvent(Microsoft.JSInterop.IJSRuntime,Microsoft.JSInterop.DotNetObjectReference{Plotly.Blazor.PlotlyChart},System.Threading.CancellationToken)">
<summary>
Can be used to subscribe to relayout events.
</summary>
<param name="jsRuntime"></param>
<param name="objectReference"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:Plotly.Blazor.PlotlyJsInterop.ToImage(Microsoft.JSInterop.IJSRuntime,Microsoft.JSInterop.DotNetObjectReference{Plotly.Blazor.PlotlyChart},Plotly.Blazor.ImageFormat,System.UInt32,System.UInt32,System.Threading.CancellationToken)">
<summary>
Can be used to export the chart as a static image and returns a binary string of the exported image.
Expand Down Expand Up @@ -116361,6 +116390,11 @@
Objects are currently required for accomodating different plot value types
</summary>
</member>
<member name="P:Plotly.Blazor.PlotlyChart.RelayoutAction">
<summary>
Defines the action that should happen when the RelayoutEvent is triggered.
</summary>
</member>
<member name="M:Plotly.Blazor.PlotlyChart.ClickEvent(System.Object,System.Object)">
<summary>
Method which is called by JSRuntime once a plot has been clicked, to invoke the passed in ClickAction.
Expand All @@ -116376,6 +116410,7 @@
</summary>
<param name="eventData"></param>
</member>
<!-- Badly formed XML comment ignored for member "M:Plotly.Blazor.PlotlyChart.RelayoutEvent(Plotly.Blazor.Interop.RelayoutEventData)" -->
<member name="M:Plotly.Blazor.PlotlyChart.SubscribeClickEvent(System.Threading.CancellationToken)">
<summary>
Subscribes to the click event of the chart.
Expand All @@ -116390,6 +116425,13 @@
<param name="cancellationToken">CancellationToken</param>
<returns>Task</returns>
</member>
<member name="M:Plotly.Blazor.PlotlyChart.SubscribeRelayoutEvent(System.Threading.CancellationToken)">
<summary>
Subscribes to the relayout event of the chart.
</summary>
<param name="cancellationToken">CancellationToken</param>
<returns>Task</returns>
</member>
<member name="M:Plotly.Blazor.PlotlyChart.Clear(System.Threading.CancellationToken)">
<summary>
Clears the traces from the current chart.
Expand Down
26 changes: 26 additions & 0 deletions Plotly.Blazor/PlotlyChart.razor
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,13 @@
[Parameter]
public Action<IEnumerable<HoverEventDataPoint>> HoverAction { get; set; }


/// <summary>
/// Defines the action that should happen when the RelayoutEvent is triggered.
/// </summary>
[Parameter]
public Action<RelayoutEventData> RelayoutAction { get; set; }

/// <summary>
/// Method which is called by JSRuntime once a plot has been clicked, to invoke the passed in ClickAction.
/// Objects are currently required for accomodating different plot value types.
Expand All @@ -649,6 +656,15 @@
HoverAction?.Invoke(eventData);
}

//// <summary>
/// Method which is called by JSRuntime when the chart's layout has changed.
/// </summary>
[JSInvokable("RelayoutEvent")]
public void RelayoutEvent(RelayoutEventData obj)
{
RelayoutAction?.Invoke(obj);
}

/// <summary>
/// Subscribes to the click event of the chart.
/// </summary>
Expand All @@ -669,6 +685,16 @@
await JsRuntime.SubscribeHoverEvent(objectReference, cancellationToken);
}

/// <summary>
/// Subscribes to the relayout event of the chart.
/// </summary>
/// <param name="cancellationToken">CancellationToken</param>
/// <returns>Task</returns>
public async Task SubscribeRelayoutEvent(CancellationToken cancellationToken = default)
{
await JsRuntime.SubscribeRelayoutEvent(objectReference, cancellationToken);
}

/// <summary>
/// Clears the traces from the current chart.
/// </summary>
Expand Down
11 changes: 11 additions & 0 deletions Plotly.Blazor/PlotlyJsInterop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,17 @@ public static async Task SubscribeHoverEvent(this IJSRuntime jsRuntime, DotNetOb
{
await jsRuntime.InvokeVoidAsync($"{PlotlyInterop}.subscribeHoverEvent", cancellationToken, objectReference, objectReference.Value.Id);
}

/// <summary>
/// Can be used to subscribe to relayout events.
/// </summary>
/// <param name="jsRuntime"></param>
/// <param name="objectReference"></param>
/// <param name="cancellationToken"></param>
public static async Task SubscribeRelayoutEvent(this IJSRuntime jsRuntime, DotNetObjectReference<PlotlyChart> objectReference, CancellationToken cancellationToken)
{
await jsRuntime.InvokeVoidAsync($"{PlotlyInterop}.subscribeRelayoutEvent", cancellationToken, objectReference, objectReference.Value.Id);
}

/// <summary>
/// Can be used to export the chart as a static image and returns a binary string of the exported image.
Expand Down
24 changes: 24 additions & 0 deletions Plotly.Blazor/wwwroot/plotly-interop.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,29 @@
}
}));
})
},
subscribeRelayoutEvent: function (dotNetObj, id) {
var plot = document.getElementById(id);
plot.on('plotly_relayout', function (data) {

var x1 = data["xaxis.range[0]"];
var x2 = data["xaxis.range[1]"];

var y1 = data["yaxis.range[0]"]
var y2 = data["yaxis.range[1]"]

var result = {};

if (x1 && x2)
{
result.XRange = [x1, x2];
}

if (y1 && y2)
{
result.YRange = [y1, y2];
}
dotNetObj.invokeMethodAsync('RelayoutEvent', result);
});
}
}