I build dashboards for small teams and school projects. I also help my cousin run a tiny coffee shop site. So yes, I live in charts. I’ve used Chart.js, D3.js, ECharts, Highcharts, ApexCharts, and Plotly.js.
Lately I've also been testing the lean but capable EJSChart, which lets me stand up bar, line, and pie charts in minutes without extra bloat.
Some days they’re friendly. Some days they’re moody. You know what? That’s normal.
If you prefer the long-form story with more screenshots, I broke it down in this field report on making charts with vanilla JavaScript right here.
Let me walk you through what I liked, what bugged me, and real bits of code that I used.
What I need from a chart, plain and simple
- Looks good without a lot of fuss.
- Loads fast on phones.
- Tooltips that don’t glitch.
- Can theme to match brand colors.
- Works with a screen reader, or at least doesn’t block it.
For developers chasing raw rendering speed on low-power devices, my benchmark notes on high-performance JavaScript chart libraries might help—have a peek at them in this deep dive.
That’s my short list. Not fancy. Just real.
Chart.js — my “get it done by lunch” buddy
For quick work, Chart.js feels like a friend. I used it for weekly coffee sales. Time was tight. The boss (my cousin) wanted bars by noon. We made it.
Example I shipped:
<canvas id="sales" height="120"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
const ctx = document.getElementById('sales').getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'],
datasets: [{
label: 'Cups Sold',
data: [34, 28, 41, 39, 45, 60, 52],
backgroundColor: '#4e79a7'
}]
},
options: {
responsive: true,
plugins: {
legend: { display: false },
tooltip: {
callbacks: {
// I showed price per day at $3.50 per cup
label: c => `$${(c.parsed.y * 3.5).toFixed(2)} revenue`
}
}
},
scales: { y: { beginAtZero: true } }
}
});
</script>
What I loved:
- Clean look right away.
- Good docs.
- Canvas is smooth with small to medium data.
What bugged me:
- With thousands of points, it can feel slow.
- Custom legends and advanced stuff take more code.
Still, if someone says “we need a chart today,” this is where my hands go.
For even more context, I compared Chart.js with several of its peers in a hands-on roundup, noting wins and misses, which you can read here.
D3.js — powerful, but bring snacks
I used D3 for a school fitness report. We tracked a heart rate line over time. I needed custom ticks and a highlight band for the target zone. D3 let me do all that. But it’s more like building a bike than riding one.
Tiny example I used as a base:
<svg id="hr" width="420" height="200"></svg>
<script src="https://cdn.jsdelivr.net/npm/d3@7"></script>
<script>
const data = [
{ t: 0, bpm: 72 }, { t: 1, bpm: 88 }, { t: 2, bpm: 110 },
{ t: 3, bpm: 124 }, { t: 4, bpm: 118 }, { t: 5, bpm: 95 }
];
const svg = d3.select('#hr');
const w = +svg.attr('width'), h = +svg.attr('height');
const m = { top: 10, right: 20, bottom: 25, left: 30 };
const x = d3.scaleLinear().domain(d3.extent(data, d => d.t)).range([m.left, w - m.right]);
const y = d3.scaleLinear().domain([60, 140]).range([h - m.bottom, m.top]);
svg.append('g')
.attr('transform', `translate(0,${h - m.bottom})`)
.call(d3.axisBottom(x).ticks(6));
svg.append('g')
.attr('transform', `translate(${m.left},0)`)
.call(d3.axisLeft(y).ticks(5));
const line = d3.line().x(d => x(d.t)).y(d => y(d.bpm));
svg.append('path')
.datum(data)
.attr('fill', 'none')
.attr('stroke', '#e15759')
.attr('stroke-width', 2)
.attr('d', line);
</script>
What I loved:
- Full control. Every tick, every color, every weird shape.
- Great for teaching and data stories.
What bugged me:
- Long ramp.
- With big data in SVG, it slows down. I switch to canvas when points get heavy.
If you need a chart that doesn’t exist yet, D3 is your tool belt.
If open-source flexibility is your thing, you might enjoy my candid notes on a handful of other community-driven chart tools, available at this link.
ECharts — great defaults, dashboard friendly
I used ECharts for a city weather panel. Line charts, a tiny map, and a donut. It looked “wow” fast. Mobile pan and zoom felt smooth, too.
Real snippet I used:
<div id="temp" style="height:260px"></div>
<script src="https://cdn.jsdelivr.net/npm/echarts@5"></script>
<script>
const chart = echarts.init(document.getElementById('temp'));
const option = {
title: { text: 'Daily Temp' },
tooltip: { trigger: 'axis' },
xAxis: { type: 'category', data: ['Mon','Tue','Wed','Thu','Fri'] },
yAxis: { type: 'value' },
series: [{ type: 'line', data: [68, 71, 75, 78, 73], smooth: true, areaStyle: {} }]
};
chart.setOption(option);
window.addEventListener('resize', () => chart.resize());
</script>
What I loved:
- Stylish themes.
- Smooth zoom and tooltips.
- Big data feels okay.
What bugged me:
- The build is chunky. On slow phones, first load takes a bit.
- Docs are huge; you can get lost.
Still, for dashboards with many charts, ECharts treats you well.
Speaking of circular visuals, I also documented my wins and fails while chasing a smooth animated pie chart in vanilla JavaScript—see the breakdown here.
Highcharts, ApexCharts, and Plotly — quick takes
Highcharts
- I used it for a fund report with export buttons. PNG and CSV worked great.
- Clear look, good legends, nice hover.
- Paid for business use. Keep that in mind.
ApexCharts
- I used it inside React. The wrapper was simple.
- Nice defaults for line and area.
- Some odd spacing with long labels, but fixable.
Plotly.js
- I used it for a science lab plot.
- Strong on zoom, hover compare, and saving images.
- Bundle can feel heavy for tiny pages.
Here’s a tiny Highcharts example I sent to a client:
<div id="hc" style="height:240px"></div>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script>
Highcharts.chart('hc', {
title: { text: 'Quarterly Score' },
xAxis: { categories: ['Q1','Q2','Q3','Q4'] },
series: [{ name: 'Score', data: [72, 78, 81, 86], color: '#59a14f' }],
credits: { enabled: false }
});
</script>
And if you ever need finance-style candlestick visuals, I stress-tested seven different JavaScript options and posted the raw results in this write-up.
For an additional perspective, ApexCharts maintains a concise JavaScript chart comparison table you can skim, and the folks at Cybrosys share a helpful [comparison of popular JavaScript charting libraries](https
