diff --git a/Canvas.Core/Canvas.Core.csproj b/Canvas.Core/Canvas.Core.csproj index 164da65..2ecba70 100644 --- a/Canvas.Core/Canvas.Core.csproj +++ b/Canvas.Core/Canvas.Core.csproj @@ -5,7 +5,7 @@ disable disable True - 3.3.0 + 4.0.0 Internal package used in Canvas.Views.Web artemiusgreat indemos.com diff --git a/Canvas.Core/Composers/Composer.cs b/Canvas.Core/Composers/Composer.cs index 717a117..8749275 100644 --- a/Canvas.Core/Composers/Composer.cs +++ b/Canvas.Core/Composers/Composer.cs @@ -40,7 +40,7 @@ public interface IComposer /// /// Domain /// - DomainModel Domain { get; set; } + DimensionModel Dimension { get; set; } /// /// Engine @@ -80,7 +80,7 @@ public interface IComposer /// /// Domain update event /// - Action OnRender { get; set; } + Action OnAction { get; set; } /// /// Mouse wheel event @@ -114,25 +114,17 @@ public interface IComposer void OnMouseLeave(ViewModel e); /// - /// Create - /// - /// - /// - Task Create() where T : IEngine, new(); - - /// - /// Update + /// Update items /// /// - /// - Task Update(DomainModel? message = null, string source = null); + /// + void Render(DimensionModel message); /// - /// Update items + /// Update dimensions /// - /// - /// - void Render(DomainModel message); + /// + void SetDimensions(DimensionModel domain); /// /// Convert values to canvas coordinates @@ -206,7 +198,7 @@ public partial class Composer : IComposer /// /// Domain /// - public virtual DomainModel Domain { get; set; } + public virtual DimensionModel Dimension { get; set; } /// /// Engine @@ -246,7 +238,7 @@ public partial class Composer : IComposer /// /// Domain update event /// - public virtual Action OnRender { get; set; } + public virtual Action OnAction { get; set; } /// /// Constructor @@ -258,7 +250,7 @@ public Composer() ValueCount = 3; IndexCount = 9; - Domain = new DomainModel(); + Dimension = new DimensionModel(); Components = new Dictionary(); Items = []; @@ -266,7 +258,7 @@ public Composer() ShowIndex = o => $"{o:0.00}"; ShowValue = o => $"{o:0.00}"; - OnRender = (message, source) => { }; + OnAction = o => { }; Components[nameof(ComponentEnum.Shape)] = new ComponentModel { @@ -307,32 +299,12 @@ public Composer() }; } - /// - /// Create - /// - /// - /// - /// - public virtual Task Create() where T : IEngine, new() => View.Create(() => this); - - /// - /// Update - /// - /// - /// - /// - public virtual Task Update(DomainModel? domain = null, string source = null) - { - OnRender(Domain = ComposeDomain(domain ?? Domain), source); - return View.Update(Domain); - } - /// /// Update items /// /// /// - public virtual void Render(DomainModel domain) + public virtual void Render(DimensionModel domain) { Engine.Clear(); @@ -359,11 +331,11 @@ public virtual void Render(DomainModel domain) /// public virtual DataModel GetItemPosition(DataModel item) { - var valueRange = Domain.MaxValue - Domain.MinValue; - var minX = Domain.MinIndex; - var maxX = Domain.MaxIndex; - var minY = Domain.MinValue - valueRange * Space; - var maxY = Domain.MaxValue + valueRange * Space; + var valueRange = Dimension.MaxValue - Dimension.MinValue; + var minX = Dimension.MinIndex; + var maxX = Dimension.MaxIndex; + var minY = Dimension.MinValue - valueRange * Space; + var maxY = Dimension.MaxValue + valueRange * Space; // Convert to device pixels @@ -395,11 +367,11 @@ public virtual DataModel GetItemPosition(double index, double value) /// public virtual DataModel GetItemValue(DataModel item) { - var valueRange = Domain.MaxValue - Domain.MinValue; - var minX = Domain.MinIndex; - var maxX = Domain.MaxIndex; - var minY = Domain.MinValue - valueRange * Space; - var maxY = Domain.MaxValue + valueRange * Space; + var valueRange = Dimension.MaxValue - Dimension.MinValue; + var minX = Dimension.MinIndex; + var maxX = Dimension.MaxIndex; + var minY = Dimension.MinValue - valueRange * Space; + var maxY = Dimension.MaxValue + valueRange * Space; // Convert to values @@ -420,8 +392,8 @@ public virtual DataModel GetItemValue(DataModel item) /// public virtual IList ZoomValue(int delta) { - var minY = Domain.MinValue; - var maxY = Domain.MaxValue; + var minY = Dimension.MinValue; + var maxY = Dimension.MaxValue; var domain = new List { minY, maxY }; if (Equals(maxY, minY)) @@ -454,8 +426,8 @@ public virtual IList ZoomValue(int delta) /// public virtual IList ZoomIndex(int delta) { - var minX = Domain.MinIndex; - var maxX = Domain.MaxIndex; + var minX = Dimension.MinIndex; + var maxX = Dimension.MaxIndex; var domain = new[] { minX, maxX }; if (Equals(minX, maxX)) @@ -482,8 +454,8 @@ public virtual IList ZoomIndex(int delta) /// public virtual IList PanIndex(int delta) { - var minX = Domain.MinIndex; - var maxX = Domain.MaxIndex; + var minX = Dimension.MinIndex; + var maxX = Dimension.MaxIndex; var domain = new List { minX, maxX }; if (Equals(minX, maxX)) @@ -516,7 +488,7 @@ public virtual IList PanIndex(int delta) public virtual void OnWheel(ViewModel e) { var isZoom = e.IsShape; - var domain = Domain; + var domain = Dimension; switch (true) { @@ -524,7 +496,7 @@ public virtual void OnWheel(ViewModel e) case true when e.Data.Y < 0: domain.IndexDomain = isZoom ? ZoomIndex(1) : PanIndex(-1); break; } - Update(domain, Name); + View.Update(domain, Name); } /// @@ -539,7 +511,7 @@ public virtual void OnMouseMove(ViewModel e) { var deltaX = MoveEvent?.Data.X - e.Data.X; var deltaY = MoveEvent?.Data.Y - e.Data.Y; - var domain = Domain; + var domain = Dimension; switch (true) { @@ -547,7 +519,7 @@ public virtual void OnMouseMove(ViewModel e) case true when deltaX < 0: domain.IndexDomain = PanIndex(-1); break; } - Update(domain, Name); + View.Update(domain, Name); } MoveEvent = e; @@ -566,8 +538,7 @@ public virtual void OnScale(ViewModel e, int orientation = 0) { var deltaX = ScaleEvent?.Data.X - e.Data.X; var deltaY = ScaleEvent?.Data.Y - e.Data.Y; - var domain = Domain; - var source = Name; + var domain = Dimension; switch (orientation > 0) { @@ -577,11 +548,11 @@ public virtual void OnScale(ViewModel e, int orientation = 0) switch (orientation < 0) { - case true when deltaY > 0: domain.ValueDomain = ZoomValue(-1); source = null; break; - case true when deltaY < 0: domain.ValueDomain = ZoomValue(1); source = null; break; + case true when deltaY > 0: domain.ValueDomain = ZoomValue(-1); break; + case true when deltaY < 0: domain.ValueDomain = ZoomValue(1); break; } - Update(domain, source); + View.Update(domain, Name); } ScaleEvent = e; @@ -595,11 +566,11 @@ public virtual void OnMouseDown(ViewModel e) { if (e.IsControl) { - var domain = Domain; + var domain = Dimension; domain.ValueDomain = null; - Update(domain); + View.Update(domain); } } @@ -617,8 +588,8 @@ public virtual void OnMouseLeave(ViewModel e) /// protected virtual IList GetIndices() { - var minIndex = Domain.MinIndex; - var maxIndex = Domain.MaxIndex; + var minIndex = Dimension.MinIndex; + var maxIndex = Dimension.MaxIndex; var range = 0.0 + maxIndex - minIndex; var center = Math.Round(minIndex + range / 2.0, MidpointRounding.ToEven); var step = Math.Round(range / IndexCount, MidpointRounding.ToZero); @@ -653,8 +624,8 @@ void createItem(double i) /// protected virtual IList GetValues() { - var minValue = Domain.MinValue; - var maxValue = Domain.MaxValue; + var minValue = Dimension.MinValue; + var maxValue = Dimension.MaxValue; var range = maxValue - minValue; var center = minValue + range / 2.0; var step = range / ValueCount; @@ -689,7 +660,7 @@ void createItem(double i) /// /// /// - protected virtual DomainModel ComposeDomain(DomainModel domain) + public virtual void SetDimensions(DimensionModel domain) { var autoMin = 0; var autoMax = Items.Count; @@ -709,15 +680,16 @@ protected virtual DomainModel ComposeDomain(DomainModel domain) if (min > max) { - return response; + Dimension = response; + return; } if (Equals(min, max)) { response.AutoValueDomain[0] = Math.Min(0, min); response.AutoValueDomain[1] = Math.Max(0, max); - - return response; + Dimension = response; + return; } if (min < 0 && max > 0) @@ -726,14 +698,13 @@ protected virtual DomainModel ComposeDomain(DomainModel domain) response.AutoValueDomain[0] = -extreme; response.AutoValueDomain[1] = extreme; - - return response; + Dimension = response; + return; } response.AutoValueDomain[0] = min; response.AutoValueDomain[1] = max; - - return response; + Dimension = response; } /// diff --git a/Canvas.Core/Composers/GroupComposer.cs b/Canvas.Core/Composers/GroupComposer.cs index c216c34..413fe61 100644 --- a/Canvas.Core/Composers/GroupComposer.cs +++ b/Canvas.Core/Composers/GroupComposer.cs @@ -13,7 +13,7 @@ public class GroupComposer : Composer /// /// /// - public override void Render(DomainModel domain) + public override void Render(DimensionModel domain) { Engine.Clear(); diff --git a/Canvas.Core/Composers/MapComposer.cs b/Canvas.Core/Composers/MapComposer.cs index df6f375..4aa460f 100644 --- a/Canvas.Core/Composers/MapComposer.cs +++ b/Canvas.Core/Composers/MapComposer.cs @@ -1,4 +1,3 @@ -using Canvas.Core.Engines; using Canvas.Core.Models; using System; using System.Collections.Generic; @@ -10,15 +9,15 @@ public class MapComposer : Composer /// /// Max number of points on Y axis /// - public int Dimension { get; set; } + public int Range { get; set; } /// /// Enumerate indices /// protected override IList GetIndices() { - var minIndex = Domain.MinIndex; - var maxIndex = Domain.MaxIndex; + var minIndex = Dimension.MinIndex; + var maxIndex = Dimension.MaxIndex; var range = 0.0 + maxIndex - minIndex; var count = Math.Min(IndexCount, range); var step = Math.Round(range / count, MidpointRounding.ToEven); @@ -53,8 +52,8 @@ void createItem(double i) /// protected override IList GetValues() { - var minValue = Domain.MinValue; - var maxValue = Domain.MaxValue; + var minValue = Dimension.MinValue; + var maxValue = Dimension.MaxValue; var range = 0.0 + maxValue - minValue; var count = Math.Min(ValueCount, range); var step = Math.Round(range / count, MidpointRounding.ToEven); @@ -88,18 +87,18 @@ void createItem(double i) /// Value scale /// /// - public override IList ZoomValue(int delta) => Domain.ValueDomain; + public override IList ZoomValue(int delta) => Dimension.ValueDomain; /// /// Index scale /// /// - public override IList ZoomIndex(int delta) => Domain.IndexDomain; + public override IList ZoomIndex(int delta) => Dimension.IndexDomain; /// /// Index scale /// /// - public override IList PanIndex(int delta) => Domain.IndexDomain; + public override IList PanIndex(int delta) => Dimension.IndexDomain; } } diff --git a/Canvas.Core/Models/DomainModel.cs b/Canvas.Core/Models/DimensionModel.cs similarity index 94% rename from Canvas.Core/Models/DomainModel.cs rename to Canvas.Core/Models/DimensionModel.cs index 4a01472..1168aeb 100644 --- a/Canvas.Core/Models/DomainModel.cs +++ b/Canvas.Core/Models/DimensionModel.cs @@ -3,7 +3,7 @@ namespace Canvas.Core.Models { - public struct DomainModel + public struct DimensionModel { /// /// Index axis diff --git a/Canvas.Core/Shapes/ColorMapShape.cs b/Canvas.Core/Shapes/ColorMapShape.cs index 9a3e35d..1a0d6a3 100644 --- a/Canvas.Core/Shapes/ColorMapShape.cs +++ b/Canvas.Core/Shapes/ColorMapShape.cs @@ -50,8 +50,8 @@ public override IList GetSeriesValues(DataModel view, DataModel coordina /// public override void CreateShape(int index, string name, IList items) { - var dimension = (Composer as MapComposer).Dimension; - var range = Composer.Domain.MaxValue - Composer.Domain.MinValue; + var dimension = (Composer as MapComposer).Range; + var range = Composer.Dimension.MaxValue - Composer.Dimension.MinValue; var previous = Points.FirstOrDefault(); var step = range / dimension; diff --git a/Canvas.Core/View.cs b/Canvas.Core/View.cs index c3ff256..7ca947a 100644 --- a/Canvas.Core/View.cs +++ b/Canvas.Core/View.cs @@ -42,7 +42,7 @@ public interface IView : IDisposable /// /// /// - Task Update(DomainModel message); + Task Update(DimensionModel? domain = null, string source = null); /// /// Create diff --git a/Canvas.Views.Web/Canvas.Views.Web.csproj b/Canvas.Views.Web/Canvas.Views.Web.csproj index 5551313..8facbe4 100644 --- a/Canvas.Views.Web/Canvas.Views.Web.csproj +++ b/Canvas.Views.Web/Canvas.Views.Web.csproj @@ -10,7 +10,7 @@ true True - 3.3.0 + 4.0.0 finance chart opengl canvas trading gdi stock direct2d artemiusgreat indemos.com diff --git a/Canvas.Views.Web/Views/BaseView.cs b/Canvas.Views.Web/Views/BaseView.cs index 0e8f5d4..1b6b4a9 100644 --- a/Canvas.Views.Web/Views/BaseView.cs +++ b/Canvas.Views.Web/Views/BaseView.cs @@ -43,9 +43,10 @@ public class BaseView : ComponentBase, IView /// /// Update /// - /// + /// + /// /// - public virtual async Task Update(DomainModel message) + public virtual async Task Update(DimensionModel? domain = null, string source = null) { await Schedule(() => { @@ -54,9 +55,14 @@ await Schedule(() => return; } - Composer.Engine.Clear(); - Composer.Render(Composer.Domain); + Composer.SetDimensions(domain ?? Composer.Dimension); + Composer.Render(domain ?? Composer.Dimension); Route = "data:image/webp;base64," + Convert.ToBase64String(Composer.Engine.Encode(SKEncodedImageFormat.Webp, 100)); + + if (source is not null) + { + Composer.OnAction(domain ?? Composer.Dimension); + } }); await InvokeAsync(StateHasChanged); diff --git a/Canvas.Views.Web/Views/CanvasGroupView.razor.cs b/Canvas.Views.Web/Views/CanvasGroupView.razor.cs index d07ffd1..c67b51b 100644 --- a/Canvas.Views.Web/Views/CanvasGroupView.razor.cs +++ b/Canvas.Views.Web/Views/CanvasGroupView.razor.cs @@ -53,12 +53,12 @@ await view.Value.Create(() => return composer; }); - composer.OnRender += (domain, source) => Views.ForEach(o => + composer.OnAction += domain => Views.Values.ForEach(async o => { - if (source is not null && Equals(composer.Name, o.Value.Composer.Name) is false) + if (Equals(composer.Name, o?.Composer?.Name) is false) { - domain.ValueDomain = o.Value.Composer.Domain.ValueDomain; - o.Value.Composer.Update(domain); + domain.ValueDomain = o.Composer.Dimension.ValueDomain; + await o.Update(domain); } }); } @@ -71,19 +71,19 @@ await view.Value.Create(() => /// /// Update /// - /// + /// /// /// - public virtual Task Update(DomainModel message, IList items = null) + public virtual Task Update(DimensionModel? dimension, IList items = null) { - var processes = Views.Select(o => + var processes = Views.Values.Select(o => { if (items is not null) { - o.Value.Composer.Items = items; + o.Composer.Items = items; } - return o.Value.Composer.Update(message); + return o.Update(dimension); }); return Task.WhenAll(processes); diff --git a/Canvas.Views.Web/Views/CanvasView.razor.cs b/Canvas.Views.Web/Views/CanvasView.razor.cs index 6757f61..5eca685 100644 --- a/Canvas.Views.Web/Views/CanvasView.razor.cs +++ b/Canvas.Views.Web/Views/CanvasView.razor.cs @@ -134,7 +134,7 @@ Task Setup() => Schedule(async () => Composer = action(); Composer.Engine = engine.Create(bounds.Data.X, bounds.Data.Y); - await Update(Composer.Domain); + await Update(); }); return this; diff --git a/Samples/Pages/Charts.razor.cs b/Samples/Pages/Charts.razor.cs index 135d5ed..c6876d2 100644 --- a/Samples/Pages/Charts.razor.cs +++ b/Samples/Pages/Charts.razor.cs @@ -19,7 +19,7 @@ public partial class Charts protected DateTime Time { get; set; } = DateTime.Now; protected DateTime TimeGroup { get; set; } = DateTime.Now; protected List Points { get; set; } = new(); - protected Dictionary Indices { get; set; } = new(); + protected Dictionary Indices { get; set; } = []; protected override async Task OnAfterRenderAsync(bool setup) { @@ -118,7 +118,7 @@ protected void OnData() } .Update(group.Groups["Assets"].Groups["Prices"]); - var domain = new DomainModel { IndexDomain = new int[] { Points.Count - 100, Points.Count } }; + var domain = new DimensionModel { IndexDomain = [Points.Count - 100, Points.Count] }; View.Update(domain, Points); } diff --git a/Samples/Pages/Group.razor b/Samples/Pages/Group.razor index eaf2da5..9fe93dd 100644 --- a/Samples/Pages/Group.razor +++ b/Samples/Pages/Group.razor @@ -50,8 +50,8 @@ View = View }; - await composer.Create(); - await composer.Update(); + await View.Create(() => composer); + await View.Update(); } await base.OnAfterRenderAsync(setup); diff --git a/Samples/Pages/Heatmap.razor b/Samples/Pages/Heatmap.razor index bfc7a59..cc45df5 100644 --- a/Samples/Pages/Heatmap.razor +++ b/Samples/Pages/Heatmap.razor @@ -48,7 +48,7 @@ var composer = new MapComposer { Name = "Correlation", - Dimension = points.Max(shape => (shape as ColorMapShape).Points.Count), + Range = points.Max(shape => (shape as ColorMapShape).Points.Count), Items = points, View = View, IndexCount = labels.Length, @@ -57,8 +57,8 @@ ShowValue = i => labels.ElementAtOrDefault((int)i) }; - await composer.Create(); - await composer.Update(); + await View.Create(() => composer); + await View.Update(); } await base.OnAfterRenderAsync(setup); diff --git a/Samples/Pages/Prints.razor b/Samples/Pages/Prints.razor index 4f7467d..165899a 100644 --- a/Samples/Pages/Prints.razor +++ b/Samples/Pages/Prints.razor @@ -60,8 +60,8 @@ View = View }; - await composer.Create(); - await composer.Update(); + await View.Create(() => composer); + await View.Update(); } await base.OnAfterRenderAsync(setup); diff --git a/Samples/Pages/Single.razor b/Samples/Pages/Single.razor index 8c6e8a9..693b292 100644 --- a/Samples/Pages/Single.razor +++ b/Samples/Pages/Single.razor @@ -32,8 +32,8 @@ View = View }; - await composer.Create(); - await composer.Update(); + await View.Create(() => composer); + await View.Update(); } await base.OnAfterRenderAsync(setup);