Can you smell it? The aroma of the baked pizza? Do you feel it? The increasing heartbeat rate when you look at the countdown timer where only 30 seconds left? How about joy mixed with pride when watching the number of completed orders increase and your revenue of the day bloom?
All that is possible now with Grafana 10 and the canvas panel, which becomes generally available in the latest Grafana 10 release. It saw the light of dawn in June 2023, and no doubt it could be called the best Grafana release yet.
The canvas panel is far from being complete but mature enough for a production environment. The breathtaking presentation featuring the house's energy with metrics and animated wind turbines gave many of us the itch to drop everything and try to build something with it.
As proved many times, Grafana is a champion in the observability of K8s clusters, monitoring logs, and traces.
However, we at Volkov Labs find it delightful to explore other Grafana possibilities. Time after time, we uncovered it being effective in areas yet to be considered. This time our love for pizza and the news about the Canvas panel being released as part of the core begged us to challenge ourselves with the pizzeria observability dashboard.
The results are in and look pleasing. Keep reading to learn what we were able to come up with.
Mockup
We started by designing the layout of the panel in Figma. The canvas panel requires the background to be a raster image, and custom elements are based on vector SVG graphics. Figma can do both at the same time!
We selected the most important metrics to track in the pizzeria observability journey:
- Number of online and walk-in orders.
- How many orders were completed today.
- Revenue based on the completed orders.
- Waiting time for walk-in customers.
- Status of the ovens and progress of pizza baking.
The pizza oven includes:
- Timer to display time left.
- Smoke, lights, fire and knob lights to indicate that the oven is working.
- Pizza opacity to imitate the baking process. The fully cooked pizza has 100%.

Background
The data metrics were removed from the Mockup and will be replaced with data elements on the canvas panel. Pizza ovens will be replaced with advanced custom elements.

The exported background file can be placed in the public/img/bg/
folder mapped in the Docker container or referenced from the URL in the panel's options:

Pizza oven
As we mentioned the wind turbine, drone and server elements in the canvas panel look interesting, but these kinds of elements can't be easily incorporated in the working version of Grafana. New advanced elements should be scripted in the Grafana source code, compiled and built into the new Docker container to take advantage of.
Creating new advanced elements starts with a transparent SVG file. This file will be used in the React display component. We recommend including id
attributes to identify and animate layers.
Created oven's layers consist of text, vector, and ellipse elements with added filters and effects for a natural look and feel.

Advanced canvas element
The advanced canvas element consists of:
- Definition with id, name, and description.
- Options with default parameters for background, and placement.
- UI options for element configuration.
- Function to return data from data sources.
- React component to display the element.
Element definitions
All custom elements should be identified with id, name and description. Name and description will be displayed for user selection in the panel options. The default size should be set based on the exported SVG width and height.
export const pizzaOvenItem: CanvasElementItem = {
id: "pizzaOven",
name: "Pizza Oven",
description: "Animated pizza oven",
display: PizzaOvenDisplay,
defaultSize: {
width: 200,
height: 300,
},
};
UI configuration options
We selected state
and time
options as input dimensions which can be set as fixed or data source field values:
state
controls lights, fire and knob lights to indicate that the oven is working.time
displays how much time is left and controls the opacity of the pizza layers.
registerOptionsUI: (builder: any) => {
const category = ["Pizza Oven"];
builder
.addCustomEditor({
category,
id: "state",
path: "config.state",
name: "State",
editor: ResourceDimensionEditor,
})
.addCustomEditor({
category,
id: "time",
path: "config.time",
name: "Time",
editor: ResourceDimensionEditor,
});
};
Values from data sources
Based on the configured options values will be static or returned from the data source. To create a data
structure to display elements we used getResource
method to retrieve the last value from the data source.
prepareData: (ctx: DimensionContext, cfg: PizzaOvenConfig) => {
const stateValues = cfg?.state && ctx.getResource(cfg.state).field?.values || [];
const timeValues = cfg?.time && ctx.getResource(cfg.time).field?.values || [];
const data: PizzaOvenData = {
state: stateValues.length && stateValues[stateValues.length-1],
time: timeValues.length ? timeValues[timeValues.length-1] : 0
};
return data;
},
React display component
The display component for the pizza oven returns SVG graphics with smoke animation and is controlled by the configured UI options and data source values.
An advanced element with styles, types and a React component
loading...
The proposed canvas element was created in the public/app/features/canvas/elements/
folder and included in the registry (public/app/features/canvas/registry.ts
) as an advanced element item:
export const defaultElementItems = [
metricValueItem, // default for now
textItem,
rectangleItem,
iconItem,
serverItem,
];
export const advancedElementItems = [
buttonItem,
windTurbineItem,
droneTopItem,
droneFrontItem,
droneSideItem,
pizzaOvenItem,
];
export const canvasElementRegistry =
new Registry() <
CanvasElementItem >
(() => [...defaultElementItems, ...advancedElementItems]);
Developing and building a Docker image
To get started with Grafana development on Mac or Linux:
- Clone repository
git clone https://github.com/grafana/grafana.git
- Install dependencies
yarn install --immutable
- Start Frontend
yarn start
- Start Backend
make run
Developing and building Docker images is explained in the Grafana developer guide.
If you followed all the steps you should see a Pizza Oven advanced element in the list:

PostgreSQL with Timescale data source
For the demonstration, we used the PostgreSQL with Timescale database, which is the ultimate storage partner for Grafana. You can find an explanation in the tutorial:
The table orders
to keep track of online and walk-in orders and the cooking progress:
CREATE TABLE orders (
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
created timestamp with time zone NOT NULL,
name text,
phone text,
description text,
online boolean,
price integer,
oven integer,
started timestamp with time zone NOT NULL
);
CREATE SEQUENCE seq_orders START 1;
insert into orders values(nextval('seq_orders'), now(), 'Mike', '123-456-789', 'Cheese Pizza', true, 19.99, 1, now());
insert into orders values(nextval('seq_orders'), now(), 'Ella', '132-461-782', 'Pepperoni Pizza', false, 24.99, 2, now());
The canvas panel is awesome
The canvas panel can be used for a variety of use cases, pizzeria included.
