Skip to main content

Expression Columns

Perspective supports expression columns, which are virtual columns calculated as part of the View, optionally using values from its underlying Table's columns. Such expression columns are defined in Perspective's expression language, an extended version of ExprTK, which is itself quite similar (in design and features) to expressions in Excel.

UI

Expression columns can be created in <perspective-viewer> by clicking the "New Column" button at the bottom of the column list (in red below), or via the API by adding the expression to the expressions config key when calling restore().


By default, such expression columns are not "used", and will appear above the Table's other deselected columns in the column list, with an additional set of buttons for:

  • Editing the column's expression. Doing so will update the definitions of all usage of the expression column.
  • Deleting the column. Clicking Reset (or calling the reset() method) will not delete expressions unless the Shift key is held (or true parameter supplied, respectively). This button only appears if the expression column i unused.

To use the column, just drag/select the column as you would a normal column, e.g. as a "Filter", "Group By", etc. Expression columns cannot be edited or updated (as they exist on the View() and are generated from the Table()'s real columns). However, they will automatically update whenever their dependent columns update.

Perspective Extensions to ExprTK

ExprTK has its own excellent documentation which covers the core langauge in depth, which is an excellent place to start in learning the basics. In addition to these features, Perspective adds a few of its own custom extensions and syntax.

Static Typing

In addition to float values which ExprTK supports natively, Perspective's expression language also supports Perspective's other types date, datetime, integer, boolean; as well as rudimentary type-checking, which will report an

error when the values/columns supplied as arguments cannot be resolved to the expected type, e.g. `length(x)` expects an argument `x` of type `string` and is not a valid expression for an `x` of another type. Perspective supplies a set of _cast_ functions for converting between types where possible e.g. `string(x)` to cast a variable `x` to a `string`.

Expression Column Name

Expressions can be named by providing a comment as the first line of the expression. This name will be used in the <perspective-viewer> UI when referring to the column, but will also be used in the API when specifying e.g. group_by or order_by fields. When creating a new column via <oerspective-viewer>'s expression editor, new columns will get a default name (which you may delete or change):

// New Column 1

Without such a comment, an expression will show up in the <perspective-viewer> API and UI as itself (clipped to a reasonable length for the latter).

Referencing Table() Columns

Columns from the Table() can be referenced in an expression with double quotes.

// Expected Sales
("Sales" * 10) + "Profit"

String Literals

In contrast to standard ExprTK, string literals are declared with single quotes:

// Profitable
if ("Profit" > 0) {
'Stonks'
} else {
'Not Stonks'
}

Extended Library

Perspective adds many of its own functions in addition to ExprTK's standard ones, including common functions for datetime and string types such as substring(), bucket(), day_of_week(), etc. A full list of available functions is available in the Expression Columns API.

Examples

Casting

Just 2, as an integer (numeric literals currently default to float unless cast).

integer(2)

Variables

// My Column Name
var incrementedBy200 := "Sales" + 200;
var half := incrementedBy200 / 2;
half

// Complex Expression
var upperCustomer := upper("Customer Name");
var separator := concat(upperCustomer, ' | ');
var profitRatio := floor(percent_of("Profit", "Sales")); // Remove trailing decimal.
var combined := concat(separator, string(profitRatio));
var percentDisplay := concat(combined, '%');
percentDisplay

Conditionals

// Conditional
var priceAdjustmentDate := date(2016, 6, 18);
var finalPrice := "Sales" - "Discount";
var additionalModifier := 0;

if("Order Date" > priceAdjustmentDate) {
finalPrice -= 5;
additionalModifier -= 2;
}
else
finalPrice += 5;

finalPrice + additionalModifier