Using SVG patterns to create small multiple pie charts with image fills. I dynamically calculate the spacing and size of the pattern to allow for space between each pie chart.
forked from tlfrd's block: Pie Chart with Image Pattern
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
.note {
stroke: purple;
stroke-width: 0.5px;
}
.note-percent {
fill: purple;
opacity: 0.5;
stroke: purple;
}
</style>
</head>
<body>
<script>
var width = 960,
height = 500;
var imageURL = "https://i.imgur.com/2yueu7S.png";
var initialPosition = { x: 50, y: 50 };
var rectSize = { width: 100, height: 50 };
var spacing = {
h: 30,
v: 30
}
var gridLength = 6;
var dataLength = 28;
var data = d3.range(0, dataLength, 1);
var dataGrid = [];
data.forEach(function(a, i) {
var dataObj = {
percent: Math.random(),
x: i % gridLength,
y: Math.floor(i / gridLength)
};
dataGrid.push(dataObj);
});
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
svg.append("defs")
.append("pattern")
.attr("id", "money")
.attr('patternUnits', 'userSpaceOnUse')
.attr("width", rectSize.width + spacing.h)
.attr("height", rectSize.height + spacing.v)
.attr("x", initialPosition.x + rectSize.width + spacing.h)
.attr("y", initialPosition.y + rectSize.height + spacing.v)
.append("image")
.attr("xlink:href", imageURL)
.attr("width", rectSize.width)
.attr("height", rectSize.height);
var rects = svg.append("g").selectAll("rect")
.data(dataGrid)
.enter().append("rect")
.attr("class", "note")
.attr("x", function(d) {
return initialPosition.x + (rectSize.width + spacing.h) * d.x;
})
.attr("y", function(d) {
return initialPosition.y + (rectSize.height + spacing.v) * d.y;
})
.attr("width", rectSize.width)
.attr("height", rectSize.height)
.attr("fill", "url(#money)");
var percentRects = svg.append("g").selectAll("rect")
.data(dataGrid)
.enter().append("rect")
.attr("class", "note-percent")
.attr("x", function(d) {
return initialPosition.x + (rectSize.width + spacing.h) * d.x;
})
.attr("y", function(d) {
return initialPosition.y + (rectSize.height + spacing.v) * d.y;
})
.attr("width", 0)
.attr("height", rectSize.height);
percentRects
.transition()
.duration(500)
.attr("width", function(d) {
return rectSize.width * d.percent
})
</script>
</body>
https://d3js.org/d3.v4.min.js