//radinal force //seperate force const margin={top:20,right:20,bottom:20,left:20}, width=$(".plot").width()-margin.left-margin.right, height=$(".plot").height()-margin.top-margin.bottom; //plot and svg const svg = d3.select('.plot') .append('svg') .attr('width', width + margin.left + margin.right) .attr('height', height + margin.top + margin.bottom) .append('g') .attr('transform', 'translate(' + width/2 + ',' + height/2 + ')'); const rangeCategory=[], bandWidth=width/24; for (let i=1;i<25;i++){ rangeCategory.push(24*i); } const color = d3.scaleOrdinal().range(["#ff52c8","#55E9B0","#9018F2"]).domain(["movie","category","detail"]); //load in data/ d3.queue() .defer(d3.csv,"oscars.csv",parseData) .await(ready); function ready (error,oscars) { //split function remove(d){ const newString=d.replace(/ and /g,", ").split(", ") return newString } uniqueArray = a => [...new Set(a.map(o => JSON.stringify(o)))].map(s => JSON.parse(s)) //update d.details oscars.forEach((d,i)=>{ d.details=remove(d.details)}) //flaten the details for each object const flatOscars=[]; for (let i=0;i{category.push(d.category)}); category=uniqueArray(category); //push all category,movie and detail to same array and remove duplicate let dot=[],line=[],graph=[]; flatOscars.forEach( (d,i)=>{ dot.push({id:d.category,type:"category"},{id:d.movie,type:"movie"},{id:d.detail,type:"detail"}); line.push({source:d.category,target:d.movie},{source:d.movie,target:d.detail}) }) const findByMovie={}; for (let i=0;i{return 4}) .attr("fill", (d) =>{ return color(d.type); }) .style("stroke",(d)=>{ if(d.win=="TRUE"){return "white"} else{return } }) .on("mouseover", fadeIn(.3)) .on("mouseout", fadeOut(1)) .on("click",(d,i)=>{return console.log(d)}) const simulation = d3.forceSimulation(nodes) .force("charge",d3.forceCollide().radius(6)) .force("r", d3.forceRadial(function(d) { if(d.type=="category"){return 10} else if(d.type=="movie"){return 75} else{return 150} })) .force("links",d3.forceLink().id(function(d){return d.id}).links(graph.links).strength(0)) .on("tick",ticked) var linkedByIndex = {}; graph.links.forEach(function(d) { linkedByIndex[d.source.index + "," + d.target.index] = 1; }); function isConnected(a, b) { return linkedByIndex[a.index + "," + b.index] || linkedByIndex[b.index + "," + a.index] || a.index == b.index; }; function fadeIn(opacity) { return function(d) { node.style("stroke-opacity", function(o) { thisOpacity = isConnected(d, o) ? .9 : opacity; this.setAttribute('fill-opacity', thisOpacity); return thisOpacity; }); link.style("stroke-opacity", opacity) .style("stroke-opacity", function(o) { return o.source === d || o.target === d ? 1 : 0; }); }; }; function fadeOut(opacity) { return function(d) { node.style("stroke-opacity", function(o) { thisOpacity = isConnected(d, o) ? 1 : opacity; this.setAttribute('fill-opacity', thisOpacity); return thisOpacity; }); link.style("stroke-opacity", 0.2) }; }; function ticked() { link .attr("x1", function(d) { return d.source.x; }) .attr("y1", function(d) { return d.source.y; }) .attr("x2", function(d) { return d.target.x; }) .attr("y2", function(d) { return d.target.y; }); node .attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }); } } function parseData(d){ return{ category:d.Category, movie:d.Movie, details:d.Details, win:d.Win } }