Produktive Tage
KW42Fokusstunden pro Wochentag, aus Kalender- und Editor-Aktivität. Der Ball markiert den Tag, auf den du zeigst.
Showcase · Three.js · WebGPU · TSL
Drei Kennzahl-Karten, gezeichnet wie technische Zeichnungen. Fahr mit der Maus über eine Karte und zeig auf einen Balken, ein Tortenstück oder eine Stunde. Ein Klick klappt die Zeichnung zu einem lesbaren Diagramm auf. Alles wird live in deinem Browser gerendert.
Fokusstunden pro Wochentag, aus Kalender- und Editor-Aktivität. Der Ball markiert den Tag, auf den du zeigst.
Anteil der Monatsausgaben nach Kategorie. Essen gehen ist gegenüber September um 18 % gestiegen.
Sitzungen pro Tagesstunde. Die Strichlänge zeigt die Aktivität, das Licht ruht auf der stärksten Zeit.
Mit der Maus über die Karten · Klick macht sie flach
Showcase · Three.js · WebGPU · TSL
Isometric Data Cards sind drei interaktive Kennzahl-Karten für ein Dashboard oder eine Landingpage. Jede Karte zeigt eine isometrische Strichzeichnung ihrer Daten: ein 3D-Balkendiagramm, ein 3D-Kreisdiagramm und einen Leuchtturm auf einem 24-Stunden-Zifferblatt. Linien, die hinter einem Körper liegen, sind gestrichelt, wie in einer technischen Zeichnung.
Die Bewegung trägt Bedeutung statt Dekoration. Ein Markierungsball springt auf den Balken, auf den du zeigst, ein Tortenstück gleitet zum Ablesen heraus, der Leuchtturm beleuchtet die Stunde unter deinem Mauszeiger. Ein Klick klappt die Zeichnung zu einem normalen Diagramm mit Achsen und Werten auf. Verspielte und präzise Ansicht sind dasselbe Objekt.
Die drei Karten
Jede Karte beantwortet eine Frage, und jede Animation zeigt die Antwort, statt sie zu schmücken.
Sieben Balken für sieben Wochentage. Die Balken bewegen sich nie, denn sie sind die Daten. Ein oranger Ball liegt auf dem Spitzentag. Zeigst du auf einen anderen Tag, springt er im Bogen hinüber, landet mit einer Stauchung und einem kleinen Rückprall, und die Oberseite des Balkens leuchtet auf.
Technik: Der Ball ist simuliert: Schwerkraft, eine Absprunggeschwindigkeit, die die Balken dazwischen überwindet, Rückprall beim Landen und eine gedämpfte Stauch-Feder. Er wirft weiches oranges Licht auf den Balken unter sich.
Fünf Stücke, eins pro Kategorie. Das Stück unter dem Mauszeiger wird orange und gleitet ein Stück aus der Torte, sein Licht fällt auf eine gepunktete Bodenfläche. Im Ruhezustand hebt die Karte die Kategorie mit der größten Veränderung hervor.
Technik: Die Stücke sind extrudierte Kreissektoren. Ihre gewölbten Wände bekommen pro Frame berechnete Silhouettenlinien, damit der Umriss aus jedem Winkel und während des Flachklappens stimmt.
Ein 24-Stunden-Zifferblatt, auf dem die Strichlänge die Aktivität zeigt. Der Leuchtturm wirft einen Lichtkegel auf das Zifferblatt: im Ruhezustand über die stärkste Zeit, beim Hover auf die Stunde, auf die du zeigst, mit ihrem Anteil an der Spitze.
Technik: Das Licht ist ein Kegel, der pro Frame von der Lampe zu einem Punkt auf dem Zifferblatt gespannt wird, mit einem Lichtfleck, wo er auftrifft. Die Stunde ergibt sich daraus, wo der Zeigerstrahl die Ebene des Zifferblatts trifft.
So ist es gebaut
Die Zeichnungen nutzen den Three.js-WebGPURenderer und TSL, die Three.js Shading Language. Eine orthografische Kamera in CSS-Pixeln deckt die Seite ab. So sitzt jedes Diagramm genau auf seiner HTML-Karte und kann sie trotzdem verlassen.
Jede Kante wird zweimal gezeichnet. Der zweite Durchgang zeichnet nur dort, wo der Tiefentest die Kante als verdeckt erkennt, und zwar gestrichelt. Unsichtbare Körper, einen halben Pixel kleiner, übernehmen das Verdecken.
// Every solid is drawn as its edges, twice.
// In front: solid lines. Behind something: dashed.
const front = new Line2NodeMaterial({ linewidth: 1.25 })
const behind = new Line2NodeMaterial({
linewidth: 1, dashed: true, dashSize: 3, gapSize: 3.5,
depthFunc: THREE.GreaterDepth, // only where hidden
})
// Depth-only solids, a hair smaller, hide the edges behind them.
const solid = new MeshBasicNodeMaterial({ colorWrite: false })Ein Zylinder hat entlang seiner Wand keine Kanten, ein Tortenstück oder der Leuchtturm würde seinen Umriss verlieren. Pro Frame werden zwei Silhouettenlinien dort gesetzt, wo sich die Wand vom Betrachter abwendet.
// Curved walls have no edges: find where the wall turns away.
// n(a) · view = 0 -> A cos a + B sin a = C
const d = viewDir.transformDirection(inverseWorldMatrix)
const k = (r0 - r1) / (y1 - y0) // taper of the cone
const phi = Math.atan2(-d.z, d.x)
const delta = Math.acos(-k * d.y / Math.hypot(d.x, d.z))
const silhouettes = [phi + delta, phi - delta]Der Markierungsball ist nicht animiert, sondern simuliert. Er springt mit einer Geschwindigkeit, die jeden Balken auf dem Weg überwindet, lässt sich in der Luft umlenken, wenn du es dir anders überlegst, und verliert bei jedem Aufprall Energie.
// Hop to the next bar: an arc that clears everything between.
const jump = (lift: number) => {
ball.vy = Math.sqrt(2 * G * (clearance() + lift - ball.y))
const t = (ball.vy + Math.sqrt(ball.vy ** 2 + 2 * G * (ball.y - landY))) / G
ball.vx = (targetX - ball.x) / t
}
// On touch-down: squash by impact speed, bounce with less energy.
if (ball.y <= landY) ball.vy = impact > 120 ? impact * 0.42 : 0Raycasting auf Balken oder Tortenstücke versagt, sobald sie sich bewegen. Stattdessen wird der Zeigerstrahl mit einer Ebene im Koordinatensystem des Diagramms geschnitten. Die Position auf dieser Ebene bestimmt Tag, Kategorie oder Stunde.
// Pick by column, not by mesh: intersect the pointer ray
// with the vertical plane through the bars.
inverse.copy(chart.matrixWorld).invert()
ray.copy(raycaster.ray).applyMatrix4(inverse)
if (ray.intersectPlane(barPlane, hit)) {
active = Math.round((hit.x - firstBarX) / STEP)
}Beim Klick wächst die Karte in die Bildschirmmitte, während sich die Zeichnung in eine gerade Ansicht dreht und ihre Tiefe flachgedrückt wird. Achsenbeschriftungen und Werte blenden am Ende der Bewegung als HTML ein.
// Isometric -> flat: rotate to a straight view and
// press the depth axis flat, in one eased motion.
q.slerpQuaternions(Q_ISO, chart.qFlat, eased)
chart.root.quaternion.copy(q)
chart.root.scale[chart.collapse] = scale * lerp(1, 0.02, eased)Interaktion
Jede Reaktion beantwortet eine Frage zu den Daten. Wer mit den Karten spielt, liest sie gleichzeitig.
Die Karte unter dem Mauszeiger wechselt von dunkel zu creme, und ihre Strichzeichnung wechselt die Tinte, im Gleichtakt mit dem 3D.
Balken, Stück oder Stunde unter dem Mauszeiger werden aktiv, ihr Wert erscheint daneben und in der Fußzeile der Karte.
Die Zeichnung klappt zu einem 2D-Diagramm mit Achsen und Werten auf. Erneut klicken, Escape drücken oder daneben klicken klappt sie zurück.
Die Karten sind fokussierbar und öffnen sich mit Enter oder Leertaste. Jede Karte trägt eine Textbeschreibung ihres Diagramms.
Performance
Drei Diagramme sollten keinen Laptop-Lüfter anwerfen. Diese Entscheidungen halten die Karten sparsam.
Alle Zeichnungen teilen sich einen Renderer und eine Kamera in CSS-Pixeln und werden jeden Frame auf die HTML-Karten gelegt.
Die Engine lädt, wenn der Bereich in die Nähe kommt, und hört auf zu zeichnen, sobald er außerhalb des Bildschirms ist und alle Karten an ihrem Platz sind.
Titel, Werte, Achsen und Fußzeilen sind HTML: lesbar für Suchmaschinen und Screenreader und scharf bei jedem Zoom.
Der WebGPURenderer nutzt WebGPU, wo es verfügbar ist, und sonst WebGL 2. Derselbe TSL-Code läuft auf beiden.
Für dein Produkt
Dieselben Bausteine funktionieren mit deinen eigenen Zahlen:
Kennzahl-Karten, die eine Metrik auf einen Blick erklären und sich zu einem präzisen Diagramm öffnen.
Wochenberichte und Jahresrückblicke, die Menschen wirklich erkunden.
Zeig, was dein Produkt misst, mit lebendigen Diagrammen statt Screenshots.
Ausgaben und Sparziele mit Stücken und Balken, die auf Berührung reagieren.
Serien, stärkste Tage und beste Uhrzeiten als kleine Objekte.
Isometrische Szenen für redaktionelle Seiten, Geschäftsberichte und Pitch-Decks im Web.
Ich setze genau dein Briefing um: deine Daten, deine Farben, die Diagrammtypen, die du brauchst, in reinem Three.js oder in React und Next.js. Du bekommst sauberen, dokumentierten Code, der auch auf dem Handy funktioniert.
TypeScript-, React- & Next.js-EntwicklungEin isometrisches Diagramm zeichnet Daten als 3D-Objekte aus einem festen Winkel ohne Perspektive. Parallele Linien bleiben parallel und Größen vergleichbar. Es wirkt wie eine technische Zeichnung und lässt sich leichter ablesen als ein perspektivisches 3D-Diagramm.
Perspektivische 3D-Diagramme verzerren Werte. Diese Karten nutzen die isometrische Ansicht für den Überblick und klappen per Klick zu einem normalen flachen Diagramm mit exakten Werten auf. Hinter dem Effekt geht nichts verloren.
Ja. Jedes Diagramm nimmt einfache Listen aus Zahlen und Beschriftungen. Live-Daten aus einer API oder Datenbank funktionieren genauso.
Ja. Die Engine ist eine framework-unabhängige TypeScript-Klasse, die eine kleine Client-Komponente startet und wieder aufräumt. Diese Seite ist selbst eine Next.js-Seite.
Nicht, wenn er so gebaut ist. Alle Texte sind serverseitig gerendertes HTML. Die Engine lädt erst, wenn der Bereich in die Nähe kommt, und zeichnet nicht, solange er nicht sichtbar ist.
Mein Stundensatz liegt bei 75 USD. Der Aufwand hängt von der Anzahl der Diagramme, den Interaktionen und der Einbindung in dein Produkt ab. Umfang und Schätzung vereinbaren wir, bevor ich anfange.
Erzähl mir, was du zeigen willst, wo es eingebunden wird und welchen Zeitrahmen du hast. Ich antworte mit Rückfragen oder einer ersten Schätzung.
Design-Inspiration: die interaktiven isometrischen Datenkarten von Zsolt Kacso. Diese Version wurde von Grund auf mit Three.js, WebGPU und TSL neu gebaut. Original-Post auf X