Charts

Area chart

A filled area under one series, or up to four stacked, with ticks, gridlines and a readout per point.

Built on
<svg>vector-effectcontainer queries@starting-stylecolor-mix()
Client JavaScript
None
Works without React
Yes, as HTML and CSS
Source, gzipped
5.1 kB
Built from
Chart legend
  1. Nov 1
    • Bandwidth4.2
  2. Nov 2
    • Bandwidth4.8
  3. Nov 3
    • Bandwidth4.5
  4. Nov 4
    • Bandwidth5.6
  5. Nov 5
    • Bandwidth6.1
  6. Nov 6
    • Bandwidth5.2
  7. Nov 7
    • Bandwidth4.9
  8. Nov 8
    • Bandwidth6.4
  9. Nov 9
    • Bandwidth7.1
  10. Nov 10
    • Bandwidth6.8
Try its options

Loading its options.

Code
import { AreaChart } from "@/components/equip/area-chart";

const days = ["Nov 1", "Nov 2", "Nov 3", "Nov 4", "Nov 5", "Nov 6", "Nov 7", "Nov 8", "Nov 9", "Nov 10"];

export default function Demo() {
  return (
    <AreaChart
      label="Bandwidth served, terabytes per day"
      labels={days}
      series={[{ label: "Bandwidth", values: [4.2, 4.8, 4.5, 5.6, 6.1, 5.2, 4.9, 6.4, 7.1, 6.8] }]}
      format={{ maximumFractionDigits: 1 }}
      height={84}
      ticks={2}
      smooth
      style={{ width: 216 }}
    />
  );
}
Your versionchange its options in Look, This part
HTMLworks in any framework, with the part's CSS
<figure aria-label="Bandwidth served, terabytes per day: 6.8 at Nov 10, highest 7.1 at Nov 9" class="eq-area-chart" style="width:216px;--_h:84px">
  <div class="eq-area-chart-body">
    <div class="eq-area-chart-y" aria-hidden="true">
      <span class="eq-area-chart-ytick" style="--_y:100%">0</span>
      <span class="eq-area-chart-ytick" style="--_y:50%">5</span>
      <span class="eq-area-chart-ytick" style="--_y:0%">10</span>
    </div>
    <div class="eq-area-chart-plot">
      <svg class="eq-area-chart-grid" aria-hidden="true" viewBox="0 0 100 100" preserveAspectRatio="none">
        <line class="eq-area-chart-gridline" data-base="true" x1="0" x2="100" y1="100" y2="100" />
        <line class="eq-area-chart-gridline" x1="0" x2="100" y1="50" y2="50" />
        <line class="eq-area-chart-gridline" x1="0" x2="100" y1="0" y2="0" />
      </svg>
      <svg class="eq-area-chart-lines" aria-hidden="true" viewBox="0 0 100 100" preserveAspectRatio="none">
        <path class="eq-area-chart-fill" data-series="0" d="M0 58 C3.7 56 7.41 52 11.11 52 C14.81 52 18.52 55 22.22 55 C25.92 55 29.63 46.67 33.33 44 C37.03 41.33 40.74 39 44.44 39 C48.15 39 51.85 46 55.56 48 C59.26 50 62.97 51 66.67 51 C70.37 51 74.08 39.67 77.78 36 C81.48 32.33 85.19 29 88.89 29 C92.59 29 96.3 31 100 32 L100 100 C96.3 100 92.59 100 88.89 100 C85.19 100 81.48 100 77.78 100 C74.08 100 70.37 100 66.67 100 C62.97 100 59.26 100 55.56 100 C51.85 100 48.15 100 44.44 100 C40.74 100 37.03 100 33.33 100 C29.63 100 25.92 100 22.22 100 C18.52 100 14.81 100 11.11 100 C7.41 100 3.7 100 0 100 Z" />
        <path class="eq-area-chart-line" data-series="0" d="M0 58 C3.7 56 7.41 52 11.11 52 C14.81 52 18.52 55 22.22 55 C25.92 55 29.63 46.67 33.33 44 C37.03 41.33 40.74 39 44.44 39 C48.15 39 51.85 46 55.56 48 C59.26 50 62.97 51 66.67 51 C70.37 51 74.08 39.67 77.78 36 C81.48 32.33 85.19 29 88.89 29 C92.59 29 96.3 31 100 32" />
      </svg>
      <ol class="eq-area-chart-cols" role="list" aria-label="Bandwidth served, terabytes per day">
        <li class="eq-area-chart-col" tabindex="0" data-side="start" style="--_a:0%;--_w:5.56%;--_c:0%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:58%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Nov 1</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Bandwidth</span><span class="eq-chart-legend-value">4.2</span></li></ul></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="start" style="--_a:5.55%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:52%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Nov 2</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Bandwidth</span><span class="eq-chart-legend-value">4.8</span></li></ul></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="start" style="--_a:16.66%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:55%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Nov 3</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Bandwidth</span><span class="eq-chart-legend-value">4.5</span></li></ul></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="start" style="--_a:27.77%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:44%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Nov 4</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Bandwidth</span><span class="eq-chart-legend-value">5.6</span></li></ul></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="start" style="--_a:38.88%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:39%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Nov 5</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Bandwidth</span><span class="eq-chart-legend-value">6.1</span></li></ul></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="end" style="--_a:50%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:48%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Nov 6</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Bandwidth</span><span class="eq-chart-legend-value">5.2</span></li></ul></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="end" style="--_a:61.11%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:51%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Nov 7</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Bandwidth</span><span class="eq-chart-legend-value">4.9</span></li></ul></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="end" style="--_a:72.22%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:36%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Nov 8</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Bandwidth</span><span class="eq-chart-legend-value">6.4</span></li></ul></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="end" style="--_a:83.33%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:29%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Nov 9</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Bandwidth</span><span class="eq-chart-legend-value">7.1</span></li></ul></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="end" style="--_a:94.44%;--_w:5.56%;--_c:100%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:32%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Nov 10</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Bandwidth</span><span class="eq-chart-legend-value">6.8</span></li></ul></span></li>
      </ol>
    </div>
    <div class="eq-area-chart-x" aria-hidden="true"><span class="eq-area-chart-xtick" data-edge="start" style="--_x:0%">Nov 1</span><span class="eq-area-chart-xtick" data-minor="true" style="--_x:22.22%">Nov 3</span><span class="eq-area-chart-xtick" style="--_x:44.44%">Nov 5</span><span class="eq-area-chart-xtick" data-minor="true" style="--_x:66.67%">Nov 7</span><span class="eq-area-chart-xtick" style="--_x:88.89%">Nov 9</span></div>
  </div>
</figure>

Examples

Stacked by plan

Several series stack with the first at the bottom; each band's edge has its own dash, and the readout adds a total.

  1. May
    • Team820
    • Business310
    • Enterprise42
    Total1,172
  2. Jun
    • Team870
    • Business340
    • Enterprise45
    Total1,255
  3. Jul
    • Team930
    • Business352
    • Enterprise51
    Total1,333
  4. Aug
    • Team1,010
    • Business395
    • Enterprise54
    Total1,459
  5. Sep
    • Team1,080
    • Business430
    • Enterprise60
    Total1,570
  6. Oct
    • Team1,160
    • Business472
    • Enterprise66
    Total1,698
  7. Nov
    • Team1,240
    • Business518
    • Enterprise71
    Total1,829
Code
import { AreaChart } from "@/components/equip/area-chart";

const months = ["May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov"];

export default function Example() {
  return (
    <AreaChart
      label="Paying workspaces by plan"
      labels={months}
      series={[
        { label: "Team", values: [820, 870, 930, 1010, 1080, 1160, 1240] },
        { label: "Business", values: [310, 340, 352, 395, 430, 472, 518] },
        { label: "Enterprise", values: [42, 45, 51, 54, 60, 66, 71] },
      ]}
      smooth
      height={160}
      style={{ maxWidth: 520 }}
    />
  );
}
HTMLworks in any framework, with the part's CSS
<figure aria-label="Paying workspaces by plan: total 1,829 at Nov, highest 1,829 at Nov" class="eq-area-chart" style="max-width:520px;--_h:160px">
  <ul role="list" aria-hidden="true" class="eq-chart-legend eq-area-chart-legend" data-orientation="row">
    <li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Team</span></li>
    <li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Business</span></li>
    <li class="eq-chart-legend-item" data-series="2"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Enterprise</span></li>
  </ul>
  <div class="eq-area-chart-body">
    <div class="eq-area-chart-y" aria-hidden="true">
      <span class="eq-area-chart-ytick" style="--_y:100%">0</span>
      <span class="eq-area-chart-ytick" style="--_y:75%">500</span>
      <span class="eq-area-chart-ytick" style="--_y:50%">1,000</span>
      <span class="eq-area-chart-ytick" style="--_y:25%">1,500</span>
      <span class="eq-area-chart-ytick" style="--_y:0%">2,000</span>
    </div>
    <div class="eq-area-chart-plot">
      <svg class="eq-area-chart-grid" aria-hidden="true" viewBox="0 0 100 100" preserveAspectRatio="none">
        <line class="eq-area-chart-gridline" data-base="true" x1="0" x2="100" y1="100" y2="100" />
        <line class="eq-area-chart-gridline" x1="0" x2="100" y1="75" y2="75" />
        <line class="eq-area-chart-gridline" x1="0" x2="100" y1="50" y2="50" />
        <line class="eq-area-chart-gridline" x1="0" x2="100" y1="25" y2="25" />
        <line class="eq-area-chart-gridline" x1="0" x2="100" y1="0" y2="0" />
      </svg>
      <svg class="eq-area-chart-lines" aria-hidden="true" viewBox="0 0 100 100" preserveAspectRatio="none">
        <path class="eq-area-chart-fill" data-series="0" d="M0 59 C5.56 58.17 11.11 57.42 16.67 56.5 C22.22 55.58 27.78 54.67 33.33 53.5 C38.89 52.33 44.44 50.75 50 49.5 C55.56 48.25 61.11 47.25 66.67 46 C72.22 44.75 77.78 43.33 83.33 42 C88.89 40.67 94.44 39.33 100 38 L100 100 C94.44 100 88.89 100 83.33 100 C77.78 100 72.22 100 66.67 100 C61.11 100 55.56 100 50 100 C44.44 100 38.89 100 33.33 100 C27.78 100 22.22 100 16.67 100 C11.11 100 5.56 100 0 100 Z" />
        <path class="eq-area-chart-fill" data-series="1" d="M0 43.5 C5.56 42.17 11.11 40.77 16.67 39.5 C22.22 38.23 27.78 37.52 33.33 35.9 C38.89 34.27 44.44 31.65 50 29.75 C55.56 27.85 61.11 26.39 66.67 24.5 C72.22 22.61 77.78 20.47 83.33 18.4 C88.89 16.33 94.44 14.2 100 12.1 L100 38 C94.44 39.33 88.89 40.67 83.33 42 C77.78 43.33 72.22 44.75 66.67 46 C61.11 47.25 55.56 48.25 50 49.5 C44.44 50.75 38.89 52.33 33.33 53.5 C27.78 54.67 22.22 55.58 16.67 56.5 C11.11 57.42 5.56 58.17 0 59 Z" />
        <path class="eq-area-chart-fill" data-series="2" d="M0 41.4 C5.56 40.02 11.11 38.59 16.67 37.25 C22.22 35.91 27.78 35.05 33.33 33.35 C38.89 31.65 44.44 29.03 50 27.05 C55.56 25.08 61.11 23.49 66.67 21.5 C72.22 19.51 77.78 17.26 83.33 15.1 C88.89 12.94 94.44 10.73 100 8.55 L100 12.1 C94.44 14.2 88.89 16.33 83.33 18.4 C77.78 20.47 72.22 22.61 66.67 24.5 C61.11 26.39 55.56 27.85 50 29.75 C44.44 31.65 38.89 34.27 33.33 35.9 C27.78 37.52 22.22 38.23 16.67 39.5 C11.11 40.77 5.56 42.17 0 43.5 Z" />
        <path class="eq-area-chart-line" data-series="0" d="M0 59 C5.56 58.17 11.11 57.42 16.67 56.5 C22.22 55.58 27.78 54.67 33.33 53.5 C38.89 52.33 44.44 50.75 50 49.5 C55.56 48.25 61.11 47.25 66.67 46 C72.22 44.75 77.78 43.33 83.33 42 C88.89 40.67 94.44 39.33 100 38" />
        <path class="eq-area-chart-line" data-series="1" d="M0 43.5 C5.56 42.17 11.11 40.77 16.67 39.5 C22.22 38.23 27.78 37.52 33.33 35.9 C38.89 34.27 44.44 31.65 50 29.75 C55.56 27.85 61.11 26.39 66.67 24.5 C72.22 22.61 77.78 20.47 83.33 18.4 C88.89 16.33 94.44 14.2 100 12.1" />
        <path class="eq-area-chart-line" data-series="2" d="M0 41.4 C5.56 40.02 11.11 38.59 16.67 37.25 C22.22 35.91 27.78 35.05 33.33 33.35 C38.89 31.65 44.44 29.03 50 27.05 C55.56 25.08 61.11 23.49 66.67 21.5 C72.22 19.51 77.78 17.26 83.33 15.1 C88.89 12.94 94.44 10.73 100 8.55" />
      </svg>
      <ol class="eq-area-chart-cols" role="list" aria-label="Paying workspaces by plan">
        <li class="eq-area-chart-col" tabindex="0" data-side="start" style="--_a:0%;--_w:8.33%;--_c:0%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:59%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:43.5%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="2" aria-hidden="true" viewBox="0 0 10 10" style="--_y:41.4%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">May</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Team</span><span class="eq-chart-legend-value">820</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Business</span><span class="eq-chart-legend-value">310</span></li><li class="eq-chart-legend-item" data-series="2"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Enterprise</span><span class="eq-chart-legend-value">42</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>1,172</span></span></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="start" style="--_a:8.34%;--_w:16.67%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:56.5%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:39.5%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="2" aria-hidden="true" viewBox="0 0 10 10" style="--_y:37.25%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Jun</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Team</span><span class="eq-chart-legend-value">870</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Business</span><span class="eq-chart-legend-value">340</span></li><li class="eq-chart-legend-item" data-series="2"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Enterprise</span><span class="eq-chart-legend-value">45</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>1,255</span></span></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="start" style="--_a:25%;--_w:16.67%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:53.5%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:35.9%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="2" aria-hidden="true" viewBox="0 0 10 10" style="--_y:33.35%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Jul</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Team</span><span class="eq-chart-legend-value">930</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Business</span><span class="eq-chart-legend-value">352</span></li><li class="eq-chart-legend-item" data-series="2"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Enterprise</span><span class="eq-chart-legend-value">51</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>1,333</span></span></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="start" style="--_a:41.67%;--_w:16.67%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:49.5%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:29.75%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="2" aria-hidden="true" viewBox="0 0 10 10" style="--_y:27.05%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Aug</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Team</span><span class="eq-chart-legend-value">1,010</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Business</span><span class="eq-chart-legend-value">395</span></li><li class="eq-chart-legend-item" data-series="2"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Enterprise</span><span class="eq-chart-legend-value">54</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>1,459</span></span></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="end" style="--_a:58.34%;--_w:16.67%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:46%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:24.5%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="2" aria-hidden="true" viewBox="0 0 10 10" style="--_y:21.5%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Sep</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Team</span><span class="eq-chart-legend-value">1,080</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Business</span><span class="eq-chart-legend-value">430</span></li><li class="eq-chart-legend-item" data-series="2"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Enterprise</span><span class="eq-chart-legend-value">60</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>1,570</span></span></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="end" style="--_a:75%;--_w:16.67%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:42%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:18.4%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="2" aria-hidden="true" viewBox="0 0 10 10" style="--_y:15.1%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Oct</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Team</span><span class="eq-chart-legend-value">1,160</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Business</span><span class="eq-chart-legend-value">472</span></li><li class="eq-chart-legend-item" data-series="2"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Enterprise</span><span class="eq-chart-legend-value">66</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>1,698</span></span></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="end" style="--_a:91.67%;--_w:8.33%;--_c:100%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:38%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:12.1%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="2" aria-hidden="true" viewBox="0 0 10 10" style="--_y:8.55%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Nov</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Team</span><span class="eq-chart-legend-value">1,240</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Business</span><span class="eq-chart-legend-value">518</span></li><li class="eq-chart-legend-item" data-series="2"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Enterprise</span><span class="eq-chart-legend-value">71</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>1,829</span></span></span></li>
      </ol>
    </div>
    <div class="eq-area-chart-x" aria-hidden="true"><span class="eq-area-chart-xtick" data-edge="start" style="--_x:0%">May</span><span class="eq-area-chart-xtick" data-minor="true" style="--_x:33.33%">Jul</span><span class="eq-area-chart-xtick" style="--_x:66.67%">Sep</span><span class="eq-area-chart-xtick" data-edge="end" data-minor="true" style="--_x:100%">Nov</span></div>
  </div>
</figure>

Fixed scale for a quota

Set max to the quota so the fill reads as how close you are to it, not just how it has grown.

  1. Sep 1
    • Hot118GB
    • Archive96GB
    Total214GB
  2. Sep 8
    • Hot124GB
    • Archive98GB
    Total222GB
  3. Sep 15
    • Hot131GB
    • Archive104GB
    Total235GB
  4. Sep 22
    • Hot140GB
    • Archive109GB
    Total249GB
  5. Sep 29
    • Hot152GB
    • Archive112GB
    Total264GB
  6. Oct 6
    • Hot158GB
    • Archive119GB
    Total277GB
  7. Oct 13
    • Hot171GB
    • Archive121GB
    Total292GB
  8. Oct 20
    • Hot183GB
    • Archive130GB
    Total313GB
  9. Oct 27
    • Hot190GB
    • Archive138GB
    Total328GB
  10. Nov 3
    • Hot204GB
    • Archive142GB
    Total346GB
Code
import { AreaChart } from "@/components/equip/area-chart";

const weeks = ["Sep 1", "Sep 8", "Sep 15", "Sep 22", "Sep 29", "Oct 6", "Oct 13", "Oct 20", "Oct 27", "Nov 3"];

export default function Example() {
  return (
    <AreaChart
      label="Object storage used, of a 500 GB quota"
      labels={weeks}
      series={[
        { label: "Hot", values: [118, 124, 131, 140, 152, 158, 171, 183, 190, 204] },
        { label: "Archive", values: [96, 98, 104, 109, 112, 119, 121, 130, 138, 142] },
      ]}
      max={500}
      format={{ style: "unit", unit: "gigabyte", unitDisplay: "narrow", maximumFractionDigits: 0 }}
      height={120}
      style={{ maxWidth: 480 }}
    />
  );
}
HTMLworks in any framework, with the part's CSS
<figure aria-label="Object storage used, of a 500 GB quota: total 346GB at Nov 3, highest 346GB at Nov 3" class="eq-area-chart" style="max-width:480px;--_h:120px">
  <ul role="list" aria-hidden="true" class="eq-chart-legend eq-area-chart-legend" data-orientation="row">
    <li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Hot</span></li>
    <li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Archive</span></li>
  </ul>
  <div class="eq-area-chart-body">
    <div class="eq-area-chart-y" aria-hidden="true">
      <span class="eq-area-chart-ytick" style="--_y:100%">0GB</span>
      <span class="eq-area-chart-ytick" style="--_y:50%">250GB</span>
      <span class="eq-area-chart-ytick" style="--_y:0%">500GB</span>
    </div>
    <div class="eq-area-chart-plot">
      <svg class="eq-area-chart-grid" aria-hidden="true" viewBox="0 0 100 100" preserveAspectRatio="none">
        <line class="eq-area-chart-gridline" data-base="true" x1="0" x2="100" y1="100" y2="100" />
        <line class="eq-area-chart-gridline" x1="0" x2="100" y1="50" y2="50" />
        <line class="eq-area-chart-gridline" x1="0" x2="100" y1="0" y2="0" />
      </svg>
      <svg class="eq-area-chart-lines" aria-hidden="true" viewBox="0 0 100 100" preserveAspectRatio="none">
        <path class="eq-area-chart-fill" data-series="0" d="M0 76.4 L11.11 75.2 L22.22 73.8 L33.33 72 L44.44 69.6 L55.56 68.4 L66.67 65.8 L77.78 63.4 L88.89 62 L100 59.2 L100 100 L88.89 100 L77.78 100 L66.67 100 L55.56 100 L44.44 100 L33.33 100 L22.22 100 L11.11 100 L0 100 Z" />
        <path class="eq-area-chart-fill" data-series="1" d="M0 57.2 L11.11 55.6 L22.22 53 L33.33 50.2 L44.44 47.2 L55.56 44.6 L66.67 41.6 L77.78 37.4 L88.89 34.4 L100 30.8 L100 59.2 L88.89 62 L77.78 63.4 L66.67 65.8 L55.56 68.4 L44.44 69.6 L33.33 72 L22.22 73.8 L11.11 75.2 L0 76.4 Z" />
        <path class="eq-area-chart-line" data-series="0" d="M0 76.4 L11.11 75.2 L22.22 73.8 L33.33 72 L44.44 69.6 L55.56 68.4 L66.67 65.8 L77.78 63.4 L88.89 62 L100 59.2" />
        <path class="eq-area-chart-line" data-series="1" d="M0 57.2 L11.11 55.6 L22.22 53 L33.33 50.2 L44.44 47.2 L55.56 44.6 L66.67 41.6 L77.78 37.4 L88.89 34.4 L100 30.8" />
      </svg>
      <ol class="eq-area-chart-cols" role="list" aria-label="Object storage used, of a 500 GB quota">
        <li class="eq-area-chart-col" tabindex="0" data-side="start" style="--_a:0%;--_w:5.56%;--_c:0%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:76.4%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:57.2%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Sep 1</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Hot</span><span class="eq-chart-legend-value">118GB</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Archive</span><span class="eq-chart-legend-value">96GB</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>214GB</span></span></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="start" style="--_a:5.55%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:75.2%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:55.6%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Sep 8</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Hot</span><span class="eq-chart-legend-value">124GB</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Archive</span><span class="eq-chart-legend-value">98GB</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>222GB</span></span></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="start" style="--_a:16.66%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:73.8%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:53%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Sep 15</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Hot</span><span class="eq-chart-legend-value">131GB</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Archive</span><span class="eq-chart-legend-value">104GB</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>235GB</span></span></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="start" style="--_a:27.77%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:72%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:50.2%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Sep 22</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Hot</span><span class="eq-chart-legend-value">140GB</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Archive</span><span class="eq-chart-legend-value">109GB</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>249GB</span></span></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="start" style="--_a:38.88%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:69.6%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:47.2%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Sep 29</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Hot</span><span class="eq-chart-legend-value">152GB</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Archive</span><span class="eq-chart-legend-value">112GB</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>264GB</span></span></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="end" style="--_a:50%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:68.4%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:44.6%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Oct 6</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Hot</span><span class="eq-chart-legend-value">158GB</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Archive</span><span class="eq-chart-legend-value">119GB</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>277GB</span></span></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="end" style="--_a:61.11%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:65.8%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:41.6%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Oct 13</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Hot</span><span class="eq-chart-legend-value">171GB</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Archive</span><span class="eq-chart-legend-value">121GB</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>292GB</span></span></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="end" style="--_a:72.22%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:63.4%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:37.4%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Oct 20</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Hot</span><span class="eq-chart-legend-value">183GB</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Archive</span><span class="eq-chart-legend-value">130GB</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>313GB</span></span></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="end" style="--_a:83.33%;--_w:11.11%;--_c:50%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:62%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:34.4%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Oct 27</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Hot</span><span class="eq-chart-legend-value">190GB</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Archive</span><span class="eq-chart-legend-value">138GB</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>328GB</span></span></span></li>
        <li class="eq-area-chart-col" tabindex="0" data-side="end" style="--_a:94.44%;--_w:5.56%;--_c:100%"><span class="eq-area-chart-guide" aria-hidden="true"></span><svg class="eq-area-chart-point" data-series="0" aria-hidden="true" viewBox="0 0 10 10" style="--_y:59.2%"><circle cx="5" cy="5" r="5" /></svg><svg class="eq-area-chart-point" data-series="1" aria-hidden="true" viewBox="0 0 10 10" style="--_y:30.8%"><circle cx="5" cy="5" r="5" /></svg><span class="eq-area-chart-tip"><span class="eq-area-chart-tip-label">Nov 3</span><ul role="list" class="eq-chart-legend" data-orientation="column"><li class="eq-chart-legend-item" data-series="0"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Hot</span><span class="eq-chart-legend-value">204GB</span></li><li class="eq-chart-legend-item" data-series="1"><svg class="eq-chart-legend-mark" data-mark="line" aria-hidden="true" width="18" height="10" viewBox="0 0 18 10"><line x1="1" y1="5" x2="17" y2="5" /></svg><span class="eq-chart-legend-name">Archive</span><span class="eq-chart-legend-value">142GB</span></li></ul><span class="eq-area-chart-tip-total"><span>Total</span><span>346GB</span></span></span></li>
      </ol>
    </div>
    <div class="eq-area-chart-x" aria-hidden="true"><span class="eq-area-chart-xtick" data-edge="start" style="--_x:0%">Sep 1</span><span class="eq-area-chart-xtick" data-minor="true" style="--_x:22.22%">Sep 15</span><span class="eq-area-chart-xtick" style="--_x:44.44%">Sep 29</span><span class="eq-area-chart-xtick" data-minor="true" style="--_x:66.67%">Oct 13</span><span class="eq-area-chart-xtick" style="--_x:88.89%">Oct 27</span></div>
  </div>
</figure>

Props

PropTypeDefaultWhat it does
series{ label: string; values: (number | null)[] }[]noneOne series fills to zero; two to four stack, the first at the bottom. Missing and negative values count as zero.
labelsstring[]noneThe ordered x axis, such as months.
labelstringnoneNames the figure. The latest total and the peak are added to it.
heightnumber140Height of the plot area in pixels.
smoothbooleanfalseMonotone curves, so bands never cross or overshoot.
maxnumbernoneFixes the top of the scale, such as a quota.
ticksnumber4About how many gridlines to draw.
showLegendbooleanseries.length > 1Shows the legend above the plot.
formatIntl.NumberFormatOptionsnoneHow values and ticks are written.
localestring"en-US"Passed to Intl.NumberFormat.
...restComponentProps<"figure">noneEvery native figure attribute.

Anatomy

root.eq-area-chartA figure named with the summary.
legend.eq-area-chart-legendA Chart legend with line marks.
body.eq-area-chart-bodyThe axes and plot; a size container.
y axis.eq-area-chart-y
y tick.eq-area-chart-ytick
plot.eq-area-chart-plot
grid.eq-area-chart-grid
gridline.eq-area-chart-gridlinedata-base marks the zero line.
areas.eq-area-chart-linesDraws in from the left on the spring.
fill.eq-area-chart-fillOne band per series.
edge.eq-area-chart-lineThe top of each band, with the series' dash.
empty.eq-area-chart-emptyShown when there is nothing above zero.
columns.eq-area-chart-colsA list with one focusable item per x label.
column.eq-area-chart-col
guide.eq-area-chart-guide
point.eq-area-chart-pointMarks the top of each band under the pointer or focus.
tip.eq-area-chart-tipThe readout: visually hidden until its column is hovered or focused.
tip label.eq-area-chart-tip-label
tip total.eq-area-chart-tip-totalShown when series stack.
x axis.eq-area-chart-x
x tick.eq-area-chart-xtickdata-minor ticks step aside on a narrow chart.

Keyboard

TabMoves through the x labels; each one shows and reads every series value and the total.

Notes

  • Bands differ in ink strength, and each edge carries its own dash, so stacked series never rely on colour alone.
  • The svg is hidden from assistive tech; the list of columns is the text alternative, one item per x label.
  • Stacked areas show parts of a total; to compare series that do not add up, use a Line chart.
  • The chart takes the full width of its container; cap it with max-width or set a width.
  • Renders on the server with no client JavaScript.
  • The draw-in uses @starting-style; where it is missing the areas are simply there.

Source

Two files, and they are the whole part. Open either to read it, copy it straight from its bar, or add the part to your loadout and install it with everything else you picked.

components/equip/area-chart.tsx254 lines
import type { CSSProperties, ComponentProps } from "react";
import { ChartLegend } from "./chart-legend";
import "./area-chart.css";

export type AreaSeries = {
  label: string;
  /** One value per x label, in the same order. Missing and negative values count as zero. */
  values: (number | null)[];
};

export type AreaChartProps = ComponentProps<"figure"> & {
  /** One series fills down to zero; two to four stack, the first at the bottom. Past four, the rest are left out. */
  series: AreaSeries[];
  /** The ordered x axis, such as months or days. */
  labels: string[];
  /** Names the chart, such as "Storage by tier". The latest total and the peak are added to it. */
  label: string;
  /** Height of the plot area in pixels. */
  height?: number;
  /** Draws monotone curves instead of straight segments. */
  smooth?: boolean;
  /** Fixes the top of the scale. */
  max?: number;
  /** About how many gridlines to draw. */
  ticks?: number;
  /** Shows the legend above the plot. On by default when there is more than one series. */
  showLegend?: boolean;
  format?: Intl.NumberFormatOptions;
  locale?: string;
};

const MAX_SERIES = 4;
const MAX_X_TICKS = 6;

type Pt = { x: number; y: number };

export function AreaChart({
  series,
  labels,
  label,
  height = 140,
  smooth = false,
  max,
  ticks = 4,
  showLegend,
  format,
  locale = "en-US",
  className,
  style,
  ...rest
}: AreaChartProps) {
  const number = new Intl.NumberFormat(locale, format);
  const bands = series.slice(0, MAX_SERIES);
  const n = labels.length;
  const at = (s: AreaSeries, i: number) => {
    const v = s.values[i];
    return typeof v === "number" && Number.isFinite(v) && v > 0 ? v : 0;
  };
  /* tops[k][i] is the running total up to and including series k at x i. */
  const tops = bands.map((_, k) => labels.map((_, i) => bands.slice(0, k + 1).reduce((sum, s) => sum + at(s, i), 0)));
  const totals = tops[tops.length - 1] ?? [];
  const peak = Math.max(0, ...totals);
  const empty = n === 0 || bands.length === 0 || peak === 0;

  const scale = niceScale(0, peak || 1, ticks, 0, max);
  const y = (v: number) => round((1 - Math.min(v, scale.hi) / scale.hi) * 100);
  const x = (i: number) => (n === 1 ? 50 : round((i / (n - 1)) * 100));

  const edge = (vals: number[]): Pt[] =>
    n === 1 ? [{ x: 0, y: y(vals[0] ?? 0) }, { x: 100, y: y(vals[0] ?? 0) }] : vals.map((v, i) => ({ x: x(i), y: y(v) }));
  const draw = (pts: Pt[], move: boolean) => (smooth ? curve(pts, move) : straight(pts, move));
  const shapes = tops.map((top, k) => {
    const upper = edge(top);
    const lower = k === 0 ? upper.map((p) => ({ x: p.x, y: 100 })) : edge(tops[k - 1] ?? []);
    return {
      area: `${draw(upper, true)} L${draw([...lower].reverse(), false).slice(1)} Z`,
      line: draw(upper, true),
    };
  });

  const peakAt = totals.indexOf(peak);
  const last = totals[totals.length - 1] ?? 0;
  const summary = empty
    ? `${label}: no data`
    : `${label}: ${bands.length > 1 ? "total " : ""}${number.format(last)} at ${labels[n - 1]}, highest ${number.format(peak)} at ${labels[peakAt]}`;

  const step = Math.max(1, Math.ceil(n / MAX_X_TICKS));
  const width = n > 1 ? 100 / (n - 1) : 100;
  const legend = showLegend ?? bands.length > 1;

  return (
    <figure
      aria-label={summary}
      {...rest}
      className={["eq-area-chart", className].filter(Boolean).join(" ")}
      style={{ ...style, "--_h": `${height}px` } as CSSProperties}
    >
      {legend && !empty && (
        <ChartLegend className="eq-area-chart-legend" mark="line" items={bands.map((s) => ({ label: s.label }))} aria-hidden="true" />
      )}
      <div className="eq-area-chart-body">
        <div className="eq-area-chart-y" aria-hidden="true">
          {!empty &&
            scale.ticks.map((t) => (
              <span key={t} className="eq-area-chart-ytick" style={{ "--_y": `${y(t)}%` } as CSSProperties}>
                {number.format(t)}
              </span>
            ))}
        </div>
        <div className="eq-area-chart-plot">
          <svg className="eq-area-chart-grid" aria-hidden="true" viewBox="0 0 100 100" preserveAspectRatio="none">
            {!empty &&
              scale.ticks.map((t) => (
                <line key={t} className="eq-area-chart-gridline" data-base={t === 0 || undefined} x1="0" x2="100" y1={y(t)} y2={y(t)} />
              ))}
            {empty && <line className="eq-area-chart-gridline" data-base="" x1="0" x2="100" y1="100" y2="100" />}
          </svg>
          {empty ? (
            <span className="eq-area-chart-empty">No data</span>
          ) : (
            <>
              <svg className="eq-area-chart-lines" aria-hidden="true" viewBox="0 0 100 100" preserveAspectRatio="none">
                {shapes.map((s, k) => (
                  <path key={k} className="eq-area-chart-fill" data-series={k} d={s.area} />
                ))}
                {shapes.map((s, k) => (
                  <path key={k} className="eq-area-chart-line" data-series={k} d={s.line} />
                ))}
              </svg>
              <ol className="eq-area-chart-cols" role="list" aria-label={label}>
                {labels.map((name, i) => {
                  const cx = x(i);
                  const a = Math.max(0, cx - width / 2);
                  const b = Math.min(100, cx + width / 2);
                  return (
                    <li
                      key={`${name}-${i}`}
                      className="eq-area-chart-col"
                      tabIndex={0}
                      data-side={n > 1 && i >= n / 2 ? "end" : "start"}
                      style={{ "--_a": `${round(a)}%`, "--_w": `${round(b - a)}%`, "--_c": `${round(((cx - a) / (b - a || 1)) * 100)}%` } as CSSProperties}
                    >
                      <span className="eq-area-chart-guide" aria-hidden="true" />
                      {tops.map((top, k) => (
                        <svg
                          key={k}
                          className="eq-area-chart-point"
                          data-series={k}
                          aria-hidden="true"
                          viewBox="0 0 10 10"
                          style={{ "--_y": `${y(top[i] ?? 0)}%` } as CSSProperties}
                        >
                          <circle cx="5" cy="5" r="5" />
                        </svg>
                      ))}
                      <span className="eq-area-chart-tip">
                        <span className="eq-area-chart-tip-label">{name}</span>
                        <ChartLegend
                          mark="line"
                          orientation="column"
                          items={bands.map((s, k) => ({ label: s.label, value: number.format(at(s, i)), series: k }))}
                        />
                        {bands.length > 1 && (
                          <span className="eq-area-chart-tip-total">
                            <span>Total</span>
                            <span>{number.format(totals[i] ?? 0)}</span>
                          </span>
                        )}
                      </span>
                    </li>
                  );
                })}
              </ol>
            </>
          )}
        </div>
        <div className="eq-area-chart-x" aria-hidden="true">
          {labels.map((name, i) =>
            i % step === 0 ? (
              <span
                key={`${name}-${i}`}
                className="eq-area-chart-xtick"
                data-edge={i === 0 ? "start" : i === n - 1 ? "end" : undefined}
                data-minor={(i / step) % 2 === 1 || undefined}
                style={{ "--_x": `${x(i)}%` } as CSSProperties}
              >
                {name}
              </span>
            ) : null,
          )}
        </div>
      </div>
    </figure>
  );
}

/* Round steps of 1, 2, 2.5 or 5 times a power of ten, so gridlines land on numbers people say. */
function niceScale(lo: number, hi: number, count: number, fixLo?: number, fixHi?: number) {
  let a = fixLo ?? lo;
  let b = fixHi ?? hi;
  if (!(b > a)) b = a + (Math.abs(a) || 1);
  const raw = (b - a) / Math.max(1, count);
  const mag = 10 ** Math.floor(Math.log10(raw));
  const f = raw / mag;
  /* Take the first round step at or above the ideal one that lands on both ends, so a fixed end gets its own line. */
  const steps = [1, 2, 2.5, 5, 10, 20, 25, 50].map((m) => m * mag).filter((s) => s >= raw * (1 - 1e-9) || s === 10 * mag);
  const fits = (s: number) => {
    const lo2 = fixLo ?? Math.floor(a / s) * s;
    const hi2 = fixHi ?? Math.ceil(b / s) * s;
    const k = (hi2 - lo2) / s;
    return Math.abs(k - Math.round(k)) < 1e-6 && k <= count * 2;
  };
  const step = steps.find(fits) ?? (f <= 1 ? 1 : f <= 2 ? 2 : f <= 2.5 ? 2.5 : f <= 5 ? 5 : 10) * mag;
  if (fixLo === undefined) a = Math.floor(a / step) * step;
  if (fixHi === undefined) b = Math.ceil(b / step) * step;
  const ticks: number[] = [];
  for (let k = Math.ceil(a / step - 1e-9); k * step <= b + step * 1e-9; k++) ticks.push(Math.round(k * step * 1e9) / 1e9 || 0);
  return { lo: a, hi: b, ticks };
}

function straight(r: Pt[], move: boolean) {
  return r.map((p, i) => `${i === 0 && move ? "M" : "L"}${p.x} ${p.y}`).join(" ");
}

/* A monotone cubic (Steffen), so a band never overshoots its points or crosses the one below. */
function curve(r: Pt[], move: boolean) {
  const s = r.slice(1).map((p, i) => {
    const q = r[i] ?? p;
    return (p.y - q.y) / (p.x - q.x || 1);
  });
  const m = r.map((p, i) => {
    const s0 = s[i - 1];
    const s1 = s[i];
    if (s0 === undefined) return s1 ?? 0;
    if (s1 === undefined) return s0;
    const h0 = p.x - (r[i - 1]?.x ?? p.x);
    const h1 = (r[i + 1]?.x ?? p.x) - p.x;
    const mid = (s0 * h1 + s1 * h0) / (h0 + h1 || 1);
    return (Math.sign(s0) + Math.sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(mid));
  });
  let d = `${move ? "M" : "L"}${r[0]?.x ?? 0} ${r[0]?.y ?? 0}`;
  for (let i = 0; i < r.length - 1; i++) {
    const p = r[i];
    const q = r[i + 1];
    if (!p || !q) continue;
    const h = (q.x - p.x) / 3;
    d += ` C${round(p.x + h)} ${round(p.y + (m[i] ?? 0) * h)} ${round(q.x - h)} ${round(q.y - (m[i + 1] ?? 0) * h)} ${q.x} ${q.y}`;
  }
  return d;
}

function round(n: number) {
  return Math.round(n * 100) / 100;
}
components/equip/area-chart.css308 lines
@layer equip {
  .eq-area-chart {
    display: grid;
    gap: var(--eq-space-3);
    width: 100%;
    min-width: 0;
    margin: 0;
    font: var(--eq-weight) var(--eq-text-xs) / 1.3 var(--eq-font);
    color: var(--eq-ink-2);
  }

  /* The series steps, the same as Chart legend's: ink strength plus a dash per step. */
  .eq-area-chart [data-series] {
    --_tone: var(--eq-chart-1);
    --_dash: none;
  }

  .eq-area-chart [data-series="1"] {
    --_tone: var(--eq-chart-2);
    --_dash: 5 4;
  }

  .eq-area-chart [data-series="2"] {
    --_tone: var(--eq-chart-3);
    --_dash: 0.1 4;
  }

  .eq-area-chart [data-series="3"] {
    --_tone: var(--eq-chart-4);
    --_dash: 8 4 0.1 4;
  }

  .eq-area-chart-body {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    grid-template-rows: var(--_h) auto;
    column-gap: var(--eq-space-2);
    padding-block-start: var(--eq-space-1);
    container-type: inline-size;
  }

  .eq-area-chart-y {
    display: grid;
    grid-template-rows: var(--_h);
    color: var(--eq-ink-3);
    font-variant-numeric: tabular-nums;
    text-align: end;
  }

  /* Every tick shares one cell, so the column is as wide as the widest label. */
  .eq-area-chart-ytick {
    grid-area: 1 / 1;
    align-self: start;
    position: relative;
    top: var(--_y);
    translate: 0 -50%;
    white-space: nowrap;
  }

  .eq-area-chart-plot {
    position: relative;
    min-width: 0;
    container-type: inline-size;
  }

  .eq-area-chart-grid,
  .eq-area-chart-lines {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
  }

  .eq-area-chart-gridline {
    stroke: var(--eq-line);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
  }

  .eq-area-chart-gridline[data-base] {
    stroke: var(--eq-line-strong);
  }

  /* The areas draw in from the left once, on the spring. */
  .eq-area-chart-lines {
    clip-path: inset(-8px);
    transition: clip-path var(--eq-dur-move) var(--eq-spring);
  }

  @starting-style {
    .eq-area-chart-lines {
      clip-path: inset(-8px 100% -8px -8px);
    }
  }

  /* A soft fill per band, and a full-strength edge with the series' dash on top of it. */
  .eq-area-chart-fill {
    fill: color-mix(in srgb, var(--_tone, var(--eq-ink)) 20%, transparent);
    stroke: none;
  }

  .eq-area-chart-line {
    fill: none;
    stroke: var(--_tone, var(--eq-ink));
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-dasharray: var(--_dash);
    vector-effect: non-scaling-stroke;
  }

  .eq-area-chart-empty {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    color: var(--eq-ink-3);
  }

  .eq-area-chart-cols {
    position: absolute;
    inset: 0;
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .eq-area-chart-col {
    position: absolute;
    top: 0;
    bottom: 0;
    left: var(--_a);
    width: var(--_w);
    border-radius: var(--eq-radius-s);
    outline: none;
    cursor: default;
  }

  .eq-area-chart-col:focus-visible {
    z-index: 1;
    outline: 2px solid var(--eq-focus);
    outline-offset: 2px;
  }

  .eq-area-chart-guide {
    position: absolute;
    top: 0;
    bottom: 0;
    left: var(--_c);
    width: 1px;
    background: var(--eq-line-strong);
    opacity: 0;
    transition: opacity var(--eq-dur) var(--eq-ease);
  }

  .eq-area-chart-point {
    position: absolute;
    left: var(--_c);
    top: var(--_y);
    width: 8px;
    height: 8px;
    overflow: visible;
    translate: -50% -50%;
    scale: 0;
    fill: var(--_tone, var(--eq-ink));
    transition: scale var(--eq-dur-move) var(--eq-spring);
  }

  /* The readout. Out of sight it is still text, so a screen reader reads it with its column. */
  .eq-area-chart-tip {
    position: absolute;
    top: 0;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .eq-area-chart-tip-label {
    display: block;
    margin-block-end: var(--eq-space-1);
    color: var(--eq-ink);
    font-weight: var(--eq-weight-strong);
  }

  .eq-area-chart-tip-total {
    display: flex;
    justify-content: space-between;
    gap: var(--eq-space-3);
    margin-block-start: var(--eq-space-1);
    padding-block-start: var(--eq-space-1);
    border-block-start: 1px solid var(--eq-line);
    color: var(--eq-ink);
    font-weight: var(--eq-weight-strong);
    font-variant-numeric: tabular-nums;
  }

  .eq-area-chart-col:focus-visible .eq-area-chart-guide {
    opacity: 1;
  }

  .eq-area-chart-col:focus-visible .eq-area-chart-point {
    scale: 1;
  }

  .eq-area-chart-col:focus-visible .eq-area-chart-tip {
    z-index: 1;
    width: max-content;
    max-width: calc(50cqi - var(--eq-space-3));
    height: auto;
    margin: 0;
    padding: var(--eq-space-1) var(--eq-space-2);
    overflow: visible;
    clip-path: none;
    white-space: normal;
    border: 1px solid var(--eq-line-strong);
    border-radius: var(--eq-radius-m);
    background: var(--eq-raised);
    box-shadow: var(--eq-shadow);
    -webkit-backdrop-filter: var(--eq-blur);
    backdrop-filter: var(--eq-blur);
  }

  .eq-area-chart-col[data-side="start"]:focus-visible .eq-area-chart-tip {
    left: calc(var(--_c) + var(--eq-space-2));
  }

  .eq-area-chart-col[data-side="end"]:focus-visible .eq-area-chart-tip {
    right: calc(100% - var(--_c) + var(--eq-space-2));
  }

  @media (hover: hover) {
    .eq-area-chart-col:hover {
      z-index: 1;
    }

    .eq-area-chart-col:hover .eq-area-chart-guide {
      opacity: 1;
    }

    .eq-area-chart-col:hover .eq-area-chart-point {
      scale: 1;
    }

    .eq-area-chart-col:hover .eq-area-chart-tip {
      z-index: 1;
      width: max-content;
      max-width: calc(50cqi - var(--eq-space-3));
      height: auto;
      margin: 0;
      padding: var(--eq-space-1) var(--eq-space-2);
      overflow: visible;
      clip-path: none;
      white-space: normal;
      border: 1px solid var(--eq-line-strong);
      border-radius: var(--eq-radius-m);
      background: var(--eq-raised);
      box-shadow: var(--eq-shadow);
      -webkit-backdrop-filter: var(--eq-blur);
      backdrop-filter: var(--eq-blur);
    }

    .eq-area-chart-col[data-side="start"]:hover .eq-area-chart-tip {
      left: calc(var(--_c) + var(--eq-space-2));
    }

    .eq-area-chart-col[data-side="end"]:hover .eq-area-chart-tip {
      right: calc(100% - var(--_c) + var(--eq-space-2));
    }
  }

  .eq-area-chart-x {
    position: relative;
    grid-column: 2;
    height: calc(var(--eq-text-xs) * 1.3);
    margin-block-start: var(--eq-space-2);
    color: var(--eq-ink-3);
  }

  .eq-area-chart-xtick {
    position: absolute;
    left: var(--_x);
    translate: -50% 0;
    white-space: nowrap;
  }

  .eq-area-chart-xtick[data-edge="start"] {
    translate: 0 0;
  }

  .eq-area-chart-xtick[data-edge="end"] {
    translate: -100% 0;
  }

  /* On a narrow chart every other label steps aside so the rest do not collide. The width is in
     em (of the chart body), so larger or wider type steps aside sooner. */
  @container (max-width: 24em) {
    .eq-area-chart-xtick[data-minor] {
      display: none;
    }
  }
}

EqUIp is in beta: free for non-commercial use, no warranty, and things can change. Terms

Nothing picked yet. Press A on a part, or use the plus on the board, and the install command builds here.

Loading the index.

Loading the index