Data buffers are in-memory data structures designed to hold a card's tabular data.
Data buffers make it convenient to separate data (what is displayed) from presentation (how it is displayed). You can declare a card once, and update its underlying data buffer multiple times. A card can hold zero or more data buffers.
Cards and buffers
Data buffers are tabular data structures containing columns and rows. Different cards utilize data buffers in different ways. For example, the plot in the ui.small_series_stat_card() uses a data buffer called
plot_data to hold time series data.
In the above snippet,
data('time usage', -15) defines a placeholder for a table with two columns (
usage) and 15 rows (we'll get to why the
15 is negative shortly), and the card's
plot_value point to the two columns
Appending rows (tuples or records) to the data buffer make the card plot those rows.
while loop above does something like this:
Types of buffers
There are three types of data buffers:
- Array buffers hold tabular data with a fixed number of rows, and allow random access to rows using 0-based integers as keys.
- Cyclic buffers also hold tabular data with a fixed number of rows, but do not allow random access to rows. They can only be appended to. Rows are first-in first-out (FIFO), and adding rows beyond its capacity overwrites the oldest rows.
- Map buffers (or dictionary buffers) hold tabular data with a variable number of rows, and allow random access to rows using string keys.
Map buffers are convenient to use, but use more memory on the server compared to array buffers and cyclic buffers, so use them sparingly.
The data function
data() function to declare a data buffer. The Wave server uses this declaration to allocate memory for the data buffer.
data() takes multiple arguments:
fields: The names of columns, in order; a space-separated string or a list or a tuple (
size: The number of rows to allocate.
- A positive row count creates an array buffer.
- A negative row count creates a cyclic buffer.
- A zero row count (or
None) creates a map buffer.
listof rows to initialize the data buffer with. Each row can be a list or tuple.
- For array or cyclic buffers, pass a list of rows.
- For map buffers, pass a dict with strings as keys and rows as values.
listof columns to initialize the data buffer with. All columns must be of the same length. The columns are automatically transposed to
Trueto pack (compress) the provided rows or columns, use less memory on the server-side, and improve performance. Set
pack=Trueif you intend to never make any changes to the data buffer once created. Defaults to
Buffers in practice
Declare a 5-row buffer with columns
Declare and initialize a 5-row buffer with columns
Modify a buffer row:
Modify a buffer value:
If you intend to create tabular data once and never change individual rows or values, it is better to avoid allocating memory on the server by using a packed buffer. Packed buffers use less memory on the server and improve performance. To create a packed buffer, use
data(..., pack=True). Note that
size is not required, and is ignored if provided.