Skip to contents

{blockr} structure

Under the hood, blockr utilises S3 to creates classes and apply the relevant methods whenever necessary. We describe the general idea below.

Workspace

TBD

Stack

The stack is a list of blocks.

The stack is able to dynamically add new blocks through add_block().

Modify a stack

To add a block to a stack, you can leverage add_block():

stack <- new_stack(dataset_block) |>
  add_block(select_block) |>
  add_block(filter_block, 1)

If you specify the position (last parameter), you can add a block right after the given index. For instance, the above command first inserts a select block after the data block. Then, a filter block is included right after the data block.

Note that you can’t add a block before the data block and before the plot block. In a later version, we may add multiple plots per stack.

Moving blocks

TBD

Blocks

A block is a structure carrying various information:

  • The class: blockr leverages S3, so the class is important to apply the right methods. For instance, data block, tranform and output blocks have different methods (generate_server.data_block, …, respectively).
  • expr: is the expression which will be evaluated to produce the block result.
  • result: the block output which can be passed to another block.

A block is composed of fields gathered in a list, which are translated into Shiny inputs. These fields are the necessary elements to reconstruct the block expression and subsequently produce the result whenever it gets evaluated.

Fields

Simple fields

A field is a structure with a type and a class.

The validate_field generic ensures each field has revelant values. For instance, for a string field, which ultimately becomes a shiny text input, the method validate_field.string_field is responsible for checking that the value is a character string and modifies it if not.

More complex fields

TBD

Validation and evaluation

That’s currently how {blockr} validate blocks and fields. Each block is validated, meaning that each field that compose it should have valid values according to the input data. Only when everything is valid, the block expression is evaluated and the result computed and passed to the next block. Any error is catched by R and forwarded to JavaScript so that users are notified about what went wrong and where.

Adding new fields

Fields are translated into shiny inputs. For instance, the select_field surprinsingly yields a shiny selectInput. It is quite easy to add a new field:

  1. Under ./R/field.R, create a new new_*_field and *_field functions, * being the field name.
  2. Under ./R/field.R, add a specific validation method validate_field.*_field.
  3. Under ./R/ui.R, add ui_input.*_field and ui_update.*_field to create the corresponding HTML element for Shiny.

Create a new block

You may find yourself in a situation where the set of existing blocks does not fully meet your needs. We exposed few helpers so you can quickly get started creating new block. You can call create_block choosing between transform or plot block. This creates a new block file in R/<name>-block.R.

If your block has specific output, you may need to tweak ./R/server.R:

  1. Add a server_output.*_block method, * being the new block name.
  2. Add a specific generate_server.*_block.

If you had to include new fields, refer to the previous section.