Vier nieuwe sgcHTML-componenten voor gestructureerde data: TreeGrid, PivotTable, ActivityFeed en Splitter | eSeGeCe Blog

Vier nieuwe sgcHTML-componenten voor gestructureerde data: TreeGrid, PivotTable, ActivityFeed en Splitter

· Componenten

sgcHTML is zojuist uitgebreid met 25 componenten, en dit is de eerste van vijf posts die ze per thema doorlopen. We beginnen met vier componenten rond gestructureerde, veranderlijke data: TreeGrid voor hiërarchische rijen, PivotTable voor gegroepeerde aggregaten, ActivityFeed voor een live stroom van gebeurtenissen, en Splitter voor de aanpasbare tweedelige lay-out die dat allemaal maar al te vaak moet bevatten. Elke component hieronder is een gewone Delphi/C++Builder/.NET-klasse: stel de eigenschappen in, roep HTML aan, en krijg Bootstrap 5-markup terug. Geen JavaScript-framework, geen build-stap.

TreeGrid — inklapbare hiërarchische tabellen

TsgcHTMLComponent_TreeGrid rendert een Bootstrap-tabel waarvan de rijen in- en uitklappen, opgebouwd uit eenvoudige Id / ParentId node-paren — dezelfde vorm die u al gebruikt voor organigrammen, categorieboomstructuren of geneste materiaallijstdata. Declareer een TsgcHTMLTreeGridColumn per zichtbaar veld en voeg vervolgens nodes toe; de parent/child-relatie tekent de boomstructuur en de toggle-pijltjes voor u.

uses
  sgcHTML_Component_TreeGrid;

var
  oTreeGrid: TsgcHTMLComponent_TreeGrid;
  oColumn: TsgcHTMLTreeGridColumn;
begin
  oTreeGrid := TsgcHTMLComponent_TreeGrid.Create(nil);
  try
    oTreeGrid.TreeGridID := 'orgchart';
    oTreeGrid.Sortable := True;

    oColumn := oTreeGrid.Columns.Add;
    oColumn.Caption := 'Department';
    oColumn.FieldName := 'Name';

    oColumn := oTreeGrid.Columns.Add;
    oColumn.Caption := 'Headcount';
    oColumn.FieldName := 'Headcount';
    oColumn.Align := tgaRight;

    oTreeGrid.AddNode('eng', '', ['Engineering', '42']);
    oTreeGrid.AddNode('eng-be', 'eng', ['Backend', '18']);
    oTreeGrid.AddNode('eng-fe', 'eng', ['Frontend', '15']);

    WebModule.Response := oTreeGrid.HTML;   // hierarchical table + scoped CSS + toggle script
  finally
    oTreeGrid.Free;
  end;
end;

// Or bind it straight to a self-referencing dataset (Id / ParentId columns):
oTreeGrid.LoadFromDataSet(qryDepartments, 'Id', 'ParentId');

Als uw data al in een zelfverwijzende tabel staat, kunt u de handmatige node-aanroepen helemaal overslaan en LoadFromDataSet de namen van het parent- en child-veld meegeven — de methode doorloopt de dataset en bouwt de hele boomstructuur in één keer op.

PivotTable — groeperen, aggregeren, totaliseren

TsgcHTMLComponent_PivotTable neemt platte rijen en produceert een gegroepeerde, geaggregeerde tabel met rijtotalen, kolomtotalen en een eindtotaal, het rapport dat u anders met de hand in een spreadsheet zou opbouwen. U declareert RowFields en ColumnFields om op te groeperen, één of meer Measures om te aggregeren (som, gemiddelde, aantal, min, max), en een DataFields-lijst die aangeeft welke bronkolommen daadwerkelijk gelezen moeten worden.

uses
  sgcHTML_Component_PivotTable;

var
  oPivot: TsgcHTMLComponent_PivotTable;
  oMeasure: TsgcHTMLPivotMeasure;
begin
  oPivot := TsgcHTMLComponent_PivotTable.Create(nil);
  try
    oPivot.Caption := 'Revenue by Region and Quarter';

    oPivot.RowFields.Add.FieldName := 'Region';
    oPivot.ColumnFields.Add.FieldName := 'Quarter';

    oMeasure := oPivot.Measures.Add;
    oMeasure.SourceField := 'Amount';
    oMeasure.Caption := 'Revenue';
    oMeasure.Aggregation := paSum;
    oMeasure.Format := '#,##0.00';

    oPivot.DataFields.Add('Region');
    oPivot.DataFields.Add('Quarter');
    oPivot.DataFields.Add('Amount');

    oPivot.AddRow(['EMEA', 'Q1', '12000']);
    oPivot.AddRow(['EMEA', 'Q2', '15500']);
    oPivot.AddRow(['APAC', 'Q1', '9800']);

    WebModule.Response := oPivot.HTML;   // aggregated table + row/column/grand totals
  finally
    oPivot.Free;
  end;
end;

// Or bind it straight to a dataset (reads only RowFields/ColumnFields/Measures fields):
oPivot.LoadFromDataSet(qrySales);

Alles na AddRow (of LoadFromDataSet) wordt voor u berekend: de component groepeert de ruwe rijen, past de gekozen aggregatie per cel toe, en voegt automatisch de rij-, kolom- en eindtotaalrijen en -kolommen toe.

ActivityFeed — een live, push-bare gebeurtenisstroom

TsgcHTMLComponent_ActivityFeed rendert een lijst met "wie deed wat"-items, nieuwste bovenaan, met relatieve tijdstempels ("3 min geleden", client-side live gehouden), en is vanaf het begin ontworpen om via WebSockets naartoe gepusht te worden, niet alleen eenmalig gerenderd. MaxItems houdt het een ringbuffer — het oudste item valt automatisch weg zodra u bij de limiet zit.

uses
  sgcHTML_Enums, sgcHTML_Component_ActivityFeed;

var
  oFeed: TsgcHTMLComponent_ActivityFeed;
begin
  oFeed := TsgcHTMLComponent_ActivityFeed.Create(nil);
  try
    oFeed.FeedID := 'timeline';
    oFeed.Title := 'Recent Activity';
    oFeed.MaxItems := 30;

    oFeed.AddActivity('Ana', 'closed', 'ticket #482', hcSuccess, 'bi bi-check-circle');
    oFeed.AddActivity('Marc', 'commented on', 'invoice #1190', hcPrimary);

    WebModule.Response := oFeed.HTML;   // feed list + scoped CSS + live relative-time script
  finally
    oFeed.Free;
  end;
end;

// Push a new item live to connected clients (out-of-band htmx fragment):
oFeed.AddActivity('Ana', 'approved', 'purchase order #77', hcSuccess);
Engine.BroadcastFragment(oFeed.GetLastItemFragmentHTML);

Die laatste regel is het interessante deel: GetLastItemFragmentHTML rendert alleen het nieuwste item als een out-of-band htmx-fragment, en BroadcastFragment pusht het naar elke geopende browser via de sgcWebSockets-server die u al draaiend heeft. Geen polling, geen aparte realtime-laag om op te zetten.

Splitter — de tweedelige shell die alles bijeenhoudt

TsgcHTMLComponent_Splitter is het lay-outonderdeel: twee aanpasbare panelen met een sleepbare gutter ertussen, horizontaal of verticaal, met minimale pixelgrenzen aan elke kant zodat geen van beide panelen tot niets versleept kan worden. Het is precies de shell die een TreeGrid-plus-detailpaneel of een bestandslijst-plus-editorscherm nodig heeft.

uses
  sgcHTML_Component_Splitter;

var
  oSplitter: TsgcHTMLComponent_Splitter;
begin
  oSplitter := TsgcHTMLComponent_Splitter.Create(nil);
  try
    oSplitter.SplitterID := 'workspace';
    oSplitter.Orientation := soHorizontal;
    oSplitter.InitialSplit := 30;
    oSplitter.MinSizeA := 180;
    oSplitter.MinSizeB := 320;
    oSplitter.GutterSize := 8;
    oSplitter.Height := '560px';
    oSplitter.PersistKey := 'workspace-split';

    oSplitter.AddPaneA('<div class="p-3"><h5>Files</h5>...</div>');
    oSplitter.AddPaneB('<div class="p-3"><h5>Editor</h5>...</div>');

    WebModule.Response := oSplitter.HTML;   // two panes + gutter + scoped CSS + drag script
  finally
    oSplitter.Free;
  end;
end;

PersistKey is het vermelden waard: stel deze in en de gutterpositie die een bezoeker versleept, wordt client-side onthouden en bij het volgende bezoek hersteld, zodat een werkruimte-lay-out over sessies heen behouden blijft zonder dat u ook maar één regel state-managementcode hoeft te schrijven.

Probeer ze uit

Alle vier zijn beschikbaar in de huidige sgcWebSockets-release, met volledige documentatie, referenties voor sleuteleigenschappen en Delphi/C++Builder/.NET-codevoorbeelden op hun eigen pagina's: TreeGrid, PivotTable, ActivityFeed en Splitter. De volledige featuretabel telt nu 83 componenten verdeeld over negen families — de volgende post in deze reeks behandelt de nieuwe grafieken en visuele codes.

Vragen, feedback of hulp bij migratie? Neem contact op — u krijgt antwoord van de mensen die de code hebben geschreven.