Building Dashboards
This page walks through the dashboard-building basics in one flow, from a simple layout to styling and interactivity. If you need the sample data later, open the 1-echelon 2017 dataset session; otherwise these steps run as-is.
Table of contents
Build a One-Page Dashboard with Labels, Scalars, Tables, and Charts
Start with a blank playground session and build a minimal dashboard that mixes text, KPIs, tables, and a chart on one screen.
- Paste the script and run it.
- You should now see a label at the top, a revenue KPI, a table by SKU, and a weekly revenue line chart.
- Change one revenue and re-run to update the KPI, table, and chart.
preview = show region { 1..8, 1..34 }
table Sales = with
[| as OrderDate, as sku, as Qty, as Revenue |]
[| date(2024, 1, 3), "A-100", 12, 240 |]
[| date(2024, 1, 10), "A-100", 15, 300 |]
[| date(2024, 1, 10), "B-200", 20, 260 |]
[| date(2024, 1, 17), "B-200", 18, 234 |]
[| date(2024, 1, 24), "C-300", 10, 180 |]
[| date(2024, 1, 31), "C-300", 14, 210 |]
keep span date = [date(2024, 1, 1) .. date(2024, 1, 31)]
Day.Revenue = sum(Sales.Revenue) by Sales.OrderDate at Day.date
Week.Revenue = sum(Day.Revenue)
show label "One-page sales dashboard" { .., 1..3 in preview }
show scalar "Total revenue" { .., 5..7 in preview; unit:"$" } with sum(Sales.Revenue)
show table "Revenue by SKU" { .., 9..16 in preview } with
Sales.sku
sum(Sales.Qty) as "Units"
sum(Sales.Revenue) as "Revenue" { unit:"$" }
group by Sales.sku
show linechart "Weekly revenue" { .., 18..31 in preview } with
Week.Revenue { unit:"$" }
You should see three SKU rows in the table and five weekly points on the chart. Edit the Sales table revenues or dates and re-run to update the dashboard.
Lay Out a Dashboard with Regions
Use regions to control where tiles land instead of letting them stack automatically. Regions add padding and require a blank row between tiles, so keep row gaps when stacking.
- Run the script.
- You should now see a left card with two stacked KPIs and a right card with a weekly table.
- Resize the browser or tweak the ranges to see how the region boundaries keep the layout steady.
table Weeks[week] = with
[| as week, as Units, as Revenue |]
[| week(2024, 1), 120, 3200 |]
[| week(2024, 2), 135, 3550 |]
[| week(2024, 3), 128, 3380 |]
[| week(2024, 4), 142, 3700 |]
summary = show region { ..4, ..7 }
show scalar "Total units" { .., ..2 in summary } with sum(Weeks.Units)
show scalar "Total revenue" { .., 4..5 in summary } with sum(Weeks.Revenue)
detail = show region { 5.., ..7 }
show table "Week detail" { .., ..5 in detail } with
Weeks.week
Weeks.Units
Weeks.Revenue { unit:"$" }
Try moving the table into the summary region or adjusting the { ..4, ..8 } height to see how rows become available or unavailable inside a region.
Add Basic Tile Styling with StyleCode
Add a touch of visual emphasis so your tiles are easier to scan.
- Paste the script and run it.
- You should now see a KPI tile and a table where margins of at least 20% are green, smaller nonnegative margins are amber, and negative margins are red.
- Change the margin values and re-run to watch the colors update.
preview = show region { 1..8, 1..17 }
table Products = with
[| as Product, as Margin |]
[| "Alpha", 0.32 |]
[| "Beta", 0.08 |]
[| "Gamma", -0.05 |]
[| "Delta", 0.18 |]
Products.Color = if Products.Margin >= 0.2 then "#2e7d32" else if Products.Margin >= 0 then "#f9a825" else "#c62828"
show scalar "Average margin" { .., 1..3 in preview; unit:"%" } with
avg(Products.Margin) * 100
show table "Margins by product" { .., 5..14 in preview } with
Products.Product
(Products.Margin * 100) as "Margin" { unit:"%" ; textColor: #[Products.Color] }
You should now see the margin values tinted by performance, giving you a fast visual read.
Add Tooltips and Conditional Formatting
Make the dashboard more self-explanatory with tooltips and color cues.
- Paste the script and run it.
- You should now see a summary tile with a tooltip and a table that colors rows below the reorder point.
- Adjust
Stock.OnHandand re-run to test the warning colors.
preview = show region { 1..8, 1..19 }
table Stock = with
[| as Sku, as OnHand, as Reorder |]
[| "A-100", 25, 30 |]
[| "B-200", 8, 20 |]
[| "C-300", 45, 15 |]
[| "D-400", 12, 12 |]
Stock.Alert = Stock.OnHand < Stock.Reorder
Stock.Color = if Stock.Alert then "#c62828" else "#2e7d32"
show summary "Stock check" { .., 1..6 in preview; tileTooltip: "Rows in red are below the reorder point." } with
count(Stock.*) as "SKUs"
sum(if Stock.Alert then 1 else 0) as "Below reorder"
show table "Reorder watchlist" { .., 8..16 in preview } with
Stock.Sku
Stock.OnHand { columnTooltipText: "Current units on hand" ; textColor: #[Stock.Color] }
Stock.Reorder { columnTooltipText: "Reorder threshold" ; textColor: #[Stock.Color] }
You should now see a quick warning system built directly into the tiles.
Create a Product Inspector with Slicing
Build a simple product inspector that switches views when you change the slice.
- Paste the script and run it.
- Use the slice dropdown to switch between products.
- You should now see the summary and table update for the selected product.
table Items[id] = with
[| as id, as Name, as Price, as Lines |]
[| "A-100", "Alpha mug", 12.0, 3 |]
[| "B-200", "Beta kettle", 18.0, 2 |]
[| "C-300", "Gamma bottle", 9.0, 4 |]
table Orders max 1000 = extend.range(Items.Lines)
Orders.id = Items.id
Orders.Date = date(2024, 2, 1) + Orders.N
Orders.Qty = random.poisson(2 into Orders)
Orders.Revenue = Orders.Qty * Items.Price
Orders.ItemName = Items.Name
table Slices[slice] = slice by id title: Items.Name
Items.slice = Slices.slice
Orders.slice = Items.slice
show summary "Product snapshot" slices: slice with
first(Orders.ItemName) sort Orders.Date as "Product"
sum(Orders.Qty) as "Units"
sum(Orders.Revenue) as "Revenue" { unit:"$" }
show table "Order lines" slices: slice with
Orders.Date
Orders.Qty
Orders.Revenue { unit:"$" }
You should now have a reusable pattern for product drill-downs.
Add Browser-Side Interactivity with dash
Use an editable table so your dashboard reacts without rerunning the script.
- Paste the script and run it.
- Click a cell in the Value column and edit a number.
- You should now see the row re-color as it moves in or out of range.
read upload "values" as Submitted with
Id : text
Value : number
table Values = with
[| "A" as Id, 1 as Min, 5 as Max |]
[| "B", 0, 10 |]
[| "C", -5, 5 |]
mutable Values.Value = single(Submitted.Value) by Submitted.Id at Values.Id default (Values.Min + 1)
dash Values.IsValid = Values.Min <= Values.Value and Values.Value <= Values.Max
show table "Values" editable: "values" with
Values.Id { columnReadOnly: true }
Values.Value mutable { cellBackground: #[if Values.IsValid then "#c8e6c9" else "#ffcdd2"] }
Values.Min { columnReadOnly: true }
Values.Max { columnReadOnly: true }
You should now see live updates as you edit values in the table.
Export a Result Table as a File
Generate a result table and export it as a TSV file.
- If needed, open the 1-echelon 2017 dataset session.
- Paste the script and run it.
- You should now see a top sellers table and a new file at
/exports/top-sellers.tsv.
read "/sample/Lokad_Items.tsv" as Items[id] with
"Id" as id : text
Name : text
read "/sample/Lokad_Orders.tsv.gz" as Orders expect [id, date] with
"Id" as id : text
"Date" as date : date
Quantity : number
NetAmount : number
table SkuStats[sku] = by Orders.id
SkuStats.Name = Items.Name
SkuStats.Units = sum(Orders.Quantity)
SkuStats.Revenue = sum(Orders.NetAmount)
SkuStats.Rank = rank() sort -SkuStats.Revenue
keep where SkuStats.Rank <= 10
show table "Top sellers" with
SkuStats.Rank
SkuStats.sku
SkuStats.Name
SkuStats.Units
SkuStats.Revenue
order by SkuStats.Rank
write SkuStats as "/exports/top-sellers.tsv" with
Sku = SkuStats.sku
Name = SkuStats.Name
Units = SkuStats.Units
Revenue = SkuStats.Revenue
You should now be able to open the Files tab and download the TSV export.
Continue with Styling Dashboards to give an inventory report a consistent palette, readable KPIs, and coordinated table and chart colors.