NS Design System
v3.0.0 · 257 tokens

156LMS charts

The forms an LMS dashboard actually needs: engagement heatmap, score distribution, the enrollment funnel, and sparkline stat tiles. All from the same layer and the same slots.

Engagement heatmap

Activity by weekday and week — magnitude, so SEQUENTIAL fills, one hue. Empty cells stay grid-gray: zero is data. Hover or tab to a cell for its value.

Learning activitylessons completed · by weekday
MON
MON W1 · 24 lessons
MON W2 · 36 lessons
MON W3 · 12 lessons
MON W4 · 48 lessons
MON W5 · 24 lessons
MON W6 · 36 lessons
MON W7 · 48 lessons
MON W8 · 24 lessons
MON W9 · 36 lessons
MON W10 · 48 lessons
MON W11 · 36 lessons
MON W12 · 48 lessons
TUE
TUE W1 · 12 lessons
TUE W2 · 24 lessons
TUE W3 · 36 lessons
TUE W4 · 24 lessons
TUE W5 · 48 lessons
TUE W6 · 24 lessons
TUE W7 · 36 lessons
TUE W8 · 48 lessons
TUE W9 · 24 lessons
TUE W10 · 36 lessons
TUE W11 · 48 lessons
TUE W12 · 36 lessons
WED
WED W1 · 36 lessons
WED W2 · 48 lessons
WED W3 · 24 lessons
WED W4 · 36 lessons
WED W5 · 12 lessons
WED W6 · 48 lessons
WED W7 · 24 lessons
WED W8 · 36 lessons
WED W9 · 48 lessons
WED W10 · 24 lessons
WED W11 · 36 lessons
WED W12 · 48 lessons
THU
THU W1 · 24 lessons
THU W2 · 12 lessons
THU W3 · 48 lessons
THU W4 · 24 lessons
THU W5 · 36 lessons
THU W6 · 24 lessons
THU W7 · 48 lessons
THU W8 · 12 lessons
THU W9 · 24 lessons
THU W10 · 48 lessons
THU W11 · 24 lessons
THU W12 · 36 lessons
FRI
FRI W1 · 12 lessons
FRI W2 · 24 lessons
FRI W3 · 24 lessons
FRI W4 · 36 lessons
FRI W5 · 24 lessons
FRI W6 · 36 lessons
FRI W7 · 12 lessons
FRI W8 · 24 lessons
FRI W9 · 36 lessons
FRI W10 · 24 lessons
FRI W11 · 48 lessons
FRI W12 · 24 lessons
SAT
SAT W1 · 0 lessons
SAT W2 · 12 lessons
SAT W3 · 0 lessons
SAT W4 · 24 lessons
SAT W5 · 12 lessons
SAT W6 · 0 lessons
SAT W7 · 24 lessons
SAT W8 · 12 lessons
SAT W9 · 0 lessons
SAT W10 · 12 lessons
SAT W11 · 24 lessons
SAT W12 · 12 lessons
SUN
SUN W1 · 0 lessons
SUN W2 · 0 lessons
SUN W3 · 12 lessons
SUN W4 · 0 lessons
SUN W5 · 12 lessons
SUN W6 · 24 lessons
SUN W7 · 0 lessons
SUN W8 · 0 lessons
SUN W9 · 12 lessons
SUN W10 · 0 lessons
SUN W11 · 12 lessons
SUN W12 · 24 lessons
markup
<figure class="ns-chart">
  <div class="ns-chart__head"><span class="ns-chart__title">Learning activity</span><span class="ns-chart__sub">lessons completed · by weekday</span></div>
  <div class="ns-chart__heat" style="--cols:12">
    <div class="ns-chart__heat-row" style="--cols:12">
      <span class="ns-chart__heat-label">MON</span>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">MON W1 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">MON W2 · 36 lessons</span></div>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">MON W3 · 12 lessons</span></div>
      <div class="ns-chart__cell" data-seq="4" tabindex="0"><span class="ns-chart__tip">MON W4 · 48 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">MON W5 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">MON W6 · 36 lessons</span></div>
      <div class="ns-chart__cell" data-seq="4" tabindex="0"><span class="ns-chart__tip">MON W7 · 48 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">MON W8 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">MON W9 · 36 lessons</span></div>
      <div class="ns-chart__cell" data-seq="4" tabindex="0"><span class="ns-chart__tip">MON W10 · 48 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">MON W11 · 36 lessons</span></div>
      <div class="ns-chart__cell" data-seq="4" tabindex="0"><span class="ns-chart__tip">MON W12 · 48 lessons</span></div>
    </div>
    <div class="ns-chart__heat-row" style="--cols:12">
      <span class="ns-chart__heat-label">TUE</span>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">TUE W1 · 12 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">TUE W2 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">TUE W3 · 36 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">TUE W4 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="4" tabindex="0"><span class="ns-chart__tip">TUE W5 · 48 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">TUE W6 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">TUE W7 · 36 lessons</span></div>
      <div class="ns-chart__cell" data-seq="4" tabindex="0"><span class="ns-chart__tip">TUE W8 · 48 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">TUE W9 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">TUE W10 · 36 lessons</span></div>
      <div class="ns-chart__cell" data-seq="4" tabindex="0"><span class="ns-chart__tip">TUE W11 · 48 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">TUE W12 · 36 lessons</span></div>
    </div>
    <div class="ns-chart__heat-row" style="--cols:12">
      <span class="ns-chart__heat-label">WED</span>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">WED W1 · 36 lessons</span></div>
      <div class="ns-chart__cell" data-seq="4" tabindex="0"><span class="ns-chart__tip">WED W2 · 48 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">WED W3 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">WED W4 · 36 lessons</span></div>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">WED W5 · 12 lessons</span></div>
      <div class="ns-chart__cell" data-seq="4" tabindex="0"><span class="ns-chart__tip">WED W6 · 48 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">WED W7 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">WED W8 · 36 lessons</span></div>
      <div class="ns-chart__cell" data-seq="4" tabindex="0"><span class="ns-chart__tip">WED W9 · 48 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">WED W10 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">WED W11 · 36 lessons</span></div>
      <div class="ns-chart__cell" data-seq="4" tabindex="0"><span class="ns-chart__tip">WED W12 · 48 lessons</span></div>
    </div>
    <div class="ns-chart__heat-row" style="--cols:12">
      <span class="ns-chart__heat-label">THU</span>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">THU W1 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">THU W2 · 12 lessons</span></div>
      <div class="ns-chart__cell" data-seq="4" tabindex="0"><span class="ns-chart__tip">THU W3 · 48 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">THU W4 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">THU W5 · 36 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">THU W6 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="4" tabindex="0"><span class="ns-chart__tip">THU W7 · 48 lessons</span></div>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">THU W8 · 12 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">THU W9 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="4" tabindex="0"><span class="ns-chart__tip">THU W10 · 48 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">THU W11 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">THU W12 · 36 lessons</span></div>
    </div>
    <div class="ns-chart__heat-row" style="--cols:12">
      <span class="ns-chart__heat-label">FRI</span>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">FRI W1 · 12 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">FRI W2 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">FRI W3 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">FRI W4 · 36 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">FRI W5 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">FRI W6 · 36 lessons</span></div>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">FRI W7 · 12 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">FRI W8 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="3" tabindex="0"><span class="ns-chart__tip">FRI W9 · 36 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">FRI W10 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="4" tabindex="0"><span class="ns-chart__tip">FRI W11 · 48 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">FRI W12 · 24 lessons</span></div>
    </div>
    <div class="ns-chart__heat-row" style="--cols:12">
      <span class="ns-chart__heat-label">SAT</span>
      <div class="ns-chart__cell" tabindex="0"><span class="ns-chart__tip">SAT W1 · 0 lessons</span></div>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">SAT W2 · 12 lessons</span></div>
      <div class="ns-chart__cell" tabindex="0"><span class="ns-chart__tip">SAT W3 · 0 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">SAT W4 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">SAT W5 · 12 lessons</span></div>
      <div class="ns-chart__cell" tabindex="0"><span class="ns-chart__tip">SAT W6 · 0 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">SAT W7 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">SAT W8 · 12 lessons</span></div>
      <div class="ns-chart__cell" tabindex="0"><span class="ns-chart__tip">SAT W9 · 0 lessons</span></div>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">SAT W10 · 12 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">SAT W11 · 24 lessons</span></div>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">SAT W12 · 12 lessons</span></div>
    </div>
    <div class="ns-chart__heat-row" style="--cols:12">
      <span class="ns-chart__heat-label">SUN</span>
      <div class="ns-chart__cell" tabindex="0"><span class="ns-chart__tip">SUN W1 · 0 lessons</span></div>
      <div class="ns-chart__cell" tabindex="0"><span class="ns-chart__tip">SUN W2 · 0 lessons</span></div>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">SUN W3 · 12 lessons</span></div>
      <div class="ns-chart__cell" tabindex="0"><span class="ns-chart__tip">SUN W4 · 0 lessons</span></div>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">SUN W5 · 12 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">SUN W6 · 24 lessons</span></div>
      <div class="ns-chart__cell" tabindex="0"><span class="ns-chart__tip">SUN W7 · 0 lessons</span></div>
      <div class="ns-chart__cell" tabindex="0"><span class="ns-chart__tip">SUN W8 · 0 lessons</span></div>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">SUN W9 · 12 lessons</span></div>
      <div class="ns-chart__cell" tabindex="0"><span class="ns-chart__tip">SUN W10 · 0 lessons</span></div>
      <div class="ns-chart__cell" data-seq="1" tabindex="0"><span class="ns-chart__tip">SUN W11 · 12 lessons</span></div>
      <div class="ns-chart__cell" data-seq="2" tabindex="0"><span class="ns-chart__tip">SUN W12 · 24 lessons</span></div>
    </div>
  </div>
</figure>

Score distribution

Quiz scores in ten-point bins — a histogram is a column chart whose x-axis is a scale. One series, slot 1, values in tooltips.

Quiz score distributionfinal assessment · n=412
0–10 · 8
11–20 · 12
21–30 · 21
31–40 · 33
41–50 · 54
51–60 · 87
61–70 · 120
71–80 · 148
81–90 · 107
91–100 · 58
050100
markup
<figure class="ns-chart">
  <div class="ns-chart__head"><span class="ns-chart__title">Quiz score distribution</span><span class="ns-chart__sub">final assessment · n=412</span></div>
  <div class="ns-chart__plot">
    <div class="ns-chart__col" tabindex="0" style="--v:4%">
      <span class="ns-chart__tip">0–10 · 8</span>
      <div class="ns-chart__bar"></div>
    </div>
    <div class="ns-chart__col" tabindex="0" style="--v:6%">
      <span class="ns-chart__tip">11–20 · 12</span>
      <div class="ns-chart__bar"></div>
    </div>
    <div class="ns-chart__col" tabindex="0" style="--v:10%">
      <span class="ns-chart__tip">21–30 · 21</span>
      <div class="ns-chart__bar"></div>
    </div>
    <div class="ns-chart__col" tabindex="0" style="--v:16%">
      <span class="ns-chart__tip">31–40 · 33</span>
      <div class="ns-chart__bar"></div>
    </div>
    <div class="ns-chart__col" tabindex="0" style="--v:26%">
      <span class="ns-chart__tip">41–50 · 54</span>
      <div class="ns-chart__bar"></div>
    </div>
    <div class="ns-chart__col" tabindex="0" style="--v:42%">
      <span class="ns-chart__tip">51–60 · 87</span>
      <div class="ns-chart__bar"></div>
    </div>
    <div class="ns-chart__col" tabindex="0" style="--v:58%">
      <span class="ns-chart__tip">61–70 · 120</span>
      <div class="ns-chart__bar"></div>
    </div>
    <div class="ns-chart__col" tabindex="0" style="--v:72%">
      <span class="ns-chart__tip">71–80 · 148</span>
      <div class="ns-chart__bar"></div>
    </div>
    <div class="ns-chart__col" tabindex="0" style="--v:52%">
      <span class="ns-chart__tip">81–90 · 107</span>
      <div class="ns-chart__bar"></div>
    </div>
    <div class="ns-chart__col" tabindex="0" style="--v:28%">
      <span class="ns-chart__tip">91–100 · 58</span>
      <div class="ns-chart__bar"></div>
    </div>
  </div>
  <div class="ns-chart__x"><span>0</span><span></span><span></span><span></span><span></span><span>50</span><span></span><span></span><span></span><span>100</span></div>
</figure>

Enrollment funnel

Enrolled → started → completed → certified. Centered stages, sequential fills, and the drop-off named beside each stage — the loss IS the story.

Course funnelApex basics · this quarter
Enrolled · 460 Enrolled
460
Started · 350 · −24% vs previous Started
350
Completed · 239 · −32% vs previous Completed
239
Certified · 143 · −40% vs previous Certified
143
markup
<figure class="ns-chart">
  <div class="ns-chart__head"><span class="ns-chart__title">Course funnel</span><span class="ns-chart__sub">Apex basics · this quarter</span></div>
  <div class="ns-chart__funnel">
    <div class="ns-chart__fstage" tabindex="0">
      <span class="ns-chart__tip">Enrolled · 460</span>
      <span class="ns-chart__row-label">Enrolled</span>
      <div class="ns-chart__ftrack"><div class="ns-chart__fbar" data-seq="1" style="--v:100%"></div></div>
      <span class="ns-chart__row-value">460</span>
    </div>
    <div class="ns-chart__fstage" tabindex="0">
      <span class="ns-chart__tip">Started · 350 · −24% vs previous</span>
      <span class="ns-chart__row-label">Started</span>
      <div class="ns-chart__ftrack"><div class="ns-chart__fbar" data-seq="2" style="--v:76%"></div></div>
      <span class="ns-chart__row-value">350</span>
    </div>
    <div class="ns-chart__fstage" tabindex="0">
      <span class="ns-chart__tip">Completed · 239 · −32% vs previous</span>
      <span class="ns-chart__row-label">Completed</span>
      <div class="ns-chart__ftrack"><div class="ns-chart__fbar" data-seq="3" style="--v:52%"></div></div>
      <span class="ns-chart__row-value">239</span>
    </div>
    <div class="ns-chart__fstage" tabindex="0">
      <span class="ns-chart__tip">Certified · 143 · −40% vs previous</span>
      <span class="ns-chart__row-label">Certified</span>
      <div class="ns-chart__ftrack"><div class="ns-chart__fbar" data-seq="4" style="--v:31%"></div></div>
      <span class="ns-chart__row-value">143</span>
    </div>
  </div>
</figure>

Stat tiles with sparklines

The dashboard's first row: label, value, delta in status ink, and a 12-point sparkline — no axes, no grid; the tile's job is the number.

1,284 ▲ 12%
Active learners
82 ▲ 9%
Completions / wk
71 ▼ 2%
Avg quiz score
markup
<dl class="ns-statband" style="background:var(--color-surface)">
  <div class="ns-statband__cell">
    <dd class="ns-statband__value">1,284 <span class="ns-chart__delta" data-dir="up">▲ 12%</span></dd>
    <dt class="ns-statband__label">Active learners</dt>
    <svg class="ns-chart__spark" viewBox="0 0 320 30" preserveAspectRatio="none" aria-hidden="true">
      <polyline class="ns-chart__line" data-c="1" vector-effect="non-scaling-stroke" points="0,26 29,22 58,24 87,18 116,20 145,14 174,16 203,10 232,12 261,8 290,9 320,4"/>
    </svg>
  </div>
  <div class="ns-statband__cell">
    <dd class="ns-statband__value">82 <span class="ns-chart__delta" data-dir="up">▲ 9%</span></dd>
    <dt class="ns-statband__label">Completions / wk</dt>
    <svg class="ns-chart__spark" viewBox="0 0 320 30" preserveAspectRatio="none" aria-hidden="true">
      <polyline class="ns-chart__line" data-c="1" vector-effect="non-scaling-stroke" points="0,22 29,24 58,20 87,22 116,16 145,18 174,14 203,16 232,10 261,14 290,8 320,6"/>
    </svg>
  </div>
  <div class="ns-statband__cell">
    <dd class="ns-statband__value">71 <span class="ns-chart__delta" data-dir="down">▼ 2%</span></dd>
    <dt class="ns-statband__label">Avg quiz score</dt>
    <svg class="ns-chart__spark" viewBox="0 0 320 30" preserveAspectRatio="none" aria-hidden="true">
      <polyline class="ns-chart__line" data-c="1" vector-effect="non-scaling-stroke" points="0,10 29,12 58,8 87,14 116,12 145,16 174,14 203,18 232,16 261,20 290,18 320,22"/>
    </svg>
  </div>
</dl>