Skip to content
v1.3.1
Fit

Chart

A dependency-free, responsive SVG chart — area, line, or bar — that re-measures its container and redraws crisply, with hover tooltips on pointer devices. Tier-1 adapt: the width is always fluid. For dashboards, deploy histories, and usage trends.

bash
jlds add chart

Usage

html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jarooda/jlds@main/registry/css/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jarooda/jlds@main/registry/css/chart.css">
<!-- behavior layer: builds the SVG + hover tooltip -->
<script src="https://cdn.jsdelivr.net/gh/jarooda/jlds@main/registry/js/core.js" defer></script>
<script src="https://cdn.jsdelivr.net/gh/jarooda/jlds@main/registry/js/chart.js" defer></script>

<div
  class="jl-chart"
  data-type="area"
  data-height="210"
  data-values="28,41,35,52,49,63,58"
  data-labels="Mon,Tue,Wed,Thu,Fri,Sat,Sun"
  data-suffix="k"
></div>
vue
<script setup lang="ts">
import { Chart } from "@/components/ui/chart"

const series = [
  { label: "Mon", value: 28 }, { label: "Tue", value: 41 }, { label: "Wed", value: 35 },
  { label: "Thu", value: 52 }, { label: "Fri", value: 49 }, { label: "Sat", value: 63 },
]
</script>

<template>
  <Chart type="area" :data="series" :height="210" :value-format="(v) => `${v}k`" />
</template>
tsx
import { Chart } from "@/components/ui/chart"

const series = [
  { label: "Mon", value: 28 }, { label: "Tue", value: 41 }, { label: "Wed", value: 35 },
  { label: "Thu", value: 52 }, { label: "Fri", value: 49 }, { label: "Sat", value: 63 },
]

<Chart type="area" data={series} height={210} valueFormat={(v) => `${v}k`} />

data accepts plain numbers (auto-indexed labels) or { label, value } points. Switch type between "area", "line", and "bar"; override the series color with color (any CSS color), defaulting to --accent.

Line

type="line" drops the area fill. Pair with showDots to mark each point.

html
<div class="jl-chart" data-type="line" data-dots="true"
     data-values="120,132,101,134,190,230,210,182"></div>
vue
<template>
  <Chart type="line" :data="series" :show-dots="true" />
</template>
tsx
<Chart type="line" data={series} showDots />

Bar

type="bar" renders vertical bars — good for discrete buckets. Hover dims the other bars.

html
<div class="jl-chart" data-type="bar"
     data-values="18,24,31,22,28,19,12"
     data-labels="Mon,Tue,Wed,Thu,Fri,Sat,Sun"></div>
vue
<template>
  <Chart type="bar" :data="series" />
</template>
tsx
<Chart type="bar" data={series} />

Multi-series & reference line

Pass series (an array of { name, data, color? }) for multiple lines/areas/bars — a legend and per-series tooltip appear automatically. Add referenceLine (a number, or { value, label, color }) to draw a dashed threshold. The single-series data prop still works unchanged.

html
<div
  class="jl-chart"
  data-type="line"
  data-ref="95" data-ref-label="SLA 95%" data-ref-color="var(--danger)"
  data-series='[{"name":"us-east","data":[92,97,99,96,98]},{"name":"eu-west","color":"var(--info)","data":[88,91,94,90,93]}]'
></div>
vue
<template>
  <Chart
    type="line"
    :reference-line="{ value: 95, label: 'SLA 95%', color: 'var(--danger)' }"
    :series="[
      { name: 'us-east', data: [92, 97, 99, 96, 98] },
      { name: 'eu-west', color: 'var(--info)', data: [88, 91, 94, 90, 93] },
    ]"
  />
</template>
tsx
<Chart
  type="line"
  referenceLine={{ value: 95, label: "SLA 95%", color: "var(--danger)" }}
  series={[
    { name: "us-east", data: [92, 97, 99, 96, 98] },
    { name: "eu-west", color: "var(--info)", data: [88, 91, 94, 90, 93] },
  ]}
/>

Stacked bars

type="bar" with stacked stacks multiple series for part-to-whole comparisons.

html
<div class="jl-chart" data-type="bar" data-stacked="true"
  data-series='[{"name":"Production","data":[20,28,24,32]},{"name":"Preview","color":"var(--info)","data":[12,9,15,11]}]'></div>
tsx
<Chart type="bar" stacked series={[
  { name: "Production", data: [20, 28, 24, 32] },
  { name: "Preview", color: "var(--info)", data: [12, 9, 15, 11] },
]} />

Sparkline

type="sparkline" is a tiny, axis-less inline trend — perfect under a KPI value.

html
<div class="jl-chart" data-type="sparkline" data-height="40" data-values="8,12,9,14,13,18,17,20"></div>
tsx
<Chart type="sparkline" height={40} data={[8, 12, 9, 14, 13, 18, 17, 20]} />

Props

React

Chart extends React.HTMLAttributes<HTMLDivElement>.

PropTypeDefaultDescription
datanumber[] | { label, value }[]Single-series data
series{ name, data, color? }[]Multi-series data (overrides data)
type"area" | "line" | "bar" | "sparkline""area"Visual form
stackedbooleanfalseStack bar series instead of grouping
referenceLinenumber | { value, label?, color? }Dashed threshold line
showLegendbooleanmultiShow the series legend
heightnumber200 (44 spark)Plot height (px); width is fluid
colorstring--accentSingle-series color
showGridbooleantrueHorizontal grid lines
showAxisbooleantrueValue + label axes
showDotsbooleanfalseAlways show point markers (line/area)
valueFormat(v: number) => stringStringFormat ticks + tooltip values

Vue

Same options. valueFormat maps to :value-format, referenceLine to :reference-line, showLegend to :show-legend.

CSS classes (HTML)

ClassPurpose
.jl-chartRoot (self-measuring); the SVG + tooltip are generated inside
.jl-chart__grid / __axisGrid lines and axis labels
.jl-chart__area / __line / __bar / __dotSeries marks
.jl-chart__ref / __ref-labelReference/threshold line + label
.jl-chart__legend / __swatchMulti-series legend
.jl-chart__cursor / __tipHover cursor line and value tooltip

Data attributes on the root: data-values (comma-separated), data-labels, data-type (area/line/bar/sparkline), data-height, data-grid="false", data-axis="false", data-dots="true", data-suffix. Multi-series: data-series (a JSON array of { name, data, color? }) plus data-stacked="true". Reference line: data-ref, data-ref-label, data-ref-color.