Skip to content

Instantly share code, notes, and snippets.

@officeofjane
Last active April 26, 2019 06:18
Show Gist options
  • Save officeofjane/b3e369e60a4c907ebd09673582349bed to your computer and use it in GitHub Desktop.
Save officeofjane/b3e369e60a4c907ebd09673582349bed to your computer and use it in GitHub Desktop.
SVG icons unit chart
license: mit

Unit chart using isotypes. Code adapted from Alan Smith's block, Pictogram grid in d3js.

Icon by Setyo Ari Wibowo from The Noun Project.

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body {
font-family: "avenir next", Arial, sans-serif;
font-size: 12px;
color: #696969;
margin: 0;
}
.text {
margin-right: 50px;
font-size: 14px;
}
article {
width: 960px;
display: flex;
align-items: center;
}
</style>
</head>
<body>
<article>
<div id="svg-grid"></div>
<div class="text">Here is some explanatory text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut id lacus quis mauris auctor euismod. Pellentesque consectetur turpis in lorem laoreet, at porta metus aliquam. Etiam eget purus et dolor auctor volutpat. Nulla vitae nibh tempor, sollicitudin eros et, gravida enim. Duis tempor, nulla quis convallis venenatis, turpis erat molestie nibh, quis aliquet nibh ex in libero. Praesent interdum ipsum eu felis pellentesque, vel imperdiet neque ullamcorper.</div>
</article>
<script>
let margin = {top:50, right:50, bottom:50, left:50},
width = 550 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// svg container
let svg = d3.select("#svg-grid")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
let numIcons = 84;
let numAcross = 10;
let iconPadding = 5;
let squareWidth = Math.floor(width/numAcross);
let iconWidth = squareWidth - iconPadding*2;
// define icon and store it in svg <defs> elements as a reusable component
svg.append("defs")
.append("g")
.attr("id", "iconCustom")
.append("path")
.attr("d","M9.14.86H8.86A.86.86,0,0,0,8,0H.86A.86.86,0,0,0,0,.86V8a.86.86,0,0,0,.86.86H9.14A.86.86,0,0,0,10,8V1.71A.86.86,0,0,0,9.14.86Zm0,7.57A.42.42,0,0,1,8.71,8V1.29h.43a.42.42,0,0,1,.43.43V8A.42.42,0,0,1,9.14,8.43Zm-.57,0H.86A.42.42,0,0,1,.43,8V.86A.42.42,0,0,1,.86.43H8a.42.42,0,0,1,.43.43V8A.71.71,0,0,0,8.57,8.43ZM1.14,4.14H4V1.29H1.14Zm.29-2.57H3.71V3.86H1.43ZM1.14,4.86H4v.29H1.14Zm0,.71H4v.29H1.14Zm0,.71H4v.29H1.14Zm0,.71H4v.29H1.14ZM4.86,5.57H7.71v.29H4.86Zm0,.71H7.71v.29H4.86Zm0,.71H7.71v.29H4.86Zm0-5.71H7.71v.29H4.86Zm0,.71H7.71v.29H4.86Zm0,.71H7.71V3H4.86Zm0,.71H7.71v.29H4.86Zm0,.71H7.71v.29H4.86Zm0,.71H7.71v.29H4.86Z")
.attr("transform", "scale(" + iconWidth / 10 + ")");
// draw icons
drawIcons(numIcons, numAcross, iconWidth, iconPadding, svg);
function drawIcons(count, row, width, padding, canvas) {
// count: number of icons
// nAcross: number of icons in each row
// width: width of icon
// padding: padding around each icon
// canvas: canvas element to draw on
let data = d3.range(count);
// compute dimensions
let nAcross = row;
let nDown = Math.ceil(count/nAcross);
let squareWidth = width + padding*2;
console.log(squareWidth);
// width and height of icon area
let w = nAcross * squareWidth;
let h = nDown * squareWidth;
// clear previously drawn chart
d3.select("#icons").remove();
// append group with specfied dimensions
let area = canvas.append("g")
.attr("id", "icons")
.attr("width", w)
.attr("height", h);
// draw icons
area.selectAll("use")
.data(data)
.enter()
.append("use")
.attr("xlink:href", "#iconCustom")
.attr("id", function(d) {
return "icon"+d;
})
.attr("x", function(d) { return d%nAcross * squareWidth; })
.attr("y", function(d) { return Math.floor(d/nAcross) * squareWidth; })
.style("fill", function(d) {
if (d > 12) {
return "#1c255c";
} else {
return "#ff2c50";
}
})
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment