Skip to main content

Basic gauge

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

<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>