Board with hundreds of boxes and relations. Drag, resize and scroll: everything happens in the browser and .NET is only called on release.
@using Astrol.Component.Board@using Astrol.Component.Basic.Form@using Astrol.Entities.Basic.UI.Board @* Large board: dragging, resizing and moving vertices run in the browser (no calls to .NET while you drag), so it stays smooth with hundreds of boxes. Only the boxes that change are rendered again. *@<div style="margin-bottom:5px"> <AstrolRadioGroup Value="boxCount" ValueChanged="(int count) => Load(count)" Horizontal="true" AriaLabel="Boxes"> @foreach (var count in new[] { 100, 500, 1000 }) { <AstrolRadio Value="count" Text="@($"{count} boxes")" /> } </AstrolRadioGroup></div><div style="height:420px"> <AstrolBoard TBox="string" TRelation="object" Board="board" BackgroundType="BackgroundType.Points" MinWidth="40" MinHeight="30"> <BoxRender> <div style="height:100%; display:flex; align-items:center; justify-content:center; font-size:.8em; border-radius:6px; border:1px solid var(--color-gray-a); background:var(--layout-menu-bg)"> @context.BOX_NAME </div> </BoxRender> </AstrolBoard></div> @code { private int boxCount = 500; private Board<string, object> board = Create(500); // A new Board object: the component starts again (selection and history). private void Load(int count) { boxCount = count; board = Create(count); } private static Board<string, object> Create(int count) { var b = new Board<string, object>(); for (int i = 0; i < count; i++) { b.Boxes.Add(new Box<string> { X = 20 + (i % 25) * 120, Y = 20 + (i / 25) * 100, Width = 90, Height = 60, BOX_NAME = $"#{i + 1}", Content = "" }); } for (int i = 1; i < count; i++) { b.Relations.Add(new Relation<object> { BoxIdA = b.Boxes[i - 1].Id, BoxIdB = b.Boxes[i].Id }); } return b; }}