6: Internals
internals.Rmd
{blockr} structure
Under the hood, blockr utilises S3 to creates classes and apply the relevant methods whenever necessary. We describe the general idea below.
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():
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.
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.
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:
- Under
./R/field.R, create a newnew_*_fieldand*_fieldfunctions,*being the field name. - Under
./R/field.R, add a specific validation methodvalidate_field.*_field. - Under
./R/ui.R, addui_input.*_fieldandui_update.*_fieldto 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:
- Add a
server_output.*_blockmethod,*being the new block name. - Add a specific
generate_server.*_block.
If you had to include new fields, refer to the previous section.