glacier-web-cli 0.5.0

Command-line tool for creating and running Glacier applications.
{% props label: String, values: Vec<(String, f64)>, caption: String = "" %}
{#- values: (name, percent of the goal or limit), up to three rings, outermost first. One ring shows its percentage and `caption` ("36 of 50 GB") in the centre; several get a legend. -#}
{%- let single = values.len() == 1 %}
{%- let rings = values.iter().take(3).enumerate().map(|(i, (name, pct))| {
  let r: f64 = if single { 64.0 } else { 66.0 - 16.0 * i as f64 };
  let length = std::f64::consts::TAU * r;
  (i + 1, name.clone(), *pct, r, format!("{:.1} {:.1}", length * pct.clamp(0.0, 100.0) / 100.0, length))
}).collect::<Vec<_>>() %}
{%- let width = if single { 14 } else { 10 } %}
{%- let described = rings.iter().map(|(_, name, pct, _, _)| format!("{name} {pct}%")).collect::<Vec<_>>().join(", ") %}
<div{% if !single %} style="display:grid;grid-template-columns:120px 1fr;gap:16px;align-items:center"{% end %}>
  <div class="ui-chart"{% if single %} style="width:160px;margin:0 auto"{% end %}>
    <svg viewBox="0 0 160 160" role="img" aria-label="{{ label }}: {% if single && !caption.is_empty() %}{{ described }}, {{ caption }}{% else %}{{ described }}{% end %}">
      {%- for (class, _, _, r, dash) in rings.iter() %}
      <circle cx="80" cy="80" r="{{ r }}" fill="none" stroke="var(--muted)" stroke-width="{{ width }}"/>
      <g class="s{{ class }}"><circle class="radial" cx="80" cy="80" r="{{ r }}" fill="none" stroke-width="{{ width }}" stroke-linecap="round" stroke-dasharray="{{ dash }}" transform="rotate(-90 80 80)"/></g>
      {%- end %}
      {%- if single %}
      <text x="80" y="80" text-anchor="middle" style="font-size:28px;font-weight:600;fill:var(--foreground);font-family:var(--font-sans)">{{ rings[0].2 }}%</text>
      {%- if !caption.is_empty() %}
      <text x="80" y="100" text-anchor="middle" style="font-size:12px;fill:var(--muted-foreground);font-family:var(--font-sans)">{{ caption }}</text>
      {%- end %}
      {%- end %}
    </svg>
  </div>
  {%- if !single %}
  <ul class="ui-chart-legend" style="flex-direction:column;gap:8px">
    {%- for (class, name, pct, _, _) in rings.iter() %}
    <li class="s{{ class }}"><span class="ui-chart-swatch"></span>{{ name }} <b style="margin-left:auto;color:var(--foreground);font-weight:500">{{ pct }}%</b></li>
    {%- end %}
  </ul>
  {%- end %}
</div>