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.
Semicircular dial with active/inactive tick distinction. The active range is bold and dark, inactive fades to near-invisible.
Animated tick marks draw on scroll. Pointer sweeps to value. Engraved surface container.
Same component, different data. All parameters configurable via JS options object.
A physical disc — not a flat pie chart. Segments are engraved arcs in a recessed plate. The raised centre hub floats above the surface.
Grey shades distinguish segments without colour. The disc grooves create natural visual separation.
Larger disc, more segments. Concentric groove rings add texture and reinforce the physical material feel.
Deeply engraved wedge segments pressed into the neumorphic surface. Pill bar colours. Dark divider grooves between segments with white highlights.
Four segments — engraved into the surface with dark border and highlight ridge. Colours match the pill bar palette.
Five segments — the engraved grooves between them are as important as the fills. Each segment is pressed in, not raised.
Vertical pill-shaped tubes — engraved containers with coloured fills rising from the bottom. Like test tubes lit from inside.
Each bar is an engraved tube. Fill animates up from zero on scroll. Colours customisable per bar.
Thinner tubes, more bars. Same component, different proportions via barWidth option.
Same engraved tube aesthetic as the vertical pill bars, rotated horizontal. Thinner profile — perfect for ranked lists and progress comparisons.
Thin 20px tubes. Each fills from left on scroll. Labels left-aligned, values right.
Slightly thicker 28px tubes. Different colours per bar. Staggered 80ms fill animation.
Engraved grid lines, tick-mark axes, raised bar bodies with a subtle top highlight. Each bar grows up from zero on scroll.
Default dark bars on engraved grid. Same axis groove technique as the line and gauge charts.
Custom bar colours per data point. Animate in staggered by 60ms per bar.
Same engraved aesthetic, bars grow left to right. Ideal for ranked lists, comparisons, and category breakdowns.
Labels sit left of axis, values appear at bar tip. Engraved vertical grid with tick marks.
Custom colours per bar. The horizontal format lets labels read naturally without rotation.
Engraved axes and grid lines — raised ridges pressed into the surface. The data line draws itself on scroll. Hover dots show tooltips.
JB Charts is completely standalone. Works with DivDrop or on any plain HTML page.
Pure vanilla JS and CSS. No Chart.js, no D3, no canvas. Just two files.
Reads data-dd-theme automatically. Switch themes — charts update instantly.
All charts use viewBox. They scale fluidly to any container width.
SVG role="img" + aria-label. Keyboard-navigable data points.
IntersectionObserver fires animations when the chart enters the viewport.
Use data-jb-chart + data-jb-opts for zero-JS usage.
<!-- 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>