Styling dashboards

Envision includes a dedicated sub-language, called StyleCode, that allows a refined control over the dashboards style. It borrows strongly from CSS and its extensions, LESS and SCSS. Indeed, as in CSS, elements’ appearances are controlled within StyleCode by attributing a value to a property (e.g. textColor: tomato), and sub-elements inherit their parent elements’ properties, unless these are expressly redefined.

StyleCode integration

StyleCode integration within Envision is straightforward: StyleCode snippets can be set up in StyleCode as a list of options enclosed in curly brackets or can be equivalently placed in the line before the show statement, in the same line as the show statement or spread over several lines, as illustrated in the following examples:

// Three equivalent syntaxes

{ textColor: tomato ; unit: "€" }
show table "Orders" with Id, Orders.NetAmount

show table "Orders" { textColor: tomato ; unit: "€" } with Id, Orders.NetAmount

show table "Orders" {
    textColor: tomato
    unit: "€"
} with Id, Orders.NetAmount

In the following, we review the potentialities of StyleCode, showing how every detail of a tile can be tuned in practice. A full list of target elements and their properties is provided in our StyleCode reference section. Furthermore, there is a dedicated sections on how to beautify dashboards.

Our goal in this section is to style main elements in a dashboard to reach the following layout.

StylecodeOverview

In the following subsections we will explain each element.

StyleCode consists of property-value assignments, such as textColor: tomato (assign the value tomato to the property textColor). Envision lets you place white-space anywhere in that statement, as well as surround the value with quotes. This allows for bits of fantasy in your code:

{    textColor   :"tomato";unit:    "€"    } // unusual spacing (not recommended)
{ textColor: "tomato"; unit: "€" }           // recommended formatting

For clarity and consistency, we recommend to:

Formatting labels

Labels are used on Dashboards as title and structuring elements for dashboards. These can easily be formatted using StyleCode.

show label "Sales and supplier analysis" a1d1 { 
  textAlign: center
  backgroundColor: #f7f8f9
  tileColor: #5f5f5f
}

This code centers the text of the label, defines the background color of the tile to #f7f8f9 and the accent color (in this case, the font color) to #5f5f5f. The result is the following:

Stylecodelabel

Formatting display of scalars

Here we want to format a number in the following way:

Stylecodescalar

When formatting scalars, that is tables that consist of one column and one row, the StyleCode snippet immediately succeeds the title.

read "/clean/Lokad_Items.csv" as Items
BuyPriceEUR = forex(BuyPrice,BuyCurrency, "USD", today()-2)
show table "Stock Available" e1 { 
  textAlign: center
  unit: "$"
  numbers: thousands
  backgroundColor: #f87551
  tileColor: #404040
} with sum(StockOnHand * BuyPriceEUR) as "Stock on Hand (Vol)"

Numbers: "thousands" ensures that instead of the precise value, \$ 54 820.4 , is displayed in a rounded format, \$ 54.82k. Since we want the value to be expressed in USD with the \$ sign in front of the number, we declare this with unit:"\$"; unitPosition:"left". In fact, unitPosition:"left“` is in our case redundant, since Envision automatically positions the unit sign on the left for €, \$ and £.

Formatting tables

StyleCode offers a variety of possibilities to format tables: Notably, one has options to format the header of the tile and the positioning as well as individual column properties.

In the following code snippet we want to display the relationship of articles with their suppliers and related buying information.

read "/clean/Lokad_Items.csv" as Items

InScope = Category == "Office Supplies"
IsTargetBrand = Brand == "Avery" | Brand == "Xerox"
StatusIcon = InScope? "✔️" : "❌"

show table "Products and their suppliers" a3g5 {
  // StyleCode in this line defines the header of the tile and its positioning 
  tileColor: #5f5f5f 
  backgroundColor: #a7a7a7
} with

  // Stylecode next to column names define column designs and properties
  StatusIcon as "In Scope?" { textAlign: right }
  Name { cellBackground: #f8f8f8 }
  Category { cellBackground: #f8f8f8 }
  Brand { cellBackground: #f8f8f8 }
  Supplier {
    cellBackground: #a7a7a7
    textColor: #f87551
  }
  BuyPriceEUR {
      unit: "€"
      cellBackground: #a7a7a7
      fractionSeparator:","
  }
  LeadTime { unit: " days" ; cellBackground: #a7a7a7}

This results in the following tile:

Stylecodescalar

Using StyleCode we want to graphically link columns related to an article together, as well as the columns relating to the supplier and buying conditions by assigning them different column colors, namely \#f8f8f8 for the article related columns and \#a7a7a7 for the supplier related columns.

Apart from the cellBackground specifications, the same properties as for using scalars can be used. Here, we have e.g. placed the status icon aligned to the right with { textAlign: right }, so that it is directly next to the article name.

A useful property when working with different currencies or when encountering different number formats, is the option fractionSeparator: "," which allows one to switch the decimal point from . as in \$1.50 to , as in to 1,50€.

Units are not limited to currency signs: In this example we have expressed lead times in days by specifying unit: " days" in the last column.

For the status icon we have used the possibility in Envision to display HTML UTF8 symbols (see e.g. here for a list) which can be integrate by just copy and pasting them into the code.

Formatting linecharts

StyleCode permits to integrate both stacked as well as line type graphs for linecharts. In the below example, we assume that our item table has a boolean flag InScope flagging those articles that are eligible for the Lokad optimization. Furthermore, there is a different flag IsTargetBrand flagging those eligible items that are belonging to a distinguished group of brands that we would like to highlight.

In the linechart diagram, we illustrate weekly sales of articles that are in scope and are part of the target brand category with orange bars and we stack the non-target sales that are in scope in grey on top. This allows us to express that the sum of these two is in fact the sum of all target and non-target sales of items that are in scope.

For reference, we include also a dashed line with the total amount of sales including also the sales of items that are not in scope. Using a dashed line instead of a solid line (which is the default setting) allows us to express that the quantity shown is only a reference.

read "/clean/Lokad_Items.csv" as Items
read "/clean/Lokad_Orders.csv" as Orders

InScope = Category == "Office Supplies"
IsTargetBrand = Brand == "Avery" | Brand == "Xerox"

Week.SalesQ := sum(Orders.Quantity)
Week.SalesQInScope := sum(Orders.Quantity) if (InScope & not IsTargetBrand)
Week.SalesQInScopeTarget := sum(Orders.Quantity) if (InScope & IsTargetBrand)

show linechart "Order quantities per week" a3e6 with
  Week.SalesQInScope as "In scope sales (target brand)" {
      seriesType: stack
      color: #f87551
  }
  Week.SalesQInScopeTarget as "In scope sales (excl. target brand)" {
      seriesType: stack
      color: #a7a7a7
  }
  Week.SalesQ as "Total sales (in scope & out of scope)" {
      seriesType: line
      seriesPattern: dashed
      color: #5f5f5f
  }

The above code translates into the following example.

Stylecodescalar

The two series types (line or stack) are expressed via seriesType: line and seriesType: stack, respectively. For lines, the options are

For stacked bar charts, the order of definition is important. If we were to change the order of our two stacked bar charts, the orange bars would appear on top of the grey ones.

Placing tiles

The placement of a tile is chiefly determined by the property tilePlacement, which can take the values fixed and bottom (the default).

If fixed is chosen, the position and dimensions of the tile can all be directly specified by the user. The position of a tile is defined by setting up the x and y coordinates of the top-left corner of the tile with respect to the dashboard surface (the top-left corner of the dashboard has coordinates (0,0)). This is accessible through the properties tileX and tileY (default value is $0$). The tile’s dimensions can as well be determined, using tileW for the width and tileH for the height, both having the value $1$ as default.

Otherwise, by default (bottom) a tile is placed on the first empty row of the dashboard (below all user-positioned tiles), starting from the left. If several tiles have to be positioned by default, they are placed from left to right up to the dashboard width, in the order in which they appear in the script, with dimensions $1 \times 1$. The bottom placement mode is applied also in the case where two fixed tiles overlap: the tile appearing second in the script is switched to tilePlacement: bottom.

read "/clean/Lokad_Items.csv" as Items
read "/clean/Lokad_Orders.csv" as Orders

{ tilePlacement: fixed ; tileX: 2 ; tileY: 3 ; tileW: 4 ; tileH: 5 }
show table "Orders" with Id, Orders.NetAmount

Dynamic styling

So far, the StyleCode has been static, the values of the style attributes being hard-coded within the Envision script. However, StyleCode offers the possibility to achieve data-driven styling, where styles are injected from the data into your dashboard. This is done using the #(expression) syntax where expression must be a scalar value.

Here is an example of using a currency variable to display the currency:

currency1 := same(Currency.Currency)
currency2 := "EUR"

show table "Currencies"  with
  Id
  BuyPrice { unit: #(currency1) }
  SellPrice { unit: #(currency2) }

As a second example, let’s see how #(expression) allows a user to conditionally color a tile:

oKColorBG := 1 == 0 ? "69af5d" :"a8080d"

show table "Color your background" a15 {backgroundColor: #(oKColorBG)}  with
  "It works"

At this point of time, #(expression) cannot be used with a vector. As a consequence, it is not yet possible to programmatically control the color of every cell in a table tile (i.e. conditional formatting in Excel).