# US flag factorization diagrams

. lecture : 3 minutes

I got bored. That's what happens when I stumble upon factorisation diagrams (jasondavies.com/factorisation-diagrams), while wanting to try the javascript library D3.js.

If it works, you should see a series of flags similar to the one above. (javascript needs to be enabled in your browser).

```
var FLAGHEIGHT = 400;
var fieldWidth = 0.76 * FLAGHEIGHT;
var fieldHeight = FLAGHEIGHT * 7 / 13;
// ** Fonctions **
// Draw an American Flag
// selection    The SVG element on which to draw the flag.
// height       The height of the flag. (Its width will be computed based
//              on the standard dimensions of an American flag.)
// from http://www.fascinatedwithsoftware.com/blog/post/2012/11/06/And-Now-an-SVG-American-Flag-with-D3.aspx
// voir aussi les spécification du drapeau : https://en.wikipedia.org/wiki/Flag_of_the_United_States#Specifications
function drawFlag(selection, height) {
// From the height, derive other measurements.
var width = height * 1.9;
selection.attr("height", height);
selection.attr("width", width);
var g = selection.append("g");
var x=0;
var y=0;
// Make the white background.
g.append("rect")
.attr("x", x)
.attr("y", y)
.attr("width", width)
.attr("height", height)
.attr("fill", "white");
// Make the red stripes.
d3.range(7).forEach(function (d) {
g.append("rect")
.attr("x", x)
.attr("y", y + d * 2 * height / 13)
.attr("width", width)
.attr("height", height / 13)
.attr("fill", "#b22234"); // était : #C40043
});
// Make the blue field.
g.append("rect")
.attr("x", x)
.attr("y", y)
.attr("width", fieldWidth)
.attr("height", fieldHeight)
.attr("fill", "#3c3b6e") // était : #002654
}
// Draw a star. This function just creates the SVG <path> element and wraps
// it in a <g>. It is up to the caller to set the fill and/or stroke on the
// path after this function returns.
// parent      - The element to which the returned <g> will be appended.
// nPoints     - The number of points the star should have.
function drawStar(parent, nPoints, size) {
// outerRadius - The radius of a circle that would tightly fit the star's outer vertexes.
// innerRadius - The radius of a circle that would tightly fit the star's inner vertexes.
var outerRadius = 0.0616 * size / 2;
var innerRadius = outerRadius * Math.sin(Math.PI / 10) / Math.sin(7 * Math.PI / 10);
var xCenter = 0;
var yCenter = 0;
var lineGenerator = d3.svg.line()
.x(function (d,i) {
var angle = i * Math.PI / nPoints - Math.PI / 2;
return xCenter + radius * Math.cos(angle);
})
.y(function (d,i) {
var angle = i * Math.PI / nPoints - Math.PI / 2;
return yCenter + radius * Math.sin(angle);
});
return parent.append("g").attr("class", "star")
.append("path")
.datum(d3.range(nPoints * 2))
.attr("d", lineGenerator);
}
function starDiagram(selection, factors, size) {
if (factors.length) {
var n = factors.pop(),
offset = n === 4 ? 45 : n === 2 ? 0 : -90,
radius = n * size / (n + 2),
δy = n & 1 ? (radius / 2) * (1 - Math.cos(Math.PI / n)) : 0;
selection.selectAll("g")
.data(d3.range(n))
.enter().append("g")
.attr("transform", function(d) {
var angle = d * 360 / n + offset;
return "translate(0," + δy + ")rotate(" + angle + ")translate(" + radius + ")rotate(" + -angle + ")";
})
.call(starDiagram, factors, 2 * size / (n + 2));
} else
// circles
//selection.append("circle").attr("r", size * .8).attr("fill", "white");
// stars
drawStar(selection, 5, fieldHeight*size*.24).attr("fill", "white");
}
function primeFactors(n) {
var factors = [],
f;
while (n > 1) {
factors.push(f = factor(n));
n /= f;
}
return factors;
}
function factor(n) {
if (n % 4 === 0) return 4;
for (var i = 2; i <= n / 2; i++) {
if (n % i === 0) return i;
}
return n;
}
// ** Code **
// je vide le div
d3.select("#vis").html("");
// liste des drapeaux à dessiner
// Cf. http://bost.ocks.org/mike/selection/ & http://www.macwright.org/presentations/dcjq/
var svg = d3.select("#vis").selectAll("svg")
// "data is not a property of the selection, but a property of its elements"
.data([1, 2, 3, 5, 11, 15, 20, 23, 24, 25, 27, 32, 36, 49, 50, 51, 101])
// "Enter - There was no matching element for a given datum." ; http://bost.ocks.org/mike/selection/#enter-update-exit
.enter()
.append("svg")
.style("margin", "0 auto 3em")
.style("display", "block");
// drapeau
svg.each(function(d) {
d3.select(this).call(drawFlag, FLAGHEIGHT);
});
// étoiles
svg.append("g")
// svg translations: https://www.dashingd3js.com/svg-group-element-and-d3js
.attr("transform", "translate(" + [fieldWidth / 2, fieldHeight / 2] + ")")
.each(function(d) {
d3.select(this).call(starDiagram, primeFactors(d), fieldHeight / 2.2);
});
// numéro
svg.append("text")
.attr("dy", "1em")
.attr("fill", "white")
.style("font-size", "10px")
.text(String);
```

Based on jasondavies.com/factorisation-diagrams © Jason Davies 2012, and on fascinatedwithsoftware.com/…/And-Now-an-SVG-American-Flag-with-D3.aspx © Larry Spencer 2012.

If you look at this page's source code, please be kind. I did that in a hurry and I'm just starting to use D3.js :))

### Manu·e

La personne qui a créé Épinards & Caramel. ☕🤔🐙