Slicing is a mechanism to compute many variants of the same dashboard and let end-users interact with the resulting sliced dashboard through a search-like navigation. For example, through slicing, it is possible to create a product inspector which consolidates - for every product - all the KPIs and linecharts of interest.
The following script provides a simplistic variant of such a dashboard:
table Products[Pid] = with [| as Product, as Color, as Price |] [| "pants", "blue", 25 |] [| "shirt", "white", 15 |] [| "socks", "green", 5|] Products.Slice = sliceDashboard(Products.Product) by Pid show table "My Products" a1c3 slices: Slice with Products.Product Products.Color Products.Price
In the above script, the function
sliceDashboard() takes one argument
Product.Product and one option
Pid. The argument is the name of the slice. Slice names become part of the dashboard user interface, as the slice selector offers the possibility to select slices displayed through their names. The option is the group of the slice, in a process highly similar to the group tables detailed in a previous section. Finally, the
table tile gets sliced through the tile option
slices: Slice. Note that we are referencing
Slice instead of
Products.Slice. The latter would have been acceptable as well, however as
Slice is a dimension, it does not actually need to be prefixed - except the first time, when calling
Slicing is a mechanism that impacts only tiles and only when specified at the tile level. When a tile is sliced, its input table (found as the common table among all its input vectors) gets partitioned across every single slice. The resulting tile is computed separately for each slice. Finally, the slice selector allows you to pick which slice gets displayed in the dashboard itself.
sliceDashboard() can be called at most once in an Envision script.
by behaves like it does for any aggregator, the only limitation being that the number of slices is limited to 200,000. In particular, it is possible to use multiple vectors through the usual syntax
by [expr1, expr2, expr3].
It is recommended to have the return variable named
Slice. No matter how the returned dimension is named after the call to
sliceDashboard() a table named
Slices, which has
Slice as a dimension, becomes accessible.
Roadmap: The variable returned by
sliceDashboard() is a dimension, associated to the implicitly named
Slices table. A syntax like
table Slices[Slice] = sliceDashboard(foo) by bar, which clarifies both the nature of
Slice (a dimension) and its associated table (
Slices), would be better and will most likely be introduced in the future. The guideline concerning the
Slice name will make the future automated code rewrite less impacting.
sliceDashboard() accepts a second argument to specify a label (the first argument is the name, see above). The label can be used to enrich the slice selector as illustrated by:
table Products = with [| as Product, as Color, as Price |] [| "pants", "blue", 25 |] [| "shirt", "pink", 15 |] [| "shirt", "white", 15 |] [| "socks", "green", 5|] Products.Slice = sliceDashboard(\ Products.Product,\ join(Products.Color; ", ") by Products.Product sort Products.Color) by Products.Product show table "My Products" a1c3 slices: Slice with Products.Product Products.Color Products.Price
In the script above, the second argument
join(Products.Color; ", ") .. is the concatenation of the color values. Indeed, unlike the previous example, the
shirt slice has two elements instead of one as we are grouping by
Products.Product (while we were previously leveraging the autogenerated dimension
Pid of the
by Products.Products is required in the script above, but this requirement is somewhat accidental. As the table
Products appears on the left side of the assignment,
into Products is added by default to any aggregation that does not specify its
by on the right. However, in this case, the target table for the text concatenation is not the
Products table by the
Slices table itself. This quirk would also be eliminated by the future syntax (cf. roadmap above).
Advanced remarks: Envision, and its implementation by Lokad, is geared toward batch processing where scripts are run fast, from minutes (for the big ones) down to a few seconds (for the small ones). Once the execution of a script is complete, our goal is to maintain a latency under 500ms to display even very large dashboards over typical internet connections. However, our goal is not to run a script (even a small one) in milliseconds. Indeed, guaranteeing low latencies while supporting a language having the level of expressiveness of Envision is a devilishly difficult problem. The slicing mechanism can be seen as a way to cheat with latencies. Instead of being able to compute a small dashboard very fast (while enforcing plenty of restrictions on the computations themselves), Lokad precomputes up to a large number of dashboards (with no particular restrictions on the computations), and then serves the pre-computed results very fast. Under the hood, each slice remains stored on the server-side and only gets pushed to the client browser when the slice is effectively visited.