function colorWheel(n = 24, options = {}) {
let {
margin = 20,
innerRadius = 100,
outerRadius = 200,
padAngle = 0.01,
padRadius = 100,
cornerRadius = 4
} = options;
let arcGenerator = d3
.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius)
.padAngle(padAngle)
.padRadius(padRadius)
.cornerRadius(cornerRadius);
let wc = wheelColors();
let arcData = d3.range(n).map((i) => ({
startAngle: ((i - 0.5) / n) * Math.PI * 2 + Math.PI / 2,
endAngle: ((i + 0.5) / n) * Math.PI * 2 + Math.PI / 2,
color: wc[i]
}));
let img = svg`<svg width=${margin * 2 + outerRadius * 4}
height=${
(margin + outerRadius) * 2
} style="background-color:${background}">`;
d3.select(img)
.append("g")
.attr(
"transform",
`translate(${margin + outerRadius},${margin + outerRadius})`
)
.selectAll("path")
.data(arcData)
.enter()
.append("path")
.attr("d", arcGenerator)
.attr("fill", (d) => d.color);
let placeMarks = d3
.select(img)
.append("g")
.attr("class", "places")
.attr(
"transform",
`translate(${margin + outerRadius},${margin + outerRadius})`
);
let placePolygon = d3
.select(img)
.append("g")
.attr("class", "placePolygon")
.attr(
"transform",
`translate(${margin + outerRadius},${margin + outerRadius})`
);
let placeSamples = d3
.select(img)
.append("g")
.attr("class", "placeSamples")
.attr(
"transform",
`translate(${margin * 2 + outerRadius * 3},${
margin + outerRadius
})scale(0.6)`
);
placeSamples
.append("rect")
.attr("fill", "none")
.attr("stroke", "black")
.attr("width", outerRadius * 2)
.attr("height", innerRadius * 2)
.attr("x", -outerRadius)
.attr("y", -innerRadius);
img.setPlaces = (places, close) => {
let pts = places.map((d) => [
((innerRadius + outerRadius) / 2) * Math.cos((d / n) * Math.PI * 2),
((innerRadius + outerRadius) / 2) * Math.sin((d / n) * Math.PI * 2)
]);
placeMarks.selectAll("circle").remove();
placeMarks
.selectAll("circle")
.data(pts)
.join("circle")
.attr("cx", (d) => d[0])
.attr("cy", (d) => d[1])
.attr("r", 5)
.attr("fill", "black");
placePolygon.selectAll("polygon,polyline").remove();
placePolygon
.append(close ? "polygon" : "polyline")
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none")
.attr(
"points",
pts.map((d) => "" + d)
);
placeSamples.selectAll("circle").remove();
const np = places.length;
placeSamples
.selectAll("circle")
.data(places)
.enter()
.append("circle")
.attr("fill", (d) => arcData[d].color)
.attr("r", innerRadius * 0.5)
.attr("cx", (d, i) => ((i - (np - 1) / 2) / np) * outerRadius * 0.9);
};
img.getPalette = (places) => {
return places.map((d) => arcData[d].color);
};
return img;
}