- Damit sich die Buchdaten von Anna’s Archive mit mehr als 100 Millionen Büchern auf einem einzigen Bildschirm erkunden lassen, braucht es einen Ansatz, der den begrenzten Identifikatorraum der ISBN in eine Karte verwandelt.
- ISBN13 bildet ohne die Präfixe
978-/979-und die abschließende Prüfziffer einen eindimensionalen Raum mit rund 2 Milliarden Slots, wobei Länder- und Verlagsbereiche auf Präfix-Ebene zugewiesen werden. - Da eine einfache zeilenweise Anordnung oder eine Hilbert-Kurve die ISBN-Struktur schwer erkennbar machen kann, wird die Bookshelf-Curve verwendet, die Dezimalstellen in 2D-Koordinaten überführt.
- Die Kartentiles werden als statische PNG- und JSON-Dateien bereitgestellt, und WebGL/GLSL-Shader übernehmen Rendering und Filterung wie Erscheinungsjahr, Bestandsquote, Datensatzvergleich oder Verlags-Hervorhebung sofort.
- Implementiert wurde das Ganze als statisches Frontend auf Basis von ThreeJS, React, MobX und react-threejs-fiber; für die praktische Nutzbarkeit sind vor allem die Optimierung des Text-Renderings in großer Menge und die Performance beim Zoomen und Verschieben entscheidend.
Warum der ISBN-Raum als Ziel für die Visualisierung gewählt wurde
- Bibliotheken sammeln seit Langem das Wissen der Menschheit, und im digitalen Zeitalter könnte es möglich werden, Werke, die bestimmte Kriterien erfüllen, umfassend zu erfassen.
- Anna’s Archive, eine der Shadow Libraries, brauchte eine Visualisierung, mit der sich mehr als 100 Millionen Bücher auf einmal erkunden lassen.
- Die Zieldaten umfassen unter anderem Titel, Autor, Land, Verlag, Veröffentlichungszeitraum, Anzahl haltender Bibliotheken und digitale Verfügbarkeit.
- Die interaktive Visualisierung unterstützt die Auswahl von Datensätzen, die Suche nach einzelnen Büchern, Filter nach Erscheinungsjahr und zusammengesetzte Visualisierungen auf Basis benutzerdefinierter Shader.
- Bei maximalem Zoom wechselt die Darstellung zu einer Ansicht, in der jedes Buch aussieht, als stünde es in einem Bücherregal.
Die Struktur der ISBN
- ISBN13 ist eine 13-stellige Nummer, die fast allen veröffentlichten Büchern zugewiesen wird.
- Derzeit sind die ersten drei Stellen von ISBN13 fest auf
978-oder979-gesetzt, die letzte Stelle ist eine Prüfziffer. - Daher kann der eigentliche ISBN13-Raum als etwa 2 Milliarden Slots groß betrachtet werden.
- Die Präfixe
978-und979-existieren, weil ISBN13 eine Teilmenge der European Article Number ist; dieses feste Präfix heißt Bookland. - Große ISBN-Blöcke werden von der International ISBN Agency an internationale Organisationen vergeben, und einzelne Länder teilen ihre Blöcke anschließend auf Verlagsebene weiter auf.
- ISBN-Blöcke werden immer auf **Präfix-**Ebene vergeben.
978-4ist Japan zugewiesen.- Japan weist
978-4-312einem Verlag zu. - Dieser Verlag kann Einträge im Bereich
000000-99999vergeben und so ISBNs wie978-4-312-99999-Xerzeugen.
- Je länger das Länderpräfix ist, desto kleiner ist die Zahl der Bücher, die darin vergeben werden können.
- Japan verfügt über einen ISBN-Raum von 100 Millionen.
- Singapur beginnt mit dem Präfix
978-9971-und hat daher nur Platz für 100.000 ISBNs.
Wie man eindimensionale ISBNs in zwei Dimensionen auffaltet
- Entfernt man die Präfixe
978-/979-und die Prüfziffer, wird die ISBN zu einem eindimensionalen Dezimalwert zwischen 0 und 2 Milliarden. - Die einfachste Methode wäre, Pixel von oben nach unten zeilenweise zu füllen, aber dann ziehen sich kleine Bereiche horizontal in die Länge, wodurch die ISBN-Struktur schwerer zu erkennen ist.
- Eine Hilbert-Kurve macht kleine Bereiche eher quadratisch, kann aber räumliche Strukturartefakte erzeugen, die in den Daten selbst nicht vorhanden sind.
- Um nicht vorhandene Strukturen zu vermeiden, verwendet diese Visualisierung die Bookshelf-Curve, die die Dezimalnatur der ISBN ausnutzt.
Bookshelf-Curve
- Die Bookshelf-Curve platziert beim rekursiven Wiederholen zunächst die
0-9der ersten Dezimalstelle nebeneinander und dann die0-9der nächsten Stelle vertikal darüber und darunter. - Um das Seitenverhältnis der zwei Rechteckebenen beizubehalten, muss jedes Blockformat ein Verhältnis von
√10, also ungefähr 3,16:1, haben. - Diese Struktur ähnelt dem rekursiven Seitenverhältnis von A4-Papier, nur dass sie nicht in zwei, sondern in 10 Segmente unterteilt wird.
- Die Koordinatentransformation ist einfach, weil die Ziffern der ISBN abwechselnd als Koordinaten verwendet werden.
- Der Implementierungscode ist wegen Generalisierungsversuchen 50 Zeilen lang geworden, aber das Prinzip ist so leicht nachvollziehbar, dass man die Position einer bestimmten ISBN auch von Hand verfolgen kann.
Kartentiles und Datenkodierung
- Für jedes ISBN-Präfix werden Tile-Bilder erzeugt.
- Die Zielgröße pro Tile lag bei etwa
100kB, woraus sich eine Tile-Größe von2000 × 633Pixeln ergab. - Je nach Datensatz wird in den Pixeln unterschiedliche Information gespeichert.
- Im Datensatz zum Erscheinungsjahr wird der Wert nach Abzug von
1800in einem 8-Bit-Bereich gespeichert. - Der rote Kanal enthält das durchschnittliche Erscheinungsjahr der Bücher in diesem Pixel.
- Der blaue Kanal enthält den Anteil vorhandener Bücher.
- Wenn zum Beispiel 50 % der Bücher vorhanden sind, beträgt der Wert im blauen Kanal
127/255.
- Im Datensatz zum Erscheinungsjahr wird der Wert nach Abzug von
- Auf der höchsten Zoomstufe wird zur Genauigkeit ein Buch auf genau ein Pixel abgebildet.
Rendering auf Basis von GLSL-Shadern
- Anfangs wurden RGB-Daten direkt in den Tiles gespeichert, aber für mehr Flexibilität werden nun abstraktere Daten gespeichert, während das eigentliche Rendering im GLSL-Fragment-Shader der GPU erfolgt.
- Dadurch lassen sich Farbpaletten später auswählen, beliebige Transformationen und Filter sofort anwenden oder mehrere Datensätze spontan kombinieren.
- Die Daten zum Erscheinungsjahr speichern den Bereich
1800-2055, aber 95 % der Daten liegen zwischen1985-2024, weshalb dieser Bereich im Shader komprimiert dargestellt werden kann. - Die Funktion
heatmapColor(float)wandelt einen0-1-Wert in eine vom Benutzer gewählte Farbskala um. - Die Syntax
$dataset_xist keine echte GLSL-Syntax, sondern eine einfache Template-Syntax auf Regex-Basis, damit nur die Bilder geladen werden, die der Shader tatsächlich liest. - In der Option ⚙️ Advanced der Visualisierung kann der Shader direkt bearbeitet werden, und Änderungen werden in Echtzeit übernommen.
- Die Bedeutung jedes Datensatz-Pixels ist im README dokumentiert.
Eine Darstellung, die beim Hineinzoomen wie ein Bücherregal wirkt
- In der vollständig hineingezoomten Ansicht bekommt jedes Pixel ein Styling, das wie ein Buch aussieht.
- Jedes Buch erhält eine zufällige Breite, Höhe und Musterung.
- Es entspricht nicht exakt der Form realer Bücher, lässt die maximal gezoomte Ansicht aber deutlich lebendiger wirken.
- Dieses Styling ist vollständig im Shader implementiert.
- Weil in GLSL und JavaScript dieselben Zufallsergebnisse benötigt wurden, war vor allem der Teil knifflig, in dem die Buchhöhe berechnet wird, um Textgrenzen korrekt auszurichten.
- Wenn der aktuelle Zoomwert als Uniform übergeben und zwischen zwei Zoomstufen eingeblendet wird, lässt sich der Regalstil weich einblenden.
Text, Baumstruktur und Performance
- Genau wie die Bild-Tiles wird auch Text abhängig von Zoomstufe und View-Frustum-Culling in einer hierarchischen Struktur gerendert.
- Für die Implementierung wurde react-threejs-fiber verwendet.
- React fügt beim Verschieben der Ansicht rekursiv Szenenelemente hinzu; pro Präfix bestehen diese aus einer Plane, HTML-Text und untergeordneten Präfix-Knoten.
- Das Rendern großer Textmengen verursachte anfangs erhebliche Performanceprobleme.
- Der beste Ansatz war, HTML in ein SVG-
<foreignObject />zu legen, es perdrawImageauf ein Canvas zu rendern und anschließend als Textur zu laden. - Das funktionierte, verursachte beim Rendern jedoch jedes Mal synchron eine Verzögerung von 20 ms.
- Weil sich SVG nicht in einem WebWorker zeichnen ließ, war eine Auslagerung in einen WebWorker schwierig.
- Die eigentlichen Performanceprobleme wurden größtenteils dadurch gelöst, dass die Zahl der HTML-Elemente reduziert, die pro Frame hinzugefügten DOM-Inhalte begrenzt und insbesondere der CSS-Filter-Stack von
text-shadowentfernt wurde.
Barcode und Verlagsbereiche
- Beim maximalen Zoom wird für jedes Buch ein Barcode angezeigt.
- Der Barcode wurde hinzugefügt, um die Idee zu verstärken, dass die Bücher nach ISBN sortiert sind.
- Statt einer Barcode-Rendering-Bibliothek wird die Libre Barcode-TTF-Schriftart verwendet, die 13-stellige Zahlen als Barcode rendert und sogar die Prüfziffer berechnet.
- Dank der Optimierungen des Text-Renderings im Betriebssystem war dieser Ansatz praktisch und performant.
- Jede Gruppe deckt meist einen großen Bereich auf Länderebene ab, innerhalb dessen die Verlage kleinere Bereiche belegen.
- Gruppen und Verlage erhalten jeweils eigene zufällige Farben.
- Wenn ein Verlag mehrere Bereiche besitzt, wird trotzdem dieselbe Farbe verwendet.
- Um alle Bereiche gleichzeitig hervorzuheben, bekommt jeder Verlag eine eindeutige ID, die in RGB-Komponenten gespeichert wird.
- Bei den Verlagsfarben gibt es noch Punkte, mit denen man nicht ganz zufrieden ist.
- Verlagsfarben kollidieren mit der Farbskala der Heatmap.
- Länderbereiche sind schwer zu erkennen.
Suchnavigation und Flugpfad
- Wenn ein Buch gesucht oder auf die Minimap geklickt wird, erfolgt ein Flug zur betreffenden Position.
- Einen ästhetisch guten Flugpfad zu berechnen, erwies sich als schwieriger als gedacht.
- Mit Parabel-Fitting waren die Ergebnisse eher mittelmäßig, danach wurde ein Ansatz mit einem separaten Transformationsraum ausprobiert.
- Das Endergebnis ist nicht perfekt und mit rund 500 Zeilen Code etwas überkonstruiert, funktioniert aber besser als der ursprüngliche Ansatz.
Architektur und Verarbeitungspipeline
- Ein Backend ist nicht nötig.
- Die Bild-Tiles werden als PNG gespeichert.
- Der Datenbaum wird als JSON gespeichert.
- HTML, JS, CSS, PNG und JSON können auf einem statischen File-Host wie GitHub Pages bereitgestellt werden.
- Das Frontend verwendet ThreeJS, React und MobX.
- Diese Kombination war praktisch, um wiederverwendbare Komponenten für reaktive, deklarative, GPU-beschleunigte 2D-/3D-Szenen zu bauen.
- Die Verarbeitungsskripte sind größtenteils in JS geschrieben und erzeugen JSON und PNG direkt.
- Einige Skripte mussten jedoch 250-GB-Quelldateien lesen und nach SQLite ausgeben, weshalb sie in Rust geschrieben wurden.
Ergebnis und Code
- Das Ergebnis ist eine flexible Art, veröffentlichte Bücher mit zugewiesener ISBN zu visualisieren.
- Möglich wurde das Projekt dadurch, dass ISBNs gerade klein genug als Identifikatorraum entworfen wurden.
- Mit UUIDs wäre dieselbe Aufgabe größtenteils nur ein riesiger leerer Raum gewesen.
- Der Quellcode ist in isbn-visualization öffentlich verfügbar.
1 Kommentare
Meinungen auf Hacker News
Als ich Amazon gründete, wollte ich genau so etwas machen, allerdings mit der dreiteiligen Klassifikation der Library of Congress statt mit ISBNs.
Am Ende hatten unsere Datenlieferanten Baker & Taylor und Books In Print diese dreiteilige Klassifikation zu einem einzigen String zusammengequetscht, sodass sich die Grenzen nicht zuverlässig erkennen ließen, und wir mussten aufgeben, noch bevor es richtig losging.
Eine solche „Flug“-artige Navigation im Web von 1994–1995 umzusetzen, wäre sicher ebenfalls nicht einfach gewesen – beeindruckende Arbeit.
Ich habe mir die LoC Classification und die LoC Subject Headings recht gründlich angesehen, und es ist schade, dass beide nicht frei in einem nützlichen maschinenlesbaren Format verfügbar sind. Mit PDFs kann man sich bis zu einem gewissen Grad behelfen.
Besonders der Abschnitt zum Recht der US-Bundesstaaten in der Classification hatte eine sehr ungleichmäßige Klassifikationsdichte je Bundesstaat: Soweit ich mich erinnere, waren NY und CA mit Abstand am komplexesten, PA folgte mit einigem Abstand auf Platz drei, und viele „Flyover“-Staaten waren fast lächerlich einfach und einander sehr ähnlich. Das scheint die Komplexität der kodifizierten Gesetze, der Regulierung und des Case Law in den jeweiligen Staaten widerzuspiegeln.
Eine weitere interessante historische Tatsache: Das Klassifikationssystem und die alphabetischen Top-Level-Bereiche scheinen direkt aus der Privatbibliothek von Thomas Jefferson zu stammen, aus der die LoC hervorgegangen ist.
Wer sich dafür interessiert, findet in den an den Kongress vorgelegten Jahresberichten des Librarian of Congress bei Hathi Trust viel zur Entwicklung und Erweiterung der Classification.
Classification: <https://www.loc.gov/catdir/cpso/lcco/>
Subject headings: <https://id.loc.gov/authorities/subjects.html>
Annual reports — Recent: <https://www.loc.gov/about/reports-and-budgets/annual-reports...> / Historical archive to ~1866: <https://catalog.hathitrust.org/Record/000072049>
Das war eines der technisch rückständigsten Unternehmen, mit denen ich je Geschäfte gemacht habe, und selbst als wir Anfang 2020 unser Konto schlossen, liefen Bestellungen und Abrechnungen noch über Papier, PDF und E-Mail. Ich glaube, zeitweise wollten sie Dokumente sogar per Fax geschickt bekommen.
Da es nicht selten vorkommt, dass ISBNs mehreren unterschiedlichen Büchern zugewiesen werden [0], ist die Formulierung „alle Bücher im ISBN-Raum“ möglicherweise übertrieben.
Außerdem gibt es Bücher mit ungültigen ISBNs, bei denen die Prüfziffer nicht zum Rest der ISBN passt. Wenn eine Korrektur der Prüfziffer dazu führt, dass sie mit einem anderen Buch übereinstimmt, liegt sie außerhalb des im Blogbeitrag angenommenen ISBN-Raums.
[0] https://scis.edublogs.org/2017/09/28/the-dreaded-case-of-dup...
Als ich mir die niedrigsten bekannten ISBNs tschechischer Verlage ansah, tauchte eine andere Farbe auf: https://books.google.cz/books?vid=ISBN9788000000015&redir_es... scheint keine gültige ISBN zu sein :-) Ich weiß allerdings nicht, ob in dem Buch tatsächlich eine so offensichtliche Fake-ISBN steht oder ob es sich um einen Datenfehler bei Google Books handelt.
Eine beeindruckende Präsentation.
Allerdings zeigt diese Ansicht nicht den gesamten ISBN-Katalog, sondern nur die Bestände von Anna's Archive. Wegen Annas Sammel-Bias sieht man eine Verzerrung zugunsten bestimmter Sprachbereiche, und die schwarz dargestellten Bereiche sind Einträge, die im Archiv nicht vorhanden sind.
Die Metadaten-Datenbank stammt aus mehreren Quellen und ist meines Wissens ziemlich vollständig. Schwarz sind wahrscheinlich größtenteils Bereiche, in denen keine Bücher vergeben wurden.
Wirklich großartig, ein erstaunliches Passion Project und eine hervorragende Ressource.
Beim Hineinzoomen sieht man Titel und Barcodes, und beim Darüberfahren mit der Maus erscheinen Cover und Details. Es bietet fast alles, was man sich wünschen kann.
Als Verbesserungsidee fände ich eine Checkbox gut, mit der man das schwebende weiße Panel oben links und die Elemente oben rechts ausblenden kann. Ich mag es, in solche Visualisierungen „einzutauchen“, aber die schwebenden Elemente holen einen ein wenig aus diesem Erlebnis heraus und mindern Spaß und Funktionalität etwas.
Das ist ein perfekter Anwendungsfall für Microsoft Silverlight PivotViewer, ein hervorragendes Web-Interface, das in der Neuroimaging-Community genutzt wurde, bevor Microsoft es eingestellt hat.
Es gibt einen eindrucksvollen TED-Talk von Gary W. Flake, in dem er die Nutzung demonstriert.
https://m.youtube.com/watch?v=LT_x9s67yWA
Außerdem gibt es ein IEEE-Paper von 2011. Es ist wirklich schade, dass das kein Webstandard ist.
https://www.dropbox.com/scl/fi/bl8zkjs3y47q3377hh3ya/Yan_Wil...
Eine sehr schöne Visualisierung.
Hier gibt es noch weitere großartige Einreichungen: https://software.annas-archive.li/AnnaArchivist/annas-archiv...
Meine Arbeit ist unter https://isbnviz.pages.dev zu finden
Beim Hineinzoomen sieht es wie ein Bücherregal aus. Wirklich großartig
Hervorragend. Wirkt wie eine reale Version der Library of Babel: https://libraryofbabel.info/
Bei all dem VR-Unsinn könnte ich mir vorstellen, für eine reale unendliche Bibliothek oder ein unendliches Museum Geld zu bezahlen
Viel interessanter wäre es wohl gewesen, wenn es ein Projekt wäre, das Zugang zu allen legal verfügbaren herunterladbaren Texten bietet. Zum Beispiel als Interface für Orte wie diesen:
https://onlinebooks.library.upenn.edu/
Die Präsentation in der aktuellen Form wirkte etwas überwältigend
Es hat eine Weile gedauert, bis ich verstanden habe, dass der Preset-Bereich oben links tatsächlich zu zusätzlichen Achsen der Datenvisualisierung führt, etwa ob AA enthalten ist, Seltenheit oder ob Google Books enthalten ist. Trotzdem sind Visualisierung und Datentiefe reichhaltig
Gut fand ich auch https://archive.anarchy.cool/blog/all-isbns.html#visualizing, wo die regionalen Cluster gezeigt werden
Das Jahres-Preset war schon für sich interessant, um die Publikationsaktivität nach Regionen zu betrachten. Poland ist in letzter Zeit sehr aktiv, Norway wirkt vergleichsweise ruhig. China scheint etwa seit 2005 zuzulegen und in den letzten zehn Jahren enorm gewachsen zu sein
Auch bei United States gibt es Merkwürdigkeiten. Ich hatte noch nie von ihnen gehört, aber Blackstone Audio, Blurb Inc. und Draft2Digital haben eine enorme Zahl von ISBNs vergeben
Eine etwas minimalistischere Ansicht (weniger Farben und jeweils nur eine Textebene) gibt es hier:
https://phiresky.github.io/isbn-visualization/?dataset=all&g...
Man könnte es wohl noch weiter anpassen, etwa indem man bestimmte Texte wie den Bereich „N publishers“ ausblendet oder die Mouseover-Informationen reduziert
Die Flugbahn lässt sich ziemlich plausibel als Bewegung auf der hyperbolischen oberen Halbebene modellieren. x ist dabei die Position auf der linearen Strecke zwischen den Endpunkten, y die Seitenlänge des Viewports
Ich habe an zwei Metriken gedacht, die auf dasselbe hinauslaufen. Zuerst nimmt man eine hierarchische Tile-Map an und minimiert die Zahl der geladenen Tiles. Wenn y die Seitenlänge des Viewports ist, kostet eine horizontale Bewegung um x genau x/y Tiles, und ein Hinein- oder Herauszoomen von y_0 auf y_1 lädt abs(log_2(y_1/y_0)) Tiles, was ds = dy/y entspricht. Zusammengenommen ergibt das ds^2 = (dx^2 + dy^2)/y^2, also genau die Metrik der oberen Halbebene
Eine andere Sichtweise ist, den „optischen Fluss“ des Viewports in einem gewissen Sinn zu minimieren. Auch das ergibt bis auf einen Skalierungsfaktor dieselbe Metrik. Wenn man ohne Zoom um x schwenkt, bewegt sich alles um x/y, also um den Anteil relativ zum Viewport. Zoomt man um den Faktor k, wandern Pixel bei (u,v) nach (ku,kv), die Verschiebung ist also (u,v)(k-1). Wenn die Seitenlänge von y auf y+dy geht, wird daraus (u,v)dy/y, also je nachdem, wie man die Verschiebung mittelt, ein konstanter Faktor mal dy/y
Die gewünschte Geodäte ist dann ein Horozykel, also ein Kreis mit Mittelpunkt auf y=0, aber die Bewegung entlang der Kurve zu berechnen erfordert etwas Arbeit. Nimmt man den Bogen von θ_0 bis θ_1, ergibt sich die Gesamtzeit aus dem Integral von dtheta/y = dθ/sin(θ); exakt müsste man also t = ln(csc(θ)-cot(θ)) invertieren. Ich dachte, eine Näherung wäre besser, aber Mathematica sagt, dass θ = atan2(1-2e^(2t), 2e^t) gilt, also ist es gar nicht so schlimm
Verglichen mit der „blub space“-Logik scheint deren effektive Metrik ds^2 = dz^2 + (z+1)^2 dx^2 zu sein. Das sind Polarkoordinaten mit z=1/y als Zoomstufe; mit dz=dy/y^2 erhält man ds^2 = dy^2/y^4 + dx^2*(1/y^2 + ...). Das heißt, die bestehende Implementierung verbringt bei hohen Zoomstufen offenbar viel mehr Zeit mit Panning als das hyperbolische Modell. Denn die Kosten, von 4-fach auf 2-fach zu reduzieren, sind doppelt so hoch wie von 2-fach auf 1-fach, obwohl es visuell gleich wirkt
Ihr
zoomist kein Skalierungsfaktor, sondern entspricht meinem „y“, daher lautet die Metrik ds^2 = dy^2 + (C-y)^2 dx^2. Dabei ist C etwas größer als die maximale Zoomstufe. Es gibt auch eine Spezialbehandlung für den Fall, dass diese Kurve noch weiter herauszoomen willWenn man so normalisiert, dass die Kosten fürs Panning bis ganz ans Ende im vollständig herausgezoomten Zustand (zoom=1) gleich sind, dann sind die Panning-Kosten bei sehr tiefem Hineinzoomen fast flach, während sie bei relativ weniger starkem Hineinzoomen höher sind als im hyperbolischen Modell. Das trägt wohl dazu bei, dass sich kurze Distanzen so anfühlen, als würde sich der Viewport sehr schnell bewegen, während lange Distanzen so aussehen, als würde fast bis zum Ende herausgezoomt. Mittlere Zoomstufen sind benachteiligt, also ist es besser, fast ganz herauszugehen