Jednostka lxOutline dostarcza neutralną wobec silników geometrię oraz planowanie modyfikacji dla konspektów wierszy i kolumn
Przechowuje wyłącznie zmaterializowane segmenty, rozpoznaje węzły podsumowujące po sąsiednich przejściach poziomów konspektu i tworzy skompresowane zmiany stanu dla układów z podsumowaniem po i przed, bez przydzielania wpisu dla każdej współrzędnej arkusza
Typy podstawowe
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;
Indeksy wierszy i kolumn są numerowane od jedynki, poziomy konspektu są nieujemne, a segmenty muszą być dodawane w ściśle rosnącej kolejności bez nakładania się
Sąsiednie segmenty o identycznym poziomie, stanie ukrycia i zwinięcia są automatycznie scalane; pominięte indeksy mają niejawny poziom zerowy, stan widoczny i nie mają znacznika zwinięcia
Obie klasy pamiętają swój Axis od chwili konstrukcji, Clear opróżnia plan lub geometrię w celu ponownego użycia bez ponownego przydzielania buforów wewnętrznych, a SpanCount zgłasza, ile scalonych segmentów geometria obecnie przechowuje
Semantyka węzłów
| NodeIndex | Fizyczny wiersz lub kolumna podsumowująca odpytana przez wywołującego |
| FirstDetailIndex / LastDetailIndex | Ciągły zakres szczegółów, którego poziom jest głębszy od elementu podsumowującego |
| SummaryLevel | Poziom konspektu zapisany na elemencie podsumowującym lub zero, gdy ten element nie jest zmaterializowany |
| Level | Poziom grupy reprezentowany przez węzeł, równy SummaryLevel + 1 |
| SummaryHidden | Stan ukrycia zapisany na elemencie podsumowującym |
| Collapsed | Jawny znacznik zwinięcia zapisany na elemencie podsumowującym |
| SummaryAfter | True, gdy szczegóły poprzedzają element podsumowujący, false, gdy szczegóły następują po nim |
Grupy zagnieżdżone pozostają niezależne, ponieważ każde zapytanie zatrzymuje się na pierwszym sąsiednim segmencie, którego poziom nie jest głębszy od wybranego elementu podsumowującego
Luka również kończy zakres szczegółów, dzięki czemu rozrzedzone metadane nie mogą przypadkowo spiąć nieużywanych współrzędnych w jedną grupę
Plany modyfikacji
Plan modyfikacji zawiera uporządkowane zakresy numerowane od jedynki oraz maskę pól wskazującą, czy każdy zakres zmienia stan ukrycia, stan zwinięcia czy oba; sąsiednie równoważne zmiany są scalane automatycznie
| xocPreserve | Zmienia wybrany węzeł, zachowując znaczniki zwinięcia potomków — jest to domyślne zachowanie dla grup zagnieżdżonych |
| xocCollapse | Oznacza węzły potomne jako zwinięte, gdy znajdują się wewnątrz wybranego węzła lub są ukryte poniżej żądanego poziomu wyświetlania |
| xocExpand | Zdejmuje znaczniki zwinięcia potomków, gdy znajdują się wewnątrz wybranego węzła lub są ukryte poniżej żądanego poziomu wyświetlania |
Rozwijanie rodzica z xocPreserve ujawnia bezpośrednie szczegóły, podczas gdy szczegóły należące do zwiniętych potomków pozostają ukryte; rozwijanie potomka wewnątrz zwiniętego przodka nie ujawnia zawartości przez tego przodka
Poziomy wyświetlania są numerowane od jedynki: poziom 1 zwija każdą grupę najwyższego poziomu, a każda większa wartość ujawnia jeden dodatkowy poziom konspektu, ustawiając pasujące znaczniki węzłów granicznych
Zbudowanie tego samego żądanego stanu z geometrii, która już go zawiera, daje pusty plan, a odpytanie nieistniejącego węzła zwraca false z pustym planem
Operacje na węzłach pozostawiają niezależny stan ukrycia wybranego elementu podsumowującego bez zmian, a plany poziomów wyświetlania nie czynią ponownie widocznymi elementów poziomu zerowego ukrytych poza grupą konspektu
Adaptery arkuszy
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 i TXLSXWorksheet udostępniają te same trzy metody, dzięki czemu wywołujący może odpytać lub zmienić węzeł podsumowujący wiersza lub kolumny numerowany od jedynki bez ręcznego budowania geometrii
Adapter klasyczny czyta wyłącznie przydzielone bloki wierszy i przypisane metadane kolumn, natomiast adapter XLSX scala swoje rozrzedzone listy poziomów konspektu, ukrycia i zwinięcia przed zastosowaniem jednego skompresowanego planu modyfikacji w pojedynczej transakcji zapisu
Grupy wierszy i kolumn OpenDocument zachowują swoje natywne zagnieżdżone wartości table:display; bezpośrednie edycje metadanych i strukturalne zmiany wierszy lub kolumn bezpiecznie projektują ten stan na logiczny węzeł podsumowujący, a konwersja na XLSX zapisuje znacznik zwinięcia na elemencie podsumowującym XLSX, a nie na każdym członku grupy
Istniejące metody TXLSXWorksheet.ToggleRowGrouped i ToggleColGrouped pozostają dostępne jako wrappery zgodności; ich argumentem jest pierwszy wiersz lub kolumna szczegółów, a wrapper rozwiązuje uwzględniający kierunek węzeł podsumowujący przed jego przełączeniem
Przykład dla 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;
Przykład dla 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;
}
Wydajność i zakres zastosowania
Wyszukiwanie węzła używa wyszukiwania binarnego, po którym następują wyłącznie sąsiednie zmaterializowane segmenty przecinane przez wybraną grupę, co daje pracę O(log n + k) dla n segmentów i k odwiedzonych segmentów
Masowe planowanie modyfikacji odnajduje każdy zmaterializowany węzeł liniowym przebiegiem ze stosem monotonicznym, scala przedziały widoczności stanów zwiniętych i emituje skompresowane zmiany zakresów bez odwiedzania nieużywanych współrzędnych
Konstruktor przyjmuje ostatni wiersz arkusza XLSX, zachowując wyłącznie dostarczone segmenty, więc duża współrzędna nie oznacza przydziału ani skanowania o milionie wpisów
Regresyjna bramka adaptera arkuszy wykonuje te same 32,768 zapytań o węzły i 2,048 modyfikacji zwinięcia lub rozwinięcia na sześciu zmaterializowanych wpisach wierszy w pobliżu wiersza 8 i wiersza 1,048,576, wymaga zerowej materializacji komórek i ogranicza koszt dużych współrzędnych względem punktu odniesienia małych współrzędnych
TXLSOutlineGeometry nigdy nie zapisuje bezpośrednio danych skoroszytu; adaptery silników walidują i stosują zwrócony plan, pozwalając analizie geometrii i modyfikacji stanu pozostać rozdzielnymi
Zobacz także