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_*_field
and*_field
functions,*
being the field name. - Under
./R/field.R
, add a specific validation methodvalidate_field.*_field
. - Under
./R/ui.R
, addui_input.*_field
andui_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
:
- Add a
server_output.*_block
method,*
being the new block name. - Add a specific
generate_server.*_block
.
If you had to include new fields, refer to the previous section.