Skip to main content

Gauges

The code for these examples can be used in the Markdown visualization to create to create gauges, or speedometer charts, that show where a single value falls in a predefined range.

Basic gauge

Example code

View example code
<style>
.gauge-chart {
/* colors */
--track-color: var(--color-border1);
--fill-color: var(--color-info);
--mask-color: var(--color-background);

/* dimensions */
--chart-size: 400px;
--minmax-offset: var(--size2);
--track-width-ratio: .70;
--track-size: var(--chart-size);
--mask-track-size: calc(var(--track-size) * var(--track-width-ratio));

/* values */
--fill-rotation: calc({{result._first.calc_5.value}} * 180deg);

display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--size1);
height: 100%;
}
.gauge-wrapper {
width: var(--chart-size);
height: calc(var(--chart-size) / 2);
overflow: hidden;
}
.gauge {
width: var(--chart-size);
height: var(--chart-size);
position: relative;
list-style: none;
margin: 0;
padding: 0;

& .center {
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
& .track {
background-color: var(--track-color);
width: var(--track-size);
height: var(--track-size);
}
& .fill {
width: var(--track-size);
height: var(--track-size);
background-image: conic-gradient(
from -90deg,
var(--fill-color) var(--fill-rotation),
transparent 0);
}
& .mask {
background-color: var(--mask-color);
width: var(--mask-track-size);
height: var(--mask-track-size);
}
& .metric {
position: absolute;
bottom: 50%;
text-align: center;
width: 100%;

& .metric-label {
padding: 0;
margin: 0;
}
& .metric-value {
padding: 0;
margin: 0;
line-height: 1;
font-size: 56px;
font-weight: 500;
}
}
}
.footer {
width: var(--chart-size);
display: flex;
flex-direction: row;
justify-content: space-between;
color: var(--color-text1);

& p {
--label-width: calc(calc(1 - var(--track-width-ratio)) * var(--chart-size) / 2);
width: var(--label-width);
text-align: center;
margin: 0;
}
}
.legend {
width: var(--chart-size);
display: flex;
flex-direction: row;
font-size: var(--font-xs);
align-items: center;
justify-content: center;
gap: var(--size1);
color: var(--color-text1);
padding-top: var(--size1);

& p {
margin: 0;
}
}
</style>
<div class="gauge-chart">
<div class="gauge-wrapper">
<ul class="gauge">
<li class="center track"></li>
<li class="center fill"></li>
<li class="center mask"></li>
<li class="metric">
<p class="metric-label">{{fields.order_items.total_sale_price.label}}</p>
<p class="metric-value">{{result._first.order_items.total_sale_price.value}}</p>
</li>
</ul>
</div>
<div class="footer">
<p>$0</p>
<p>{{result._first.calc_4.value}}</p>
</div>
</div>

Gauge with context

Setup

This markdown in this example references a lot of calculations to position and style elements. Below is a screenshot of the query as a reference.

Example code

View example code
<style>
.gauge-chart {
/* colors */
--track-color: var(--color-border1);
--fill-color: var(--color-info);
--mask-color: var(--color-background);
--minmax-color: color-mix(in srgb, var(--fill-color) 30%, transparent);
--avg-color: color-mix(in srgb, var(--fill-color), black 40%);

/* dimensions */
--chart-size: 400px;
--minmax-offset: var(--size2);
--track-width-ratio: .70;
--minmax-outer-size: var(--chart-size);
--track-size: calc(var(--chart-size) - 2 * var(--minmax-offset));
--mask-track-size: calc(var(--track-size) * var(--track-width-ratio));
--minmax-inner-size: var(--mask-track-size);
--mask-minmax-size: calc(var(--minmax-inner-size) - 2 * var(--minmax-offset));

/* values */
--fill-rotation: calc({{result._first.calc_5.value}} * 180deg);
--min-rotation: calc({{result._first.calc_6.value}} * 180deg);
--avg-rotation: calc({{result._first.calc_8.value}}* 180deg);
--max-rotation: calc({{result._first.calc_7.value}} * 180deg);

display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--size1);
height: 100%;
}
.gauge-wrapper {
width: var(--chart-size);
height: calc(var(--chart-size) / 2);
overflow: hidden;
}
.gauge {
width: var(--chart-size);
height: var(--chart-size);
position: relative;
list-style: none;
margin: 0;
padding: 0;

& .center {
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
& .track {
background-color: var(--track-color);
width: var(--track-size);
height: var(--track-size);
}
& .fill {
width: var(--track-size);
height: var(--track-size);
background-image: conic-gradient(
from -90deg,
var(--fill-color) var(--fill-rotation),
transparent 0);
}
& .minmax {
border-radius: 50%;
background-image: conic-gradient(
from -90deg,
transparent var(--min-rotation),
var(--minmax-color) var(--min-rotation),
var(--minmax-color) var(--avg-rotation),
var(--avg-color) var(--avg-rotation),
var(--avg-color) calc(var(--avg-rotation) + .5deg),
var(--minmax-color) calc(var(--avg-rotation) + .5deg),
var(--minmax-color) var(--max-rotation),
transparent 0);
}
& .minmax.minmax-outer {
width: var(--minmax-outer-size);
height: var(--minmax-outer-size);
}
& .minmax.minmax-inner {
width: var(--minmax-inner-size);
height: var(--minmax-inner-size);
}
& .mask {
background-color: var(--mask-color);
}
& .mask.mask-track {
width: var(--mask-track-size);
height: var(--mask-track-size);
}
& .mask.mask-minmax {
width: var(--mask-minmax-size);
height: var(--mask-minmax-size);
}
& .metric {
position: absolute;
bottom: 50%;
text-align: center;
width: 100%;

& .metric-label {
padding: 0;
margin: 0;
}
& .metric-value {
padding: 0;
margin: 0;
line-height: 1;
font-size: 48px;
color: var(--fill-color);
font-weight: 500;
}
}
}
.footer {
width: var(--chart-size);
display: flex;
flex-direction: row;
justify-content: space-between;
color: var(--color-text1);

& p {
--label-width: calc(calc(1 - var(--track-width-ratio)) * var(--chart-size) / 2);
width: var(--label-width);
text-align: center;
margin: 0;
}
}
.legend {
width: var(--chart-size);
display: flex;
flex-direction: row;
font-size: var(--font-xs);
align-items: center;
justify-content: center;
gap: var(--size1);
color: var(--color-text1);
padding-top: var(--size1);

& p {
margin: 0;
}

& .legend-title {
padding-right: var(--size4);
}
& .legend-avg {
margin-left: var(--size6);
width: var(--size05);
height: var(--size4);
background-color: var(--avg-color);
}
& .legend-minmax {
width: var(--size4);
height: var(--size4);
background-color: var(--minmax-color);
display: inline-block;
}
}
</style>
<div class="gauge-chart">
<div class="gauge-wrapper">
<ul class="gauge">
<li class="center track"></li>
<li class="center fill"></li>
<li class="center minmax minmax-outer"></li>
<li class="center mask mask-track"></li>
<li class="center minmax minmax-inner"></li>
<li class="center mask mask-minmax"></li>
<li class="metric">
<p class="metric-label">{{fields.order_items.total_sale_price.label}}</p>
<p class="metric-value">{{result._first.order_items.total_sale_price.value}}</p>
</li>
</ul>
</div>
<div class="footer">
<p>$0</p>
<p>{{result._first.calc_4.value}}</p>
</div>
<div class="legend">
<p class="legend-title">Last 7 days</p>
<p class="legend-minmax"></p>
<p class="legend-value">
{{result._first.calc_2.value}} min &mdash; {{result._first.calc_3.value}} max
</p>
<p class="legend-avg"></p>
<p class="legend-value">{{result._first.calc_1.value}} avg</p>
</div>
</div>