Interactivity

Envision is mostly aimed at long-running batch processing executed on dedicated servers, and dashboards are mostly static data output from those runs. Dashboards come out of the box with standard interactivity features: tables can be filtered, charts allow hovering to view individual data points, tooltips are shown on mouse-over, etc.

For going beyond standard interactivity, Envision provides a small subset of reactive programming to describe operations that should be performed while the dashboard is being displayed, and based on the viewer’s input. Such operations are introduced by the dash keyword.

Table of contents

The execution of the Envision script is cut into two consecutive phases:

The following example displays a table with an editable column T.Value, and paints every line in red if T.Value is not between T.Min and T.Max.

read upload "values" as Submitted with 
  Id : text
  Value : number
  Comment : text

table Values = with 
  [| "A" as Id, 1 as Min, 5 as Max |]
  [| "B"      , 0       , 10       |]
  [| "C"      , -5,     , 5        |]

Values.Comment = single(Submitted.Comment) by Submitted.Id at Values.Id

mutable Values.Value = single(Submitted.Value) by Submitted.Id at Values.Id

dash Values.IsValid = Values.Min <= Values.Value and Values.Value <= Values.Max

dash Values.Color = if Values.IsValid then "default" else "red"

show table "Values" editable: "values" { .., ..10 } with 
  Values.Id { columnReadOnly: true }
  mutable Values.Value { cellBackground: #[Values.Color] }
  Values.Min { columnReadOnly: true }
  Values.Max { columnReadOnly: true }
  Values.Comment 

Dash variables and dash expressions

An assignment dash Table.Variable = ... creates a dash variable. Its value is always computed in the reactive phase, and therefore it will not be available during the processing phase.

Expressions which contain dash variables are called dash expressions, and are also always computed in the reactive phase.

Attempting to use a dash variable or a dash expression for a non-dashboard operation will be rejected by the Envision compiler with an error message:

table T = extend.range(10)

dash T.M = T.N * 2

// Error: Cannot use dash variable 'T.M' in a non-dash assignment
T.Bad = T.M + 1 

write T as "file.csv" with 
  T.N
  // Error: Cannot use dash variable 'T.M' in a 'write' statement
  T.M 

Always-supported types and operations

Dash variables and dash expressions can only be of following types: number, boolean, text, date, week, month, markdown, and all enum types. Tuples are also supported.

The following operations are always allowed in dash expressions:

Please note that a dash variable written before a where is usually not allowed to be read inside that where! The only exception here is when the variable belongs to a table that is tiny.

Using dash expressions

As mentioned above, many code locations forbid the use dash variables or dash expressions. This is the most common case, and includes write statements, where conditions, for loops, and assignments without the dash keyword. An error is reported when attempting to use a dash variable in such a location.

// Error: Cannot use dash variable 'T.M' in a non-dash assignment.
T.Bad = T.M + 1 

Conversely, assignment statements with the dash keyword require a dash expression. An error is reported if the expression contains an operation or type that is not allowed in a dash expression.

read "/forecasts.ion" as Forecasts with 
  Demand : ranvar

// Error: This operation is not supported in a dash expression.
dash Forecasts.Mean = mean(Forecasts.Demand)

Finally, a third category allows both dash expressions and non-dash expressions; those are the expressions that are intended to be displayed in the dashboard:

The rule is that if such an expression contains at least one dash variable, then it will be expected to be a dash expression, and if it contains no dash variable, then it will be expected to be a non-dash expression.

Dash-mutable variables

An assignment mutable Table.Variable = ... creates a dash-mutable variable. These are the fundamental tool for implementing interactivity, since their value can be changed by the dashboard’s viewer. Dash-mutable variables can be used like normal dash-variables, but when the value of a dash-mutable variable is changed, the dashboard automatically re-computes all values that depend on that variable.

The assignment is used to provide the initial value of the variable. It is not, and cannot be, a dash assignment: the initial value must always computed during the processing phase.

Going back to the above example:

mutable Values.Value = single(Submitted.Value) by Submitted.Id at Values.Id

dash Values.IsValid = Values.Min <= Values.Value and Values.Value <= Values.Max

dash Values.Color = if Values.IsValid then "default" else "red"

show table "Values" editable: "values" { .., ..10 } with 
  Values.Id { columnReadOnly: true }
  mutable Values.Value { cellBackground: #[Values.Color] }
  Values.Min { columnReadOnly: true }
  Values.Max { columnReadOnly: true }
  Values.Comment 

Here, Values.Value is created as a dash-mutable variable, initialized with the output of the single(Submitted.Value) aggregation.

From Values.Value, the Values.IsValid boolean dash variable is created, and from there, the Values.Color text dash variable.

The show table statement uses:

The mutable annotation tells Envision that any changes applied to the editable column should also be applied to the dash-mutable variable. If the annotation is not present, the column is still editable (consider the Values.Comment column, which is editable despite the lack of annotation), but the edits are not applied to the dash-mutable variable.

When a dash-mutable variable is defined in a script, Envision will check that there is at least one use of that variable with the mutable annotation.

If there are several uses with the mutable annotation, then all those uses become linked together, and changes applied in one location are applied to all locations automatically.

Mutable contexts

The mutable annotation can be used in specific locations, called write contexts. The previous example illustrated that a column of a show table with the editable: option is a write context, but there are others.

A column of a show form is a write context:

table T = extend.range(10)

mutable Min = 0
mutable Max = 10

show form "Bounds" { ..3, ..5 } with 
  mutable Min
  mutable Max

dash T.IsValid = Min <= T.N and T.N <= Max

show table "Values" { 4.., ..10 } with 
  T.N { cellBackground: #[if T.IsValid then "default" else "red"] }

Note that Envision will not report an error even though there is no read form matching the Min and Max fields of the show form. The reason for reporting this error in the first place is because it is unlikely for a show form to let the viewer edit fields that will never be submitted or used—it is instead far more likely that the script author made an error and forgot to include or use those fields. However, if those fields are annotated as mutable, that is a good indication that the script author did not make an error, and truly intended those fields to be used only to improve the dashboard interactivity.

Advanced topics

Sliced assignments

The Slices table cannot contain dash variables, since by definition it is not present in the dashboard—the dashboard instead views the data one slice at a time.

Assigning a value in Slices (or a cross-table of Slices) to a dash variable causes the assignment to be performed separately on every slice.

dash X = Slices.X

The assigned expression is expected to be in the Slices table, and the assigned variable must be a scalar. The value of X will be equal to the value of Slices.X for the slice currently being displayed (and therefore, it can be different on every slice).

Markdown

Envision supports Markdown columns based on interpolation:

T.ToolTip = """
This column can only contain values between 0 and \{T.Max}.
"""

To avoid using vast amounts of storage for the markdown column T.ToolTip, Envision stores it in a format where the constant portions of the Markdown are de-duplicated across all lines of the table. When displaying the Markdown value in the web browser, the actual contents are reconstituted from this compressed format.

While this is technically done in the browser, it does not count as part of the interactive phase—it is conceptually closer to how displaying a numeric value on a dashboard will take a number stored in an IEEE754 32-bit floating-point format and turn it into text that can be displayed.

As such, T.ToolTip does not need to be a dash variable, and the above assignment does not require a dash annotation. The restrictions on T.ToolTip are also lighter than for dash variables: it can be used inside a where, or broadcast from one table to another, even if the tables involved are not tiny.

However, if any of the variables involved in the interpolation are dash-variables, then the normal rules for dash-variables apply: the assignment must be annotated with dash, the resulting Markdown variable must be a dash variable, and will be subject to all the standard restrictions of dash variables.

In the example below, the value of T.ToolTip uses the dash variable T.FuzzMax, and so T.ToolTip must be assigned with a dash annotation and becomes a dash variable itself.

mutable FuzzFactor = 1.5
dash T.FuzzMax = floor(T.Max * FuzzFactor)

dash T.ToolTip = """
This column can only contain values between 0 and \{T.FuzzMax}.
"""
User Contributed Notes
0 notes + add a note