{
const height = 520;
const margin = { top: 0, right: 20, bottom: 20, left: 20 };
const vertices = 50;
const ellipse = d3
.range(vertices)
.map((i) => [
(height * (1 + 0.88 * Math.cos((i / (vertices / 2)) * Math.PI))) / 2,
(height * (1 + 0.88 * Math.sin((i / (vertices / 2)) * Math.PI))) / 2
]);
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height + 0);
const voronoi = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const labels = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const pop_labels = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const bigFormat = d3.format(",.0f");
const seed = seedrandom(20);
const voronoiTreeMap = d3.voronoiTreemap().prng(seed).clip(ellipse);
// Apply Voronoi Treemap to Data
voronoiTreeMap(data_hierarchy);
// Assign colors to the nodes
// colorHierarchy(data_hierarchy)
// Node Processing
const allNodes = data_hierarchy
.descendants()
.sort((a, b) => b.depth - a.depth)
.map((d, i) => Object.assign({}, d, { id: i })); //원래 배열의 각 요소에 id 속성을 추가한 새로운 배열을 반환
// Voronoi Cell Rendering
voronoi
.selectAll("path")
.data(allNodes)
.enter()
.append("path")
.attr("d", (d) => "M" + d.polygon.join("L") + "Z")
.style("fill", (d) => {
// console.log("data test", d.data.age);
return colorSelect2(d.data.sex, d.data.age);
})
.attr("stroke", "#fff")
.attr("stroke-width", 2)
.style("fill-opacity", (d) => (d.depth === 2 ? 0.9 : 0))
.attr("pointer-events", (d) => (d.depth === 2 ? "all" : "none"))
.on("mouseover", function (event, d) {
console.log("test", d);
let label = labels.select(`.label-${d.id}`);
label.style("opacity", 1);
})
.on("mouseout", function (event, d) {
let label = labels.select(`.label-${d.id}`);
label.style("opacity", 0);
})
.transition()
.duration(0)
// .attr('stroke-width', 2)
.attr("stroke-width", (d) => 7 - d.depth * 4);
const key_h = 17;
const keys_women = svg
.selectAll("keys")
.data(key_age)
.enter()
.append("rect")
.attr("x", height + 50)
.attr("y", (d, i) => height / 2 - key_h * 9 + key_h * i)
.attr("width", 10)
.attr("height", key_h)
// .style('fill', 'red')
.attr("stroke", "white")
.style("fill", (d) => colorSelect2("Women", d.age));
const keys_men = svg
.selectAll("keys")
.data(key_age)
.enter()
.append("rect")
.attr("x", height + 50 + 30)
.attr("y", (d, i) => height / 2 - key_h * 9 + key_h * i)
.attr("width", 10)
.attr("height", key_h)
// .style('fill', 'red')
.attr("stroke", "white")
.style("fill", (d) => colorSelect2("Men", d.age));
const keys_text = svg
.selectAll("text")
.data(key_age)
.enter()
.append("text")
.attr("x", height + 50 + 20)
.attr("y", (d, i) => height / 2 - key_h * 9 + key_h * i + key_h / 4)
.text((d) => d.age)
.style("font-size", "10px")
.style("font-family", "Roboto")
.attr("text-anchor", "middle")
.style("fill", "#999");
svg
.append("text")
.text("Women")
.attr("x", height + 50)
.attr("y", (d, i) => height / 2 - key_h * 9 + key_h * i - key_h / 2)
.style("font-size", "12px")
.style("font-family", "Roboto")
.style("font-weight", "bold")
.style("fill", (d) => colorSelect2("Women", 50))
.attr("text-anchor", "end");
svg
.append("text")
.text("Men")
.attr("x", height + 50 + 30 + 10)
.attr("y", (d, i) => height / 2 - key_h * 9 + key_h * i - key_h / 2)
.style("font-size", "12px")
.style("font-family", "Roboto")
.style("font-weight", "bold")
.style("fill", (d) => colorSelect2("Men", 50))
.attr("text-anchor", "start");
// const countryLabel = svg
// .append("text")
// .text(country)
// .attr("x", 10)
// .attr("y", 70)
// .style("font-size", "28px")
// // .style("font-family", "Roboto")
// .style("font-weight", "bold")
// .style("fill", "#111")
// .attr("text-anchor", "start");
// const yearLabel = svg
// .append("text")
// .text(year)
// .attr("x", 10)
// .attr("y", 100)
// .style("font-size", "18px")
// // .style("font-family", "Roboto")
// // .style("font-weight", "bold")
// .style("fill", "#111")
// .attr("text-anchor", "start");
// Voroni Labels
labels
.selectAll("text")
.data(allNodes.filter((d) => d.depth === 2))
.enter()
.append("text")
.attr("class", (d) => {
// console.log("class", d);
return `label-${d.id}`;
})
.attr("text-anchor", "middle")
.attr(
"transform",
(d) => "translate(" + [d.polygon.site.x, d.polygon.site.y + 6] + ")"
)
.text((d) => d.data.name)
.attr("opacity", (d) => (d.data.value > 10 ? 1 : 0))
.attr("cursor", "default")
.attr("pointer-events", "none")
// .attr("fill", "white")
.attr("fill", (d) => (d.data.age >= 30 ? "#fff" : "#333"))
.attr("font-size", "11px")
.style("font-family", "Roboto")
.style("opacity", 0);
// pop_labels
// .selectAll("text")
// .data(allNodes.filter((d) => d.depth === 1))
// .enter()
// .append("text")
// .attr("class", (d) => `label-${d.id}`)
// .attr("text-anchor", "middle")
// .attr(
// "transform",
// (d) => "translate(" + [d.polygon.site.x, d.polygon.site.y + 22.5] + ")"
// )
// .text((d) => `${bigFormat(d.data.value)}`)
// .attr("opacity", (d) => (d.data.value > 10 ? 1 : 0))
// .attr("fill", (d) => (d.data.age >= 30 ? "#fff" : "#333"))
// .style("fill-opacity", 1)
// .style("font-size", "9px")
// .style("font-family", "Roboto");
return svg.node();
}