Skip to content

Instantly share code, notes, and snippets.

@clhenrick
Created May 8, 2019 22:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save clhenrick/57c315ef6d974cd1a7e0356ebdf69b5c to your computer and use it in GitHub Desktop.
Save clhenrick/57c315ef6d974cd1a7e0356ebdf69b5c to your computer and use it in GitHub Desktop.
D3 Scatterplot without data join
license: mit

D3 Scatterplot Without Data Join

A somewhat convoluted demo of creating a simple scatterplot using ES6 template literals. The common-tags package is used for its handy html tag function that strips out line breaks and white space from the template literal string.

The point of this example is just to show you don't need to use d3-selection's selection.data().enter().append() methods to render SVG shapes from data.

Built with blockbuilder.org

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://unpkg.com/common-tags"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<script>
var xmlns = "http://www.w3.org/2000/svg";
var margin = { top: 20, left: 50, right: 10, bottom: 50 };
var width = 500;
var height = 500;
var body = document.querySelector("body");
// NOTE: creating an SVG element using vanilla JS requires document.createElementNS
var svg = body.appendChild(document.createElementNS(xmlns,"svg"))
svg.setAttribute("width", 500);
svg.setAttribute("height", 500);
var g = svg.appendChild(document.createElementNS(xmlns, "g"));
g.setAttribute("transform", `translate(${margin.left}, ${margin.top})`);
var xScale = d3.scaleLinear()
.range([0, width - margin.left - margin.right]);
var yScale = d3.scaleLinear()
.range([height - margin.top - margin.bottom, 0]);
var cScale = d3.scaleOrdinal(d3.schemeCategory10);
function xAxis(g) {
g.attr("transform", `translate(0, ${height - margin.bottom - margin.top})`)
.call(d3.axisBottom(xScale));
}
function yAxis(g) {
g.call(d3.axisLeft(yScale));
}
function parseRow(d) {
return {
sepal_length: +d.sepal_length,
sepal_width: +d.sepal_width,
petal_length: +d.petal_length,
petal_width: +d.petal_width,
species: d.species
}
}
function renderCircle(d) {
return commonTags.html`
<circle
cx="${xScale(d.sepal_width)}"
cy="${yScale(d.sepal_length)}"
fill="${cScale(d.species)}"
r="2.5"
/>
`;
}
function main(data) {
console.log(data);
xScale.domain(d3.extent(data, d => d.sepal_width));
yScale.domain(d3.extent(data, d => d.sepal_length));
g.appendChild(
d3.select(document.createElementNS(xmlns, "g"))
.call(xAxis)
.node()
)
g.appendChild(
d3.select(document.createElementNS(xmlns, "g"))
.call(yAxis)
.node()
)
g.appendChild(document.createElementNS(xmlns, "g"))
.innerHTML = commonTags.html`${data.map(renderCircle)}`;
}
d3.csv("https://gist.githubusercontent.com/clhenrick/fe82108ca72121b3e2000ced4e36a53b/raw/eedfd982b5324d62c2c2b69171b937db73f41f29/flowers.csv", parseRow)
.then(main);
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment