Part of the DivDrop ecosystem · Standalone · No dependencies

Charts that feel
carved from stone

JB Charts brings neumorphic depth to data. Engraved containers, raised fills, physical shadows — every chart feels like it belongs on the surface, not floating above it.

Chart type 01

Gauge

Semicircular dial with active/inactive tick distinction. The active range is bold and dark, inactive fades to near-invisible.

Temperature gauge

Animated tick marks draw on scroll. Pointer sweeps to value. Engraved surface container.

Performance gauge

Same component, different data. All parameters configurable via JS options object.

Chart type 02

Disc

A physical disc — not a flat pie chart. Segments are engraved arcs in a recessed plate. The raised centre hub floats above the surface.

Revenue breakdown

Grey shades distinguish segments without colour. The disc grooves create natural visual separation.

User acquisition

Larger disc, more segments. Concentric groove rings add texture and reinforce the physical material feel.

Chart type 02b

Engraved Pie

Deeply engraved wedge segments pressed into the neumorphic surface. Pill bar colours. Dark divider grooves between segments with white highlights.

Revenue breakdown

Four segments — engraved into the surface with dark border and highlight ridge. Colours match the pill bar palette.

User acquisition

Five segments — the engraved grooves between them are as important as the fills. Each segment is pressed in, not raised.

Chart type 03

Pill Bars

Vertical pill-shaped tubes — engraved containers with coloured fills rising from the bottom. Like test tubes lit from inside.

Activity metrics

Each bar is an engraved tube. Fill animates up from zero on scroll. Colours customisable per bar.

Performance by category

Thinner tubes, more bars. Same component, different proportions via barWidth option.

Chart type 04b

Horizontal Pills

Same engraved tube aesthetic as the vertical pill bars, rotated horizontal. Thinner profile — perfect for ranked lists and progress comparisons.

Activity breakdown

Thin 20px tubes. Each fills from left on scroll. Labels left-aligned, values right.

Feature adoption

Slightly thicker 28px tubes. Different colours per bar. Staggered 80ms fill animation.

Chart type 05

Vertical Bar

Engraved grid lines, tick-mark axes, raised bar bodies with a subtle top highlight. Each bar grows up from zero on scroll.

Monthly revenue

Default dark bars on engraved grid. Same axis groove technique as the line and gauge charts.

Weekly active users

Custom bar colours per data point. Animate in staggered by 60ms per bar.

Chart type 06

Horizontal Bar

Same engraved aesthetic, bars grow left to right. Ideal for ranked lists, comparisons, and category breakdowns.

Traffic sources

Labels sit left of axis, values appear at bar tip. Engraved vertical grid with tick marks.

Feature adoption

Custom colours per bar. The horizontal format lets labels read naturally without rotation.

Chart type 04

Line Chart

Engraved axes and grid lines — raised ridges pressed into the surface. The data line draws itself on scroll. Hover dots show tooltips.

Get started

Drop in two files

JB Charts is completely standalone. Works with DivDrop or on any plain HTML page.

No dependencies

Pure vanilla JS and CSS. No Chart.js, no D3, no canvas. Just two files.

🎨

Theme-aware

Reads data-dd-theme automatically. Switch themes — charts update instantly.

📱

Responsive SVG

All charts use viewBox. They scale fluidly to any container width.

Accessible

SVG role="img" + aria-label. Keyboard-navigable data points.

Scroll-triggered

IntersectionObserver fires animations when the chart enters the viewport.

🔧

Data-attribute API

Use data-jb-chart + data-jb-opts for zero-JS usage.

HTML + JS
<!-- 1. Include the files (after DivDrop CSS if using it) -->
<link rel="stylesheet" href="https://divdrop.io/CDN/CSS/jb-charts.css">
<script src="https://divdrop.io/CDN/JS/jb-charts.js"></script>

<!-- 2. Create a container -->
<div id="myGauge"></div>
<div id="myDisc"></div>
<div id="myBars"></div>
<div id="myLine"></div>

<!-- 3. Initialise with JS -->
<script>
// Gauge
JBCharts.gauge(document.getElementById('myGauge'), {
  value: 24, min: 10, max: 40,
  unit: '°', label: 'Temperature', target: 20
});

// Disc pie
JBCharts.disc(document.getElementById('myDisc'), {
  label: 'Revenue',
  centerValue: '$2.4M', centerLabel: 'Total',
  segments: [
    { label: 'Product',     value: 52 },
    { label: 'Services',    value: 28 },
    { label: 'Consulting',  value: 12 },
    { label: 'Licensing',   value: 8  },
  ]
});

// Pill bars
JBCharts.bars(document.getElementById('myBars'), {
  label: 'Activity',
  bars: [
    { label: 'Relax',    value: 82 },
    { label: 'Cardio',   value: 0  },
    { label: 'Strength', value: 54 },
    { label: 'Stretch',  value: 91 },
  ]
});

// Line chart
JBCharts.line(document.getElementById('myLine'), {
  label: 'Monthly revenue',
  color: '#1a1a1a',
  data: [
    { label: 'Jan', value: 42 },
    { label: 'Feb', value: 58 },
    { label: 'Mar', value: 51 },
    { label: 'Apr', value: 74 },
    { label: 'May', value: 68 },
    { label: 'Jun', value: 91 },
  ]
});
</script>

<!-- Or: zero-JS data-attribute API -->
<div data-jb-chart="gauge"
     data-jb-opts='{"value":24,"min":10,"max":40,"unit":"°"}'>
</div>