Here's a scatterplot of some randomly made up fireworks display datapoint compared to the reported enjoyment of said fireworks display by an equally made up respondent.
What's cool about this is that the patterns that make up the fireworks are created using the superformula, a parameterized shape with tremendous flexibility.
xxxxxxxxxx
<html>
<head>
<title>Superformula Fireworks</title>
<meta charset="utf-8" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="superformula.js" type="text/JavaScript"></script>
</head>
<style>
svg {
height: 850px;
width: 900px;
border: 1px solid gray;
background: black;
}
g.am-axis text {
font-size: 8px;
}
.domain {
fill: none;
}
.tick > line {
stroke: white;
stroke-width: 1px;
stroke-opacity: .25;
}
.tick > text {
fill: white;
}
</style>
<body>
<div id="viz">
<svg>
</svg>
</body>
<footer>
<script>
var xAxisName = ["time of day", "number of children", "crowd", "distance from fireworks", "number of drinks", "patriotism"];
var xAxisDomain = [[2,12], [0,6], [2, 1000], [0.1,10], [0,12], [1,100]];
var yAxisName = "Enjoyment";
randomDomain = parseInt(Math.random() * 6);
d3.select("svg").append("text").text("Enjoyment").style("fill", "white").attr("transform", "translate(830,350) rotate(90)")
d3.select("svg").append("text").text(xAxisName[randomDomain]).style("fill", "white").attr("transform", "translate(20,510)")
xAxis = d3.svg.axis().scale(d3.scale.linear().domain(xAxisDomain[randomDomain]).range([0,800])).orient("bottom").tickSize(425).ticks(4);
d3.select("svg").append("g").attr("transform", "translate(0,50)").attr("id", "xAxisG").call(xAxis);
yAxis = d3.svg.axis().scale(d3.scale.linear().domain([0,10]).range([450,50])).orient("right").ticks(10).tickSize(800);
d3.select("svg").append("g").attr("id", "yAxisG").call(yAxis);
var randomData = d3.range(100).map(function (d,i) {
var randY = (Math.random() * 400) + 50;
var randX = (Math.random() * 700) + 50;
return {x: randX, y: randY}
});
var superCircle = d3.superformula()
.type("circle")
.size(25);
d3.select("svg").selectAll("path.fireworks")
.data(randomData)
.enter()
.append("path")
.attr("transform", function (d) {return "translate(400,800)"})
.attr("d", superCircle)
.style("fill", "darkgray")
.each(function (d) {
randomShape = d3.superformulaTypes[parseInt(Math.random() * 21)];
d3.select(this)
.transition()
.delay(function () {return Math.random() * 5000})
.transition()
.duration(function () {return (Math.random() * 500) + 100})
.attr("transform", function (d) {return "translate(" + d.x + "," + d.y + ")"})
.transition()
.duration(function () {return (Math.random() * 100) + 50})
.attr("d", function() {
var randomSize = parseInt((Math.random() * 1000) + 100);
var fireworkPattern = d3.superformula().type(randomShape).size(randomSize);
return fireworkPattern();
})
.style("fill", function () {
var randomColor = parseInt(Math.random() * 12)
return ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"][randomColor];
})
.transition()
.duration(500)
.attr("d", function() {
var randomSize = parseInt((Math.random() * 1000) + 100);
var fireworkPattern = d3.superformula().type(randomShape).size(35);
return fireworkPattern();
})
.style("fill-opacity", .75)
.style("stroke-width", 1)
.style("stroke-opacity", .25)
.style("stroke", "white")
})
</script>
</footer>
</html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js