Jednotka lxOutline poskytuje geometrii a plánování mutací nezávislé na enginu pro osnovy řádků a sloupců
Ukládá pouze materializované rozsahy, rozpoznává souhrnné uzly z přilehlých přechodů úrovní osnovy a vytváří komprimované změny stavu pro rozvržení se souhrnem za a před detaily bez alokace položky pro každou souřadnici listu
Základní typy
TXLSOutlineAxis = (xoaRows, xoaColumns);
TXLSOutlineChildMode = (xocPreserve, xocCollapse, xocExpand);
TXLSOutlineMutationPlan = class
constructor Create(AAxis: TXLSOutlineAxis);
procedure Clear;
property Axis: TXLSOutlineAxis;
property Count: Integer;
property Changes[Index: Integer]: TXLSOutlineStateChange;
end;
TXLSOutlineGeometry = class
constructor Create(AAxis: TXLSOutlineAxis;
ASummaryAfter: Boolean);
procedure Clear;
property Axis: TXLSOutlineAxis;
property SpanCount: Integer;
procedure AddSpan(AFirstIndex, ALastIndex, ALevel: Integer;
AHidden, ACollapsed: Boolean);
function TryGetNode(ANodeIndex: Integer;
out ANode: TXLSOutlineNode): Boolean;
function TryBuildNodeCollapsePlan(ANodeIndex: Integer;
ACollapsed: Boolean; AChildMode: TXLSOutlineChildMode;
APlan: TXLSOutlineMutationPlan): Boolean;
procedure BuildDisplayLevelPlan(ADisplayLevel: Integer;
AChildMode: TXLSOutlineChildMode;
APlan: TXLSOutlineMutationPlan);
end;
Indexy řádků a sloupců jsou indexované od jedničky, úrovně osnovy jsou nezáporné a rozsahy se musí přidávat v přísně rostoucím nepřekrývajícím se pořadí
Přilehlé rozsahy se stejnou úrovní, skrytým a sbaleným stavem se automaticky slučují; vynechané indexy mají implicitní úroveň nula, viditelný stav a žádnou značku sbalení
Obě třídy si pamatují svou Axis z konstrukce, Clear vyprázdní plán nebo geometrii pro opětovné použití bez realokace interních bufferů a SpanCount hlásí, kolik sloučených rozsahů geometrie aktuálně drží
Sémantika uzlů
| NodeIndex | Fyzický souhrnný řádek nebo sloupec dotazovaný volajícím |
| FirstDetailIndex / LastDetailIndex | Souvislý rozsah detailů, jehož úroveň je hlubší než úroveň souhrnné položky |
| SummaryLevel | Úroveň osnovy uložená na souhrnné položce, nebo nula, když tato položka není materializována |
| Level | Úroveň skupiny reprezentovaná uzlem, rovna SummaryLevel + 1 |
| SummaryHidden | Skrytý stav uložený na souhrnné položce |
| Collapsed | Explicitní značka sbalení uložená na souhrnné položce |
| SummaryAfter | True, když detaily předcházejí souhrnné položce, false, když ji následují |
Vnořené skupiny zůstávají nezávislé, protože každý dotaz končí u prvního přilehlého rozsahu, jehož úroveň není hlubší než úroveň vybrané souhrnné položky
Mezera rovněž ukončuje rozsah detailů, takže řídká metadata nemohou náhodně přemostit nepoužívané souřadnice do jedné skupiny
Plány mutací
Plán mutace obsahuje uspořádané rozsahy indexované od jedničky a masku polí udávající, zda každý rozsah mění skrytý stav, sbalený stav nebo obojí; přilehlé ekvivalentní změny se automaticky slučují
| xocPreserve | Mění vybraný uzel při zachování značek sbalení potomků, což je výchozí chování pro vnořené skupiny |
| xocCollapse | Označí uzly potomků jako sbalené, když jsou uvnitř vybraného uzlu nebo skryty pod požadovanou zobrazovací úrovní |
| xocExpand | Zruší značky sbalení potomků, když jsou uvnitř vybraného uzlu nebo skryty pod požadovanou zobrazovací úrovní |
Rozbalení rodiče s xocPreserve odhalí bezprostřední detaily, zatímco detaily náležející sbaleným potomkům zůstávají skryty; rozbalení potomka uvnitř sbaleného předka neodhalí obsah skrze tohoto předka
Zobrazovací úrovně jsou indexované od jedničky: úroveň 1 sbalí každou skupinu nejvyšší úrovně a každá vyšší hodnota odhalí jednu další úroveň osnovy, přičemž nastavuje odpovídající značky okrajových uzlů
Sestavení stejného požadovaného stavu z geometrie, která jej již obsahuje, vytvoří prázdný plán a dotaz na neuzel vrátí false s prázdným plánem
Operace uzlů ponechávají nezávislý skrytý stav vybrané souhrnné položky beze změny a plány zobrazovacích úrovní znovu nezobrazí položky úrovně nula, které byly skryty mimo skupinu osnovy
Adaptéry listů
function TryGetOutlineNode(AAxis: TXLSOutlineAxis;
ANodeIndex: Integer; out ANode: TXLSOutlineNode): Boolean;
function SetOutlineNodeCollapsed(AAxis: TXLSOutlineAxis;
ANodeIndex: Integer; ACollapsed: Boolean;
AChildMode: TXLSOutlineChildMode = xocPreserve): Boolean;
procedure SetOutlineDisplayLevel(AAxis: TXLSOutlineAxis;
ADisplayLevel: Integer;
AChildMode: TXLSOutlineChildMode = xocPreserve);
TXLSWorksheet a TXLSXWorksheet zpřístupňují stejné tři metody, takže volající mohou dotazovat nebo měnit souhrnný uzel řádku či sloupce indexovaný od jedničky bez ručního sestavování geometrie
Klasický adaptér čte pouze alokované bloky řádků a přiřazená metadata sloupců, zatímco adaptér XLSX sloučí své řídké seznamy úrovní osnovy, skrytého a sbaleného stavu dříve, než aplikuje jeden komprimovaný plán mutace v jedné zapisovací transakci
Skupiny řádků a sloupců OpenDocument si uchovávají svůj nativní vnořený stav table:display; přímé úpravy metadat a strukturální změny řádků či sloupců bezpečně promítnou tento stav do logického souhrnného uzlu a konverze do XLSX zapíše značku sbalení na souhrnnou položku XLSX namísto každého člena skupiny
Stávající metody TXLSXWorksheet.ToggleRowGrouped a ToggleColGrouped zůstávají k dispozici jako kompatibilní obálky; jejich argumentem je první řádek nebo sloupec detailů a obálka rozpozná uzel souhrnu s ohledem na směr dříve, než jej přepne
Příklad pro Delphi
Geometry := TXLSOutlineGeometry.Create(xoaRows, True);
Plan := TXLSOutlineMutationPlan.Create(xoaRows);
try
Geometry.AddSpan(2, 4, 1, False, False);
Geometry.AddSpan(5, 5, 0, False, False);
if Geometry.TryGetNode(5, Node) then
UseOutlineNode(Node.FirstDetailIndex,
Node.LastDetailIndex, Node.Collapsed);
if Geometry.TryBuildNodeCollapsePlan(5, True,
xocPreserve, Plan) then
ApplyOutlineChanges(Plan);
finally
Plan.Free;
Geometry.Free;
end;
Příklad pro C++Builder
Lxoutline::TXLSOutlineGeometry *geometry =
new Lxoutline::TXLSOutlineGeometry(Lxoutline::xoaColumns, false);
try {
geometry->AddSpan(3, 3, 0, false, true);
geometry->AddSpan(4, 7, 1, true, false);
Lxoutline::TXLSOutlineNode node;
if (geometry->TryGetNode(3, node))
UseOutlineNode(node.FirstDetailIndex, node.LastDetailIndex,
node.Collapsed);
}
__finally {
delete geometry;
}
Výkon a rozsah
Vyhledání uzlu používá binární vyhledávání následované pouze přilehlými materializovanými rozsahy, které vybraná skupina protíná, což dává práci O(log n + k) pro n rozsahů a k navštívených rozsahů
Hromadné plánování mutací objeví každý materializovaný uzel lineárním průchodem monotónního zásobníku, sloučí intervaly viditelnosti sbalení a vysílá komprimované změny rozsahů bez návštěvy nepoužívaných souřadnic
Sestavovač přijímá poslední řádek listu XLSX, přičemž uchovává pouze dodané rozsahy, takže vysoká souřadnice neimplikuje alokaci ani prohledání milionu položek
Regresní brána adaptéru listů spouští stejných 32,768 dotazů na uzly a 2,048 mutací sbalení nebo rozbalení nad šesti materializovanými položkami řádků poblíž řádku 8 a řádku 1,048,576, vyžaduje nulovou materializaci buněk a omezuje náklady vysokých souřadnic vůči základní linii nízkých souřadnic
TXLSOutlineGeometry nikdy nezapisuje přímo data sešitu; adaptéry engineů vrácený plán validují a aplikují, takže analýza geometrie a mutace stavu zůstávají odděleny
Viz také