D3js

D3, version: 5.16.0

Example based on https://observablehq.com/@yusjs/d3-bar-chart

Template:

<div id="myChart"></div>

Script:

SR.render({}, async () => { await eval(await fetch('https://cdnjs.cloudflare.com/ajax/libs/d3/5.16.0/d3.min.js').then((res) => res.text())); const data = (await d3.csv("https://gist.githubusercontent.com/mbostock/81aa27912ad9b1ed577016797a780b2c/raw/3a807eb0cbb0f5904053ac2f9edf765e2f87a2f5/alphabet.csv", ({ letter, frequency }) => ({ name: letter, value: +frequency }))).sort((a, b) => b.value - a.value) console.log("data", data) const width = 700; const height = 500; const margin = ({ top: 30, right: 0, bottom: 30, left: 40 }); const color = "steelblue"; const xAxis = g => g .attr("transform", `translate(0,${height - margin.bottom})`) .call(d3.axisBottom(x).tickFormat(i => data[i].name).tickSizeOuter(0)); const yAxis = g => g .attr("transform", `translate(${margin.left},0)`) .call(d3.axisLeft(y).ticks(null, data.format)) .call(g => g.select(".domain").remove()) .call(g => g.append("text") .attr("x", -margin.left) .attr("y", 10) .attr("fill", "currentColor") .attr("text-anchor", "start") .text(data.y)); const x = d3.scaleBand() .domain(d3.range(data.length)) .range([margin.left, width - margin.right]) .padding(0.1); const y = d3.scaleLinear() .domain([0, d3.max(data, d => d.value)]).nice() .range([height - margin.bottom, margin.top]); const chart = d3.create("div"); const svg = d3.create("svg"); svg.append("g") .attr("fill", color) .selectAll("rect") .data(data) .join("rect") .attr("x", (d, i) => x(i)) .attr("y", d => y(d.value)) .attr("height", d => y(0) - y(d.value)) .attr("width", x.bandwidth()); svg.append("g") .call(xAxis); svg.append("g") .call(yAxis); chart.append("svg").attr("viewBox", [0, 0, width, height]).html(svg.html()); document.querySelector('#myChart').innerHTML = chart.html(); });