chart = {
let employees;
let employeeNav;
const h = 700;
let faggruppe;
const fgIds = [40, 31];
const fills = ["blue", "red"];
const svg = d3
.create("svg")
.attr("width", w)
.attr("height", h)
.style("background", "#f4f4f5");
const t = svg.transition().duration(1000);
const alleAnsatte = svg.append("rect");
const design = svg.append("rect");
const teknologer = svg.append("rect");
const faggruppePadding = width * 0.08;
alleAnsatte
.style("fill", "black")
.attr("height", 20)
.attr("width", 20)
.attr("x", width - faggruppePadding)
.attr("y", 10)
.on("click", showAllEmployees);
design
.data([{ fgId: fgIds[0] }])
.style("fill", "blue")
.attr("height", 20)
.attr("width", 20)
.attr("x", width - faggruppePadding)
.attr("y", 40)
.on("click", filterFaggruppe);
teknologer
.data([{ fgId: fgIds[1] }])
.style("fill", "red")
.attr("height", 20)
.attr("width", 20)
.attr("x", width - faggruppePadding)
.attr("y", 70)
.on("click", filterFaggruppe);
showAllEmployees();
return svg.node();
function showAllEmployees() {
const t = svg.transition().duration(1000);
employees = svg
.selectAll("g")
.data(flatData, (d) => d.empId)
.join(
(enter) =>
enter
.append("g")
.on("click", showSelected)
.attr("class", "circle-group")
.style("opacity", 0)
.style("fill", "none")
.attr("transform", (d) => `translate(${d.t.x},${d.t.y})`)
.call((g) => drawProfilePic(g))
.call((g) => g.transition(t).style("opacity", 1)),
(update) =>
update
.call((g) =>
g
.transition(t)
.attr("transform", (d) => `translate(${d.t.x},${d.t.y})`)
),
(exit) => exit.remove()
)
.on("click", showSelected);
return employees;
}
function filterFaggruppe(d, e) {
const t = svg.transition().duration(700);
const faggruppe = e.fgId;
const filteredData = flatData.filter((emp) => emp.fgId === faggruppe);
console.log("filtered data", filteredData);
employees = svg.selectAll("g");
employees
.data(filteredData, (d) => d.empId)
.join(
(enter) =>
enter
.append("g")
.attr("class", "circle-group")
.style("opacity", 0)
.call((g) => drawProfilePic(g))
.call((g) => g.transition(t).style("opacity", 1))
.attr(
"transform",
(d, i) =>
`translate(${radius * 1.5 + radius * 2.2 * (i % 10)},${
radius * 1.5 + Math.floor(i / 10) * (radius * 2.2)
})`
)
.on("click", showSelected),
(update) =>
update
.call((g) =>
g
.transition(t)
.style("opacity", 1)
.attr(
"transform",
(d, i) =>
`translate(${radius * 1.5 + radius * 2.2 * (i % 10)},${
radius * 1.5 + Math.floor(i / 10) * (radius * 2.2)
})`
)
)
.call((g) => g.selectAll("circle").transition(t).attr("r", radius)),
(exit) => exit.remove()
);
}
function showSelected(d, e) {
const filteredData = flatData.filter(
(employee) => employee.empId === e.empId
);
const t = svg.transition().duration(1000);
employees = svg
.selectAll("g")
.data(filteredData, (d) => d.empId)
.join(
(enter) => enter,
(update) =>
update
.transition(t)
.attr("transform", (d) => `translate(${w / 2},${h / 2}) scale(4)`),
(exit) => exit.transition().duration(400).style("opacity", 0).remove()
);
}
function drawProfilePic(g) {
g.append("defs")
.append("clipPath")
.attr("id", "employee_pfp")
.append("circle")
.attr("cx", 0)
.attr("cy", 0)
.attr("r", radius);
g.append("image")
.attr("x", (d) => (-1 * (radius * 2)) / Math.pow(2, 1))
.attr("y", (d) => (-1 * (radius * 2)) / Math.pow(2, 1))
.attr("height", radius * 2)
.attr("width", radius * 2)
.attr("clip-path", "url(#employee_pfp)")
.attr("href", `${kavianPfp}`);
g.append("circle")
.attr("cx", 0)
.attr("cy", 0)
.attr("r", radius)
.attr("stroke-width", 1.5)
.attr("fill", "none")
.attr("stroke", (d) => (d.fgId === 40 ? "blue" : "red"));
}
}