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 thereset()
method) will not delete expressions unless theShift
key is held (ortrue
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