Skip to content

Instantly share code, notes, and snippets.

@Giammaria
Last active March 7, 2025 15:20
Show Gist options
  • Save Giammaria/0e930e7a1bb3f81a53f24b317e35d697 to your computer and use it in GitHub Desktop.
Save Giammaria/0e930e7a1bb3f81a53f24b317e35d697 to your computer and use it in GitHub Desktop.
20250307_percentage_gauge_v_v1
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 300,
"height": 300,
"autosize": {"type": "pad"},
"signals": [
{"name": "padding", "value": 0},
{
"name": "darkMode",
"init": "true",
"bind": {"name": "Dark Mode", "input": "checkbox"}
},
{"name": "background", "update": "darkMode ? '#202020' : '#fff'"},
{
"name": "percentage",
"init": "+format(random(), '.2f')",
"on": [
{"events": {"signal": "darkMode"}, "update": "+format(random(), '.2f')"}
]
},
{
"name": "initializedTime",
"init": "now()",
"on": [{"events": {"signal": "darkMode"}, "update": "now()"}]
},
{"name": "transitionDuration", "init": "percentage*1500+500"},
{
"name": "t",
"init": "0",
"on": [
{
"events": {"type": "timer", "throttle": 10},
"update": "now() >= (initializedTime + transitionDuration) ? 1 : (now()-initializedTime)/(transitionDuration)"
}
]
},
{
"name": "percentageInterpolated",
"update": "+format((t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1)*percentage, '.2f')"
},
{"name": "axisTickStep", "value": 1},
{"name": "radius", "update": "min(width, height)/2.1"},
{"name": "mainColor", "update": "darkMode ? '#8C9EFF' : '#2943D1'"},
{"name": "secondaryColor", "update": "darkMode ? '#ccc' : '#888'"},
{"name": "font", "value": "sans-serif"},
{"name": "due", "update": "now()+(2.628e+9)*(random()*10)"},
{"name": "remainingDays", "update": "round((due-now())/(8.64e+7))"},
{
"name": "dueText",
"update": "['Due ' + utcFormat(due, '%d-%b-%y'), '━━━', remainingDays + ' day' + (remainingDays > 1 ? 's' : '') + ' remain']"
}
],
"scales": [
{
"name": "scaleRadialAxis",
"type": "linear",
"domain": [0, 1],
"range": {"signal": "[PI+0.85, 3*PI-0.85]"}
}
],
"marks": [
{
"name": "axis-tics",
"type": "text",
"from": {"data": "axisDataset"},
"encode": {
"update": {
"text": {"value": "|"},
"font": {"signal": "font"},
"fontWeight": {"value": 600},
"fontSize": {"field": "fontSize"},
"x": {"signal": "width/2"},
"y": {"signal": "height/2"},
"radius": {"signal": "radius"},
"fill": {"signal": "mainColor"},
"fillOpacity": {"field": "fillOpacity"},
"theta": {"field": "theta"},
"angle": {"field": "angle"},
"baseline": {"value": "top"},
"align": {"value": "center"}
}
}
},
{
"name": "percentage-mark",
"type": "text",
"from": {"data": "percentageDataset"},
"encode": {
"update": {
"text": {"signal": "'|'"},
"font": {"signal": "font"},
"fontWeight": {"value": 100},
"fontSize": {"field": "fontSize"},
"x": {"signal": "width/2"},
"y": {"signal": "height/2"},
"radius": {"signal": "radius+(radius/30)"},
"fill": {"signal": "mainColor"},
"stroke": {"signal": "mainColor"},
"strokeJoin": {"value": "round"},
"strokeWidth": {"signal": "min(width, height)/60"},
"theta": {"field": "theta"},
"angle": {"field": "angle"},
"baseline": {"value": "top"},
"align": {"value": "center"}
}
}
},
{
"name": "percentage-text",
"type": "text",
"encode": {
"update": {
"text": {"signal": "format(percentageInterpolated, '.0%')"},
"font": {"signal": "font"},
"fontWeight": {"value": 700},
"fontSize": {"signal": "radius/2.5"},
"x": {"signal": "width/2"},
"y": {"signal": "height/3"},
"fill": {"signal": "mainColor"},
"angle": {"field": "angle"},
"baseline": {"value": "middle"},
"align": {"value": "center"}
}
}
},
{
"name": "metric-title-text",
"from": {"data": "percentage-text"},
"type": "text",
"encode": {
"update": {
"text": {"signal": "'Metric Name'"},
"font": {"signal": "font"},
"fontWeight": {"value": 500},
"fontSize": {"signal": "radius/7"},
"x": {"signal": "width/2"},
"y": {
"signal": "datum.bounds.y2",
"offset": {"signal": "min(width,height)/120"}
},
"fill": {"signal": "secondaryColor"},
"angle": {"field": "angle"},
"baseline": {"value": "top"},
"align": {"value": "center"}
}
}
},
{
"name": "metric-date-due",
"from": {"data": "metric-title-text"},
"type": "text",
"encode": {
"update": {
"text": {"signal": "dueText"},
"font": {"signal": "font"},
"fontWeight": {"value": 400},
"fontSize": {"signal": "radius/10"},
"x": {"signal": "width/2"},
"y": {"signal": "datum.bounds.y2", "offset": {"signal": "20"}},
"fill": {"signal": "secondaryColor"},
"angle": {"field": "angle"},
"baseline": {"value": "top"},
"align": {"value": "center"}
}
}
}
],
"data": [
{
"name": "axisDataset",
"values": [{}],
"transform": [
{
"type": "formula",
"expr": "sequence(0, 100+1, axisTickStep)",
"as": "tick"
},
{"type": "flatten", "fields": ["tick"]},
{
"type": "formula",
"expr": "datum.tick%(axisTickStep*2) === 0 ? radius/8 : radius/6",
"as": "fontSize"
},
{"type": "formula", "expr": "datum.tick/100", "as": "tick"},
{
"type": "formula",
"expr": "scale('scaleRadialAxis', datum.tick)",
"as": "theta"
},
{
"type": "formula",
"expr": "(datum['theta']*180/PI)%360",
"as": "angle"
},
{
"type": "formula",
"expr": "0.1+(10*+format(datum.tick/13, '.2f'))+0.1",
"as": "fillOpacity"
}
]
},
{
"name": "percentageDataset",
"values": [{}],
"transform": [
{"type": "formula", "expr": "percentageInterpolated", "as": "tick"},
{"type": "formula", "expr": "radius/5", "as": "fontSize"},
{
"type": "formula",
"expr": "scale('scaleRadialAxis', datum.tick)",
"as": "theta"
},
{
"type": "formula",
"expr": "(datum['theta']*180/PI)%360",
"as": "angle"
}
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment