KanuniLabs Blog
Notes from building two data grids
Measurements, mistakes and the reasoning behind them — from building the KanuniLabs DataGrid and PivotGrid.
All posts
Guides
Cell, batch, row, form or popup: five ways to edit a table in React, all in the free grid
An editable table can save each cell as it is typed, collect changes and save them together, or open a whole record as a row, a form or a dialog. What each mode hands your app, which screen it suits, and the one line every mode but the first needs. Shown on 240 real order lines with a free React data grid.
6 min readGuides
Server-side sorting and filtering for a React data grid, and five places your SQL quietly disagrees
A grid on a million rows in PostgreSQL asks the server for 100 rows at a time. The usual hand-written endpoint shows lines twice, drops 243,007 rows from a "not equal" filter and finds nothing for "heart". Measured on 1,067,371 real invoice lines, with the indexes that make the correct version fast.
11 min readGuides
How to build a sales report your users can rearrange, with a React pivot table
Top countries and their best sellers, with units, average price and share of the year, built from 1,067,371 real invoice lines with a free React pivot table. What each field option does, two numbers that look right and are not, and what clicking a cell costs.
9 min readGuides
A pivot table your users can drag, on a million rows, and how to tell whether it freezes the page
Letting users build their own reports means aggregating every row on each drag. Measured on 1,067,371 real invoice lines, in the browser: what a Web Worker buys, what a plain loop costs, and a sort that froze the page for half a second until we fixed it.
7 min readGuides
Three ways an Excel export stops matching the screen, measured on a million rows
An Export button is easy. A file that says what the screen said is not. We exported 1,067,371 real invoice lines and opened them in Excel: dates arrived as text, subtotals vanished, and 18,843 rows past the sheet limit were silently cut.
7 min readGuides
Select all in a million filtered rows, and send the server one line instead of a list
Ticking the header checkbox on a filtered million-row table is one click. What "all" means, what getSelectedRows returns, and what you send to the server are the actual work. Measured on 1,067,371 real invoice lines.
7 min readGuides
The hard part of an editable table is knowing what changed
Putting an input in a cell is easy. Knowing which cells changed, refusing a bad value where it is typed, taking an edit back, sending only what changed and losing nothing when the server says no is the actual work.
6 min readGuides
How to find cancellations in a million invoice lines
The obvious filter, quantity below zero, gets the money right and more than doubles the returned units. A walk through 1,067,371 real invoice lines in a React grid and pivot, and the filter that matches the data.
6 min readGuides
How to build a sales dashboard on a million real rows in React
A grid, a pivot and a chart over 1,067,371 transactions from a real UK online retailer. The data goes to the browser once, and every sort, search and pivot after that runs there.
8 min readGuides
Copy-paste that behaves like Excel — and where it doesn't
Excel-like editing can mean anything from a rectangle you can drag to a fill handle that continues a series. Here is what our grid actually does with a drag, a fill handle and a clipboard — and the specific places the comparison to Excel breaks down.
6 min readEngineering
What a data grid renders before it hydrates
When an install guide makes ssr false a required step, it is worth asking what the component touches on the server. Here is what actually has to happen before a grid can render there, and what changes after hydration.
6 min readPerformance
Where client-side sorting and filtering stop working
A Web Worker gets you a million interactive rows in the browser. It does not get you a dataset bigger than a browser tab, or one where a user is only allowed to see some of the rows. That is a different problem with a different contract.
7 min readPerformance
What actually blocks the main thread in a data grid
Virtualization fixes rendering. It does nothing for the 18 ms to 1.8 s a sort, filter or search still costs — and if that work runs on the interaction thread, the tab freezes regardless of how few rows you draw.
5 min readEngineering
Why your popup disappears in fullscreen
A menu that opens, receives events, has a real bounding box, and is invisible. The top layer explains it, z-index cannot fix it, and the obvious fix uncovered a worse bug underneath.
6 min readEngineering
How we embedded a Web Worker in an npm package
Shipping a worker used to mean asking every user to copy a file into public/. We compiled it into the bundle instead. Here is the technique, the cost we measured, and the two ways it can quietly break.
4 min readGuides
How to choose a React data grid
Feature checklists all look the same. These are the eight questions that actually separate grids once you are six months into a project — and how to test each one in an afternoon.
5 min readPerformance
Virtual scrolling a million rows — where it actually breaks
Rendering 24 rows instead of a million is the easy part. The hard part is that browsers refuse to make an element as tall as you asked, and they do not tell you.
5 min readLicensing
Why a licence key is not a secret
Our licence keys ship in client bundles, and that is fine. Here is what they actually are, what they can and cannot protect, and why pretending otherwise makes products worse.
4 min read