Skip to main content

Building Reusable Components in Canvas Dashboard

With Canvas Dashboard, you can define visuals and components once and reuse them across multiple dashboards. This document goes through a simple example to demonstrate the reusability capability.

Reusable Component Example​

The Setup​

Let's say you have a dashboard with the following syntax:

my_canvas_dashboard.page.aml
Dashboard my_dashboard {
// metadata
title: 'My Canvas Dashboard'
description: 'My new Canvas Dashboard'

// collection of blocks
block t1: TextBlock {
content: @md
Hello world
;;
}

block f1: FilterBlock {
type: 'field'
label: 'User role'
source: FieldFilterSource {
dataset: 'tenant_user'
field: r(public_users.role)
}
}

block v1: VizBlock {
label: 'A pie chart'
viz: PieChart {
dataset: 'tenant_user'
legend: r(public_users.role)
series {
field {
ref: r(public_users.id)
aggregation: 'sum'
}
}
}
}

// layout
view: CanvasLayout {
width: 1200
height: 1200
margin: 10
block f1 {
position: pos(600, 0, 300, 70)
}
block v1 {
position: pos(0, 70, 600, 600)
}
}
}

Reusing Block and Filters within another dashboard​

You can refer to your existing viz and filter blocks using the syntax my_original_dashboard.block.block_name. For example:

another_dashboard.page.aml
Dashboard another_dashboard {
// metadata
title: 'Another Canvas Dashboard'
description: 'Another Canvas Dashboard'

// collection of reused blocks from my_dashboard
block t1: my_dashboard.block.t1
block f1: my_dashboard.block.f1
block v1: my_dashboard.block.v1

// layout
view: CanvasLayout {
width: 1200
height: 1200
margin: 10
block f1 {
position: pos(600, 0, 300, 70)
}
block v1 {
position: pos(0, 70, 600, 600)
}
}
}

With AML Extend, you can also customize the reused block like below

another_dashboard.page.aml
Dashboard another_dashboard {
// other properties omitted
block v1: my_dashboard.block.v1.extend({
label: "A different label"
})
}

Reusing independent Block and Filters​

Alternatively, you can put the viz block and filter in a separate file and reuse them with AML Constant like so:

my_reusable_blocks.aml
VizBlock myviz {
label: 'A pie chart'
viz: PieChart {
dataset: 'tenant_user'
legend: r(public_users.role)
series {
field {
ref: r(public_users.id)
aggregation: 'sum'
}
}
}
}

FilterBlock myfilter {
type: 'field'
label: 'User role'
source: FieldFilterSource {
dataset: 'tenant_user'
field: r(public_users.role)
}
}

Then you can create a new dashboard

my_canvas_dashboard.page.aml
Dashboard my_reused_dashboard {
title: 'My reused Dashboard'

block f1: myfilter
block v1: myviz
...
}

Compared to the previous method, placing the reused blocks in a separate file offers a cleaner structure. However, it can make editing those blocks more challenging as you need to put them in a concrete dashboard to edit them in the UI. Ultimately, the choice between methods depends on your preferences and specific needs.

Parameterizing components​

You can also use Func to parameterize your component, like so:

my_functions.aml
Func myvizBlockWithDataset(dataset: String) {
VizBlock {
label: 'A pie chart'
viz: PieChart {
dataset: dataset
legend: r(public_users.role)
series {
field {
ref: r(public_users.id)
aggregation: 'sum'
}
}
}
}
}

and use it like this

my_canvas_dashboard.page.aml
Dashboard my_reused_dashboard {
...
block v1: myvizBLockWithDataset('tenant_user')
...
}

Open Markdown
Let us know what you think about this document :)