Единицата lxOutline предоставя независима от машината геометрия и планиране на мутации за контури по редове и колони
Тя съхранява само материализирани диапазони, разпознава обобщени възли от съседни преходи на нивото на контура и създава компресирани промени на състоянието за подредби с обобщение след и обобщение преди, без да заделя запис за всяка координата на листа
Основни типове
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;
Индексите на редове и колони започват от единица, нивата на контура са неотрицателни, а диапазоните трябва да се добавят в строго растящ, несъставен ред
Съседните диапазони с еднакво ниво, скрито състояние и състояние на свиване се сливат автоматично; пропуснатите индекси имат имплицитно ниво нула, видимо състояние и липса на маркер за свиване
И двата класа помнят своя Axis от конструкцията, Clear изпразва план или геометрия за повторна употреба, без да преразпределя вътрешните буфери, а SpanCount докладва колко слети диапазона държи в момента геометрията
Семантика на възлите
| NodeIndex | Физическият обобщен ред или колона, заявена от извикващия |
| FirstDetailIndex / LastDetailIndex | Непрекъснатият диапазон от детайли с ниво, по-дълбоко от това на обобщената позиция |
| SummaryLevel | Нивото на контура, съхранявано на обобщената позиция, или нула, когато тя не е материализирана |
| Level | Нивото на групата, представлявано от възела, равно на SummaryLevel + 1 |
| SummaryHidden | Скритото състояние, съхранявано на обобщената позиция |
| Collapsed | Изричният маркер за свиване, съхраняван на обобщената позиция |
| SummaryAfter | Истина, когато детайлите предхождат обобщената позиция, и false, когато детайлите я следват |
Вложените групи остават независими, защото всяка заявка спира на първия съседен диапазон, чието ниво не е по-дълбоко от това на избраната обобщена позиция
Празнина също прекратява диапазона от детайли, така че разредените метаданни не могат случайно да свържат неизползвани координати в една група
Планове за мутации
Планът за мутация съдържа подредени диапазони, броени от единица, и маска на полетата, указваща дали всеки диапазон променя скритото състояние, състоянието на свиване или и двете; съседните еквивалентни промени се сливат автоматично
| xocPreserve | Променя избрания възел, като запазва маркерите за свиване на наследниците, което е поведението по подразбиране за вложени групи |
| xocCollapse | Маркира наследниците като свити, когато са в избрания възел или скрити под заявеното ниво на показване |
| xocExpand | Изчиства маркерите за свиване на наследниците, когато са в избрания възел или скрити под заявеното ниво на показване |
Разгъването на родител с xocPreserve разкрива непосредствените детайли, докато детайлите на свити наследници остават скрити; разгъването на наследник вътре в свит предшественик не разкрива съдържание през този предшественик
Нивата на показване започват от единица: ниво 1 свива всяка група от най-горното ниво, а всяка по-висока стойност разкрива още едно ниво на контура, като задава съответните маркери на граничните възли
Изграждането на същото заявеното състояние от геометрия, която вече го съдържа, произвежда празен план, а заявка към невъзел връща false с празен план
Операциите върху възли оставят независимото скрито състояние на избраната обобщена позиция непроменено, а плановете за ниво на показване не разкриват позиции с ниво нула, скрити извън контурна група
Адаптери за листове
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 и TXLSXWorksheet разкриват едни и същи три метода, така че извикващият може да заявява или променя обобщен възел на ред или колона, броени от единица, без да изгражда геометрия ръчно
Класическият адаптер чете само разпределените блокове с редове и заделените метаданни за колони, докато XLSX адаптерът слива своите разредени списъци за ниво на контура, скрито и свито състояние, преди да приложи един компресиран план за мутация в една транзакция на запис
Групите по редове и колони в OpenDocument запазват своето собствено вложено състояние table:display; директните промени на метаданните и структурните промени по редове или колони безопасно проектират това състояние към логическия обобщен възел, а преобразуването към XLSX записва маркера за свиване на XLSX обобщената позиция, а не на всеки член на групата
Съществуващите методи TXLSXWorksheet.ToggleRowGrouped и ToggleColGrouped остават налични като съвместими обвивки; техен аргумент е първият детайлен ред или колона, а обвивката открива зависещия от посоката обобщен възел, преди да го превключи
Пример за 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;
Пример за 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;
}
Производителност и обхват
Търсенето на възел използва двоично търсене, следвано само от съседните материализирани диапазони, пресичани от избраната група, което дава работа от O(log n + k) за n диапазона и k посетени диапазона
Планирането на групови мутации открива всеки материализиран възел с линеен проход на монотон стек, слива интервалите на свита видимост и издава компресирани промени по диапазони, без да посещава неизползвани координати
Изграждащият приема последния ред на XLSX лист, като задържа само подадените диапазони, така че висока координата не подразбира заделяне или сканиране на милион записа
Регресионният праг на адаптера за листове изпълнява едни и същи 32,768 заявки към възли и 2,048 мутации на свиване или разгъване върху шест материализирани записа с редове около ред 8 и ред 1,048,576, изисква нула материализации на клетки и ограничава разходът при високи координати спрямо базовата линия при ниски координати
TXLSOutlineGeometry никога не записва директно данни на работната книга; адаптерите за машините валидират и прилагат върнатия план, позволявайки анализът на геометрията и промяната на състоянието да останат отделени
Вижте също