chart = {
const svg = d3
.create("svg")
.attr("viewBox", [-width / 2, -height / 2, width, height]);
const mid = {
x: 0,
y: 0
};
if (phase < 2) {
const gt = svg
.append("text")
.text("Sikt")
.attr("text-anchor", "middle")
.attr("font-size", "30px")
.attr("font-family", "sans-serif")
.attr("fill", "#160363")
.attr("y", -radius - 10);
}
const go = svg
.append("circle")
.attr("r", radius + teamRadius * 2)
.attr("cx", mid.x)
.attr("cy", mid.y)
.attr("fill", "none")
.attr("stroke-width", "3px")
.attr("stroke", "#7351fb");
function animateCircle() {
var opacity = 0.1 + (0.9 * (Math.sin(Date.now() / 400) + 1)) / 2;
go.style("stroke-opacity", opacity);
// Request the next animation frame
requestAnimationFrame(animateCircle);
}
// Start the animation
animateCircle();
if (phase === 0) {
const gsources = svg.append("g");
let fromg = gsources.selectAll().data(from).join("g");
fromg
.append("text")
.text((d) => d.label)
.attr("text-anchor", "middle")
.attr("font-size", "20px")
.attr("font-family", "sans-serif")
.attr("fill", (d) => colorFunc(d.color))
.attr("x", (d) => d.x)
.attr("y", (d) => d.y - 10);
fromg
.append("circle")
.attr("r", 6)
.attr("stroke", (d) => colorFunc(d.color))
.attr("fill", (d) => colorFunc(d.color))
.attr("cx", (d) => d.x)
.attr("cy", (d) => d.y);
}
// Arcs som viser støtteteam
if (phase >= 2) {
let fg = siktScheme.map((d) => d.color);
let bg = siktScheme.map((d) => d.font);
// Set up arc generator
const arc = d3
.arc()
.innerRadius(radius + teamRadius * 2 - 70)
.outerRadius(radius + teamRadius * 2 - 10);
const arcs = svg
.selectAll("g.arc")
.data(supportData)
.enter()
.append("g")
.attr("class", "arc")
.attr("transform", "translate(0, 0)"); // Adjust this to move the whole group of arcs
// Append the arcs
let aaaa = arcs
.append("path")
.attr("d", arc)
.attr("fill", (d, i) => fg[i])
.attr("id", function (d, i) {
return "arc" + i; // Unique id for each arc for textPath reference
});
// Append labels to arcs
arcs
.append("text")
.attr("dy", "40px") // Adjust this to move text up/down
.attr("text-anchor", "middle")
.attr("font-size", "28px")
.attr("fill", (d, i) => bg[i])
.attr("font-family", "sans-serif")
.append("textPath")
.attr("xlink:href", function (d, i) {
return "#arc" + i; // Reference to arc ids
})
.attr("side", (d) => (d.mid > Math.PI ? "right" : "left"))
.attr("startOffset", "22.5%") // Center the text
.text((d) => d.label);
function pulse() {
// Current time
let t = Date.now();
aaaa
.transition()
.duration(1000)
.ease(d3.easeLinear)
.attr("fill-opacity", function (d, i) {
// Create a pulsing effect by adjusting the opacity with a sine function
// The +1 shifts the range of Math.sin (which is -1 to 1) to the range 0 to 2
// Dividing by 2 then shifts the range to 0 to 1, which is suitable for opacity
// The division by 1000 slows down the pulse rate
return 0.7 + 0.3 * ((Math.sin((-t - i * 400) / 800) + 1) / 2);
})
.on("end", pulse); // Call the pulse function again when the transition ends
}
// Start the pulse
pulse();
}
if (phase === 4 || phase === 5) {
let subdata = phase === 4 ? fagSub : platonSub;
const arcSub = d3
.arc()
.innerRadius(radius + teamRadius * 2 - 90)
.outerRadius(radius + teamRadius * 2 - 70);
const arcs = svg
.selectAll("g.arcsub")
.data(subdata)
.enter()
.append("g")
.attr("class", "arcsub")
.attr("transform", "translate(0, 0)"); // Adjust this to move the whole group of arcs
// Append the arcs
arcs
.append("path")
.attr("d", arcSub)
.attr("fill", (d, i) => "none")
.attr("stroke", "#aaaaaa")
.attr("id", function (d, i) {
return "arcsub" + i; // Unique id for each arc for textPath reference
});
// Append labels to arcs
arcs
.append("text")
.attr("dy", "15px") // Adjust this to move text up/down
.attr("text-anchor", "middle")
.attr("font-size", "12px")
.attr("fill", "#666666")
.attr("font-family", "sans-serif")
.append("textPath")
.attr("xlink:href", function (d, i) {
return "#arcsub" + i; // Reference to arc ids
})
//.attr("side", (d) => (d.mid > Math.PI ? "right" : "left"))
.attr("startOffset", "22.5%") // Center the text
.text((d) => d.label);
}
const g = svg.append("g");
simulation.on("tick", () => {
g.selectAll("circle:not(.exit)")
.data(simulation.nodes(), (d) => d.id)
.join(
(enter) =>
enter
.append("circle")
.attr("fill", (d) => colorFunc(d.id))
.attr("stroke", (d) => colorFunc(d.id - 0.06))
.attr("stroke-width", 2)
.attr("r", 1)
.transition()
.duration(2000)
.attr("r", (d) => d.radius - 5)
.selection(),
(update) =>
update
.attr("cx", (d) => d.x)
.attr("cy", (d) => d.y)
.attr("r", (d) => d.radius - 5),
(exit) =>
exit
.classed("exit", true)
.transition()
.duration(2000)
.attr("fill", "#eee")
.attr("r", 1)
.attr("opacity", 0)
.remove()
);
});
return svg.node();
}