Skip to content

Commit

Permalink
SP5: update Blazor control
Browse files Browse the repository at this point in the history
  • Loading branch information
swharden committed Oct 22, 2023
1 parent 6ad979e commit e6d74fe
Show file tree
Hide file tree
Showing 16 changed files with 349 additions and 91 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

## ScottPlot 5.0.9-beta (in development)
* Signal: Improved support for datasets with repeating values (#2933, #2935) _Thanks @StendProg_
* Blazor: Added a Blazor control (#2959) _Thanks @sulivanganter_

## ScottPlot 4.1.68 (in development)
* Axis: Added `IsReverse` property to let users invert the orientation of an axis (#2958) _Thanks @HandsomeGoldenKnight_
Expand Down
191 changes: 191 additions & 0 deletions src/ScottPlot5/ScottPlot5 Controls/ScottPlot.Blazor/BlazorPlot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using ScottPlot.Control;
using SkiaSharp;

namespace ScottPlot.Blazor
{
public abstract class BlazorPlot : ComponentBase, IPlotControl
{
[Parameter]
public string Style { get; set; } = string.Empty;

public Plot Plot { get; } = new();

public BlazorPlot()
{
HandlerPointerMoved += OnPointerMoved;
HandlerPointerPressed += OnPointerPressed;
HandlerPointerReleased += OnPointerReleased;
HandlerDoubleTapped += OnDoubleTapped;
HandlerPointerWheelChanged += OnPointerWheelChanged;
HandlerKeyDown += OnKeyDown;
HandlerKeyUp += OnKeyUp;

DisplayScale = DetectDisplayScale();
Interaction = new(this);
}

public RenderQueue RenderQueue { get; } = new();

public Interaction Interaction { get; private set; }

public GRContext? GRContext => null;

public float DisplayScale { get; set; }

public float DetectDisplayScale()
{
// TODO: improve support for DPI scale detection
// https://github.com/ScottPlot/ScottPlot/issues/2760
return 1.0f;
}

public Coordinates GetCoordinates(Pixel px, IXAxis? xAxis = null, IYAxis? yAxis = null)
{
return Plot.GetCoordinates(px, xAxis, yAxis);
}

public virtual void Refresh() { }

public void Replace(Interaction interaction)
{
Interaction = interaction;
}

public void ShowContextMenu(Pixel position)
{
//throw new NotImplementedException();
}

public event EventHandler<PointerEventArgs> HandlerPointerMoved;

private void OnPointerMoved(object? sender, PointerEventArgs e)
{
Interaction.OnMouseMove(CoordinateToPixel(e));
}

public void OnPointerMoved(PointerEventArgs e)
{
HandlerPointerMoved.Invoke(this, e);
}

public event EventHandler<PointerEventArgs> HandlerPointerPressed;

private void OnPointerPressed(object? sender, PointerEventArgs e)
{
Interaction.MouseDown(CoordinateToPixel(e), MapToScottMouseButton(e));
}

public void OnPointerPressed(PointerEventArgs e)
{
HandlerPointerPressed.Invoke(this, e);
}

public event EventHandler<PointerEventArgs> HandlerPointerReleased;

private void OnPointerReleased(object? sender, PointerEventArgs e)
{
Interaction.MouseUp(CoordinateToPixel(e), MapToScottMouseButton(e));
}

public void OnPointerReleased(PointerEventArgs e)
{
HandlerPointerReleased.Invoke(this, e);
}

public event EventHandler<MouseEventArgs> HandlerDoubleTapped;

private void OnDoubleTapped(object? sender, MouseEventArgs e)
{
Interaction.DoubleClick();
}
public void OnDoubleTapped(MouseEventArgs e)
{
HandlerDoubleTapped.Invoke(this, e);
}

public event EventHandler<WheelEventArgs> HandlerPointerWheelChanged;

public void OnPointerWheelChanged(object? sender, WheelEventArgs e)
{
Interaction.MouseWheelVertical(CoordinateToPixel(e), -(float)e.DeltaY);
}

public void OnPointerWheelChanged(WheelEventArgs e)
{
HandlerPointerWheelChanged.Invoke(this, e);
}


public event EventHandler<KeyboardEventArgs> HandlerKeyDown;

public void OnKeyDown(object? sender, KeyboardEventArgs e)
{
Interaction.KeyDown(MapToScottKey(e.Key));

}

public void OnKeyDown(KeyboardEventArgs e)
{
HandlerKeyDown.Invoke(this, e);
}

public event EventHandler<KeyboardEventArgs> HandlerKeyUp;

public void OnKeyUp(object? sender, KeyboardEventArgs e)
{
Interaction.KeyUp(MapToScottKey(e.Key));
}

public void OnKeyUp(KeyboardEventArgs e)
{
HandlerKeyUp.Invoke(this, e);
}

public Pixel CoordinateToPixel(WheelEventArgs args)
{
return new Pixel((float)args.OffsetX, (float)args.OffsetY);
}

public Pixel CoordinateToPixel(PointerEventArgs args)
{
return new Pixel((float)args.OffsetX, (float)args.OffsetY);
}

public MouseButton MapToScottMouseButton(MouseEventArgs args)
{
if (args.Button == 0)
{
return MouseButton.Left;
}
else if (args.Button == 1)
{
return MouseButton.Middle;
}
else if (args.Button == 2)
{
return MouseButton.Right;
}
else
{
return MouseButton.Unknown;
}
}

public static Key MapToScottKey(string key)
{
switch (key)
{
case "Control":
return Key.Ctrl;
case "Alt":
return Key.Alt;
case "Shift":
return Key.Shift;
default:
return Key.Unknown;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,31 @@
@inherits BlazorPlot

<div>
<SKGLView @ref="SKGLView" OnPaintSurface="OnPaintSurface" IgnorePixelScaling="true"
<SKGLView @ref="SKView" style=@Style OnPaintSurface="OnPaintSurface" IgnorePixelScaling="true"
@onpointerdown="OnPointerPressed"
@onpointermove="OnPointerMoved"
@onpointerup="OnPointerReleased"
@ondblclick="OnDoubleTapped"
@onwheel="OnPointerWheelChanged"
@onkeydown="OnKeyDown"
@onkeyup="OnKeyUp"
style=@Style />
@onkeyup="OnKeyUp" />
</div>
@code {

private SKGLView SKGLView { get; set; } = new();
@code {

private SKGLView SKView { get; set; } = new();

public void OnPaintSurface(SKPaintGLSurfaceEventArgs e)
{
Plot.Render(e.Surface.Canvas, (int)e.Surface.Canvas.LocalClipBounds.Width, (int)e.Surface.Canvas.LocalClipBounds.Height);
Plot.Render(
canvas: e.Surface.Canvas,
width: (int)e.Surface.Canvas.LocalClipBounds.Width,
height: (int)e.Surface.Canvas.LocalClipBounds.Height);
}


public override void Refresh()
{
SKGLView.Invalidate();
SKView.Invalidate();
RenderQueue.RefreshAll();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,32 @@
@using SkiaSharp;
@inherits BlazorPlot


<div>
<SKCanvasView @ref="SkiaView" OnPaintSurface="OnPaintSurface" IgnorePixelScaling="true"
<SKCanvasView @ref="SKView" style=@Style OnPaintSurface="OnPaintSurface" IgnorePixelScaling="true"
@onpointerdown="OnPointerPressed"
@onpointermove="OnPointerMoved"
@onpointerup="OnPointerReleased"
@ondblclick="OnDoubleTapped"
@onwheel="OnPointerWheelChanged"
@onkeydown="OnKeyDown"
@onkeyup="OnKeyUp"
style=@Style />
@onkeyup="OnKeyUp" />
</div>

@code {
private SKCanvasView SkiaView { get; set; } = new();

private SKCanvasView SKView { get; set; } = new();

public void OnPaintSurface(SKPaintSurfaceEventArgs e)
{
Plot.Render(e.Surface.Canvas, (int)e.Surface.Canvas.LocalClipBounds.Width, (int)e.Surface.Canvas.LocalClipBounds.Height);
Plot.Render(
canvas: e.Surface.Canvas,
width: (int)e.Surface.Canvas.LocalClipBounds.Width,
height: (int)e.Surface.Canvas.LocalClipBounds.Height);
}


public override void Refresh()
{
SkiaView.Invalidate();
SKView.Invalidate();
RenderQueue.RefreshAll();
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Microsoft.JSInterop;
using Microsoft.JSInterop;

namespace ScottPlot.Blazor
{
Expand Down Expand Up @@ -34,4 +34,4 @@ public async ValueTask DisposeAsync()
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dotnet format
pause
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
@page "/bp"
@using ScottPlot;
@using ScottPlot.Blazor;

<p>The <strong>BlazorPlot</strong> manipulates pixel data in memory</p>

<BlazorPlotSkia @ref="BlazorPlot" Style="width: min(100%, 800px); height: 600px;" />

@code {
BlazorPlotSkia BlazorPlot = new();

protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
BlazorPlot.Plot.Add.Signal(ScottPlot.Generate.Sin());
BlazorPlot.Plot.Add.Signal(ScottPlot.Generate.Cos());

var crosshair = BlazorPlot.Plot.Add.Crosshair(0, 0);

BlazorPlot.HandlerPointerMoved += (s, e) =>
{
crosshair.Position = BlazorPlot.GetCoordinates(BlazorPlot.CoordinateToPixel(e));
BlazorPlot.Refresh();
};
}

base.OnAfterRender(firstRender);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
@page "/bpgl"
@using ScottPlot;
@using ScottPlot.Blazor;

<p>The <strong>BlazorPlotGL</strong> uses WebGL for improved performance but may not work in some browsers</p>

<BlazorPlotGL @ref="BlazorPlot" Style="width: min(100%, 800px); height: 600px;" />

@code {
BlazorPlotGL BlazorPlot = new();

protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
BlazorPlot.Plot.Add.Signal(ScottPlot.Generate.Sin());
BlazorPlot.Plot.Add.Signal(ScottPlot.Generate.Cos());

var crosshair = BlazorPlot.Plot.Add.Crosshair(0, 0);

BlazorPlot.HandlerPointerMoved += (s, e) =>
{
crosshair.Position = BlazorPlot.GetCoordinates(BlazorPlot.CoordinateToPixel(e));
BlazorPlot.Refresh();
};
}

base.OnAfterRender(firstRender);
}
}

Loading

0 comments on commit e6d74fe

Please sign in to comment.