Deneb & Vega-Lite Walkthrough Series | EP01: MARKS AND ENCODING

Let’s learn to run before we fly 🕊️ — a walk-through of the fundamental building blocks in Vega-Lite data viz development

PBI Queryous
6 min readFeb 11, 2024

Acknowledgements
Before we begin, I’d like to tag and thank Deneb creator Daniel Marsh-Patrick — you can find comprehensive Deneb resources and examples at the offical website: deneb-viz.github.io. Daniel has inspired innumerable Power BI developers around the world, enabling us to go far beyond the boundaries of “traditional” Power BI report design. This article is a celebration of Daniel’s endeavours, for which I owe my sincere gratitude 🤓🙌

Getting Started
When embarking on any new learning journey, it’s only natural that we want to create the most amazing, dazzling designs. However, despite our eagerness to unlock new skills and talents, it is absolutely necessary to begin by taking baby steps 🐣… and Vega-Lite is no exception.

It can at first be overwhelming, particularly when viewing the Vega-Lite examples gallery

I know what you are thinking:

“But I just want to make a simple line chart 😭… what happened to my clicky-clicky-draggy-droppy experience?!”

Well, Vega-Lite is incredibly powerful and versatile… but it does require some extra effort. In order to put our chart design ideas into practice, we must get to grips with JSON, and Vega-Lite’s grammar and syntax. It will enable you to build charts which overcome many of the limitations we find in native Power BI visuals. Are you ready to get stuck in? 🧙‍♂️

Step 1: Marks and Encoding
Using the PBIX solution file as a guide, let’s go through the step-by-step process. First, we want to build the dataset for our Deneb visual.

  1. Add the Deneb visual to the canvas
  2. Add the [Category] field and [AC] measure to the Values bucket
  3. Click on the elipses […] and “Edit”
  4. Select “Vega-Lite” specification, and the “empty (with Power BI theming)” template
  5. Create! 📊

Step 2: Create a Mark
You will be presented with an empty template which will contain the following specification:

{
"data": {"name": "dataset"}, // PowerBI dataset
"layer": [] // Empty layer attribute (no marks)
}

(nb: comment annotations are added here for effect, it is not yet possible to add comments to the JSON specification… but it will be soon!)

What we need to do next is “assign” specific parts of our dataset to the chart canvas using a choice of geometric shapes which we refer to as marks.

For this exercise, we will apply a bar mark. I have annotated each line to describe the Vega-Lite structure and grammar:

{                               //-- specification start
"data": {"name": "dataset"}, // powerbi dataset
"layer": [ // start layer
{ // start mark (inside curly brackets)
"mark": { // start mark attributes
"type": "bar" // mark type (bar)
} // end mark attributes
} // end mark
] // end layer
} //-- specification end

The resulting chart will look like this:

Wait, what? Where’s my bar chart? 🤔

Althrough we’ve created a bar mark, it has not bound the graphical property to any axis. This is where encoding comes in. For now, we will look at the x-axis and y-axis.

Step 3: Encoding
Below, I’ve added the encoding channel to the specification.

{
"data": {"name": "dataset"},
"encoding": {}, // empty encoding channel
"layer": [
{
"mark": {
"type": "bar"
}
}
]
}

Now remember our dataset field values?

We want to bind and define these data fields against the x and y-axis. Let’s first bind our Category field to the y-axis:

{
"data": {"name": "dataset"},
"encoding": {
"y": {"field": "Category"} // bind the "Category" field to the y-axis
},
"layer": [
{
"mark": {
"type": "bar"
}
}
]
}

Here is the result:

bar marked bound to the y-axis

Looking better, but it’s not quite finished. Our x-axis is still undefined. Let’s fix that in a jiffy… returning to our specification:

{
"data": {"name": "dataset"},
"encoding": {
"y": {"field": "Category"}, // Category field on the y-axis
"x": {"field": "AC"} // AC measure on the x-axis
},
"layer": [
{
"mark": {
"type": "bar"
}
}
]
}

Hmmn, this isn’t what we expected, is it? Vega-Lite just needs a little help understanding what type of data this is that we are binding to the axis. For example, is it nominal, ordinal or quantitative?

The [AC] measure is a quantitative value, i.e. we want to aggregate/summarise it. Let’s make a little addition to our code:

{
"data": {"name": "dataset"},
"encoding": {
"y": {
"field": "Category", // y-axis field [Category]
"type": "nominal" // data type = "nominal"
},
"x": {
"field": "AC", // x-axis field [AC]
"type": "quantitative" // data type = "quantitative"
}
},
"layer": [
{
"mark": {
"type": "bar"
}
}
]
}

Now run the code again and take a look… much better!

A proper bar chart

Congratulations, you have successfully built a beautiful bar chart. We’re almost finished. Here are a few bonus tips and quality of life techniques you can use to jazz up your designs.

Step 4: Bonus techniques to perfect your chart
Firstly, our bar chart is sorted alphabetically by default. We can change the sort order of the y-axis in a very simple step:

{
"data": {"name": "dataset"},
"encoding": {
"y": {
"field": "Category",
"type": "nominal",
"sort": "-x" // sort descending by the x-axis
// "sort": "x" // sort ascending
},
"x": {
"field": "AC",
"type": "quantitative"
}
},
"layer": [
{
"mark": {
"type": "bar"
}
}
]
}

Finally, for that extra finesse 🪄, let’s add a splash of colour:

{
"data": {"name": "dataset"},
"encoding": {
"y": {
"field": "Category",
"type": "nominal",
"sort": "-x"
},
"x": {
"field": "AC",
"type": "quantitative"
}
},
"layer": [
{
"mark": {
"type": "bar",
"color": "teal" // update the mark's color attribute
// "color": "#0000FF" // use hex codes or CSS colour schemes
}
}
]
}

This is the end of the article — but only the beginning of the series! 😋 Thank you for sticking with me and stay tuned for the next Deneb/Vega-Lite episode soon! 🧙‍♂️

🔗Github link to PBIX: EP01 Deneb VegaLite Series — Marks and Encoding

--

--

PBI Queryous

Passionate about PowerBI, Power Query, DAX and Deneb/Vega-Lite data visualisation