chart = {
d3.select(".demo").selectAll("svg").remove();
const svg = d3.select(".demo").append("svg") .attr("width",char_width).attr("height", height)
let toolTip = d3.select(".demo").append("div").attr("class", "toolTip")
var board= svg.append("g").attr("transform","translate(30,0)")
let options=Array.from(new Set(filtered_company_data.map(d=>d["gender"])))
var colorScale = d3.scaleOrdinal().domain(options).range(["#ff0000","#626681","#FFC100","#9FB40F","#76523B","#DAD5B5","#0E8E89","#E19348","#F383A2","#247FEA"])
var yScale=d3.scalePoint().domain(options).range([80, height-120]).padding(0.5)
function ticked() {
bubbles.selectAll("circle").attr("cx", function(d) {return d.x;}).attr("cy", function(d) { return d.y;})
}
var legendOrdinal = d3legend.legendColor()
.title(`${group_choice} of Candidates`)
.titleWidth(300)
.shape("path", d3.symbol().type(d3.symbolCircle).size(150)())
.shapePadding(10)
.scale(colorScale);
board.append("g")
.attr("class", "legendSymbol")
.attr("transform", "translate(20, 20)");
d3.select(".legendTitle").select("tspan").attr("dy","0.7em")
d3.select(".legendSymbol").call(legendOrdinal)
var simulation = d3.forceSimulation()
.nodes(filtered_company_data)
.force('charge', d3.forceManyBody().strength(-12))
.force("x", d3.forceX(char_width/2).strength(0.015))
.force("y", d3.forceY().y(d=>yScale(d["gender"])).strength(0.5))
.force('collision', d3.forceCollide().radius(18))
.on("tick", ticked)
var bubbles = board.selectAll("g.node").data(filtered_company_data).join("g").attr("class", "node");
const defs = bubbles.append("defs");
defs
.append('pattern')
.attr("id", d=>d["Public LinkedIn URL"].replace(/[^0-9a-z]/gi, ''))
.attr("width", 1)
.attr("height", 1)
.append("svg:image")
.attr("xlink:href", (d,i) => profiles[i]=="error"?"https://i.postimg.cc/0NKhB9qw/person.jpg":d.Image)
.attr("width", 30)
.attr("height", 30)
.attr("preserveAspectRatio", "xMidYMid slice");
bubbles.append("a")
.attr("xlink:href", d=>d["Public LinkedIn URL"])
.attr("target","_blank")
.append("circle")
.attr("class", "profile-circle")
.attr("fill", (d,i) => `url(#${d["Public LinkedIn URL"].replace(/[^0-9a-z]/gi, '')})`)
.attr("stroke", d=>colorScale(d["gender"]))
.attr("stroke-width", 3)
.attr("r", 15)
.on('mousemove', nodeMouseOver).on('mouseout', nodeMouseOut );
// .append("title")
// .text(d => d["Full Name"])
function nodeMouseOver(event, d){
const x = d.x + 30;
const y = d.y + 30;
// <img src=${d.Image} alt=${d["Full Name"]}></img>
// const i= filtered_company_data.map(u=>u["Public LinkedIn URL"]).indexof(d["id"])
// const url_use= (profiles[i]=="error")?"https://i.postimg.cc/0NKhB9qw/person.jpg":d.Image
toolTip
.style("left", `calc(10px + ${x}px)`)
.style("top", `calc(10px + ${y}px)`)
.style("display", "block")
.html(`
<h5>Name: <strong>${d["First Name"]} ${d["Last Name"]}</strong></h5>
<div style="border: solid 1px #e8e8e8; border-radius: 4px; box-sizing: border-box; width: 100%; padding-top: 62.5%; background-size: contain; background-repeat: no-repeat; background-position: center; background-image: url(${
d.Image
});"></div>
<p>Gender: <strong>${d["gender"]}</strong></p>
<p>Star: <strong>${d["Star (higher the better)"]}</strong></p>
<p>Seniority: <strong>${d["Seniority"]}</strong></p> `);
toolTip.selectChildren().style("display","block")
// Optional cursor change on target
d3.select(event.target).style("cursor", "pointer");
// Optional highlight effects on target
d3.select(this)
// .transition()
.attr('stroke', '#A8234E')
.attr('stroke-width', 3);
}
function nodeMouseOut(event, d){
// Hide tooltip on mouse out
toolTip.style("display", "none"); // Hide toolTip
// Optional cursor change removed
d3.select(event.target).style("cursor", "default");
// Optional highlight removed
d3.select(event.target)
.attr('stroke', d=>colorScale(d.gender))
.attr('stroke-width', 3);
}
invalidation.then(() => simulation.stop());
return Object.assign(svg.node(), {
update(selection) {
let data_use=clean(selection,filtered_company_data)
let options_new=Array.from(new Set(data_use.map(d=>d[selection])))
if (selection=="gender"){options_new=["Female","Male"]}
let colorScale_new = d3.scaleOrdinal().domain(options_new).range(["#ff0000","#626681","#FFC100","#9FB40F","#76523B","#DAD5B5","#0E8E89","#E19348","#F383A2","#247FEA"])
let yScale_new=d3.scalePoint().domain(options_new).range([80, height-120]).padding(0.5)
legendOrdinal.scale(colorScale_new)
d3.select(".legendSymbol").call(legendOrdinal)
function new_nodeMouseOut(event, d){
// Hide tooltip on mouse out
toolTip.style("display", "none"); // Hide toolTip
// Optional cursor change removed
d3.select(event.target).style("cursor", "default");
// Optional highlight removed
d3.select(event.target)
.attr('stroke', d=>colorScale_new(d[selection]))
.attr('stroke-width', 3)
}
simulation.force("y", d3.forceY(d=>yScale_new(d[selection])).strength(0.2))
const t = d3.transition()
.duration(750)
.ease(d3.easeLinear);
bubbles.selectAll("circle").transition(t).attr("stroke", function(d) {return colorScale_new(d[selection]);})
bubbles.selectAll("circle").on("mousemove", nodeMouseOver).on("mouseout", new_nodeMouseOut)
simulation.alpha(0.5).alphaTarget(0.3).alphaDecay(0.02).restart();
}
})
}