Skip to content

Instantly share code, notes, and snippets.

@jinniluo
Last active May 2, 2018 01:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jinniluo/3984c7e8e3262025a6367e45d13855b7 to your computer and use it in GitHub Desktop.
Save jinniluo/3984c7e8e3262025a6367e45d13855b7 to your computer and use it in GitHub Desktop.
D3-xForce
<!DOCTYPE html>
<head>
<title>3D-force-layout</title>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="plot">
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="//d3js.org/d3.v4.min.js"></script>
<script src="script.js"></script>
</body>
Category Movie Details Win
BEST PICTURE Call Me by Your Name Peter Spears, Luca Guadagnino, Emilie Georges and Marco Morabito FALSE
BEST PICTURE Darkest Hour Tim Bevan, Eric Fellner, Lisa Bruce, Anthony McCarten and Douglas Urbanski FALSE
BEST PICTURE Dunkirk Emma Thomas and Christopher Nolan FALSE
BEST PICTURE Get Out Sean McKittrick, Jason Blum, Edward H. Hamm Jr. and Jordan Peele FALSE
BEST PICTURE Lady Bird Scott Rudin, Eli Bush and Evelyn O'Neill FALSE
BEST PICTURE Phantom Thread JoAnne Sellar, Paul Thomas Anderson, Megan Ellison and Daniel Lupi FALSE
BEST PICTURE The Post Amy Pascal, Steven Spielberg and Kristie Macosko Krieger FALSE
BEST PICTURE The Shape of Water Guillermo del Toro and J. Miles Dale TRUE
BEST PICTURE Three Billboards outside Ebbing, Missouri Graham Broadbent, Pete Czernin and Martin McDonagh, FALSE
ACTOR IN A LEADING ROLE Call Me by Your Name Timothze Chalamet FALSE
ACTOR IN A LEADING ROLE Phantom Thread Daniel Day-Lewis FALSE
ACTOR IN A LEADING ROLE Get Out Daniel Kaluuya FALSE
ACTOR IN A LEADING ROLE Darkest Hour Gary Oldman TRUE
ACTOR IN A LEADING ROLE Roman J. Israel, Esq. Denzel Washington FALSE
ACTRESS IN A LEADING ROLE The Shape of Water Sally Hawkins FALSE
ACTRESS IN A LEADING ROLE Three Billboards outside Ebbing, Missouri Frances McDormand TRUE
ACTRESS IN A LEADING ROLE I, Tonya Margot Robbie FALSE
ACTRESS IN A LEADING ROLE Lady Bird Saoirse Ronan FALSE
ACTRESS IN A LEADING ROLE The Post Meryl Streep FALSE
ACTOR IN A SUPPORTING ROLE The Florida Project Willem Dafoe FALSE
ACTOR IN A SUPPORTING ROLE Three Billboards outside Ebbing, Missouri Woody Harrelson FALSE
ACTOR IN A SUPPORTING ROLE The Shape of Water Richard Jenkins FALSE
ACTOR IN A SUPPORTING ROLE All the Money in the World Christopher Plummer FALSE
ACTOR IN A SUPPORTING ROLE Three Billboards outside Ebbing, Missouri Sam Rockwell TRUE
ACTRESS IN A SUPPORTING ROLE Mudbound Mary J. Blige FALSE
ACTRESS IN A SUPPORTING ROLE I, Tonya Allison Janney TRUE
ACTRESS IN A SUPPORTING ROLE Phantom Thread Lesley Manville FALSE
ACTRESS IN A SUPPORTING ROLE Lady Bird Laurie Metcalf FALSE
ACTRESS IN A SUPPORTING ROLE The Shape of Water Octavia Spencer FALSE
ANIMATED FEATURE FILM The Boss Baby Tom McGrath and Ramsey Naito FALSE
ANIMATED FEATURE FILM The Breadwinner Nora Twomey and Anthony Leo FALSE
ANIMATED FEATURE FILM Coco Lee Unkrich and Darla K. Anderson TRUE
ANIMATED FEATURE FILM Ferdinand Carlos Saldanha FALSE
ANIMATED FEATURE FILM Loving Vincent Dorota Kobiela, Hugh Welchman and Ivan Mactaggart FALSE
CINEMATOGRAPHY Blade Runner 2049 Roger A. Deakins TRUE
CINEMATOGRAPHY Darkest Hour Bruno Delbonnel FALSE
CINEMATOGRAPHY Dunkirk Hoyte van Hoytema FALSE
CINEMATOGRAPHY Mudbound Rachel Morrison FALSE
CINEMATOGRAPHY The Shape of Water Dan Laustsen FALSE
COSTUME DESIGN Beauty and the Beast Jacqueline Durran FALSE
COSTUME DESIGN Darkest Hour Jacqueline Durran FALSE
COSTUME DESIGN Phantom Thread Mark Bridges TRUE
COSTUME DESIGN The Shape of Water Luis Sequeira FALSE
COSTUME DESIGN Victoria & Abdul Consolata Boyle FALSE
DIRECTING Dunkirk Christopher Nolan FALSE
DIRECTING Get Out Jordan Peele FALSE
DIRECTING Lady Bird Greta Gerwig FALSE
DIRECTING Phantom Thread Paul Thomas Anderson FALSE
DIRECTING The Shape of Water Guillermo del Toro TRUE
DOCUMENTARY (FEATURE) Abacus: Small Enough to Jail Steve James, Mark Mitten and Julie Goldman FALSE
DOCUMENTARY (FEATURE) Faces Places Agns Varda, JR and Rosalie Varda FALSE
DOCUMENTARY (FEATURE) Icarus Bryan Fogel and Dan Cogan TRUE
DOCUMENTARY (FEATURE) Last Men in Aleppo Feras Fayyad, Kareem Abeed and Sren Steen Jespersen FALSE
DOCUMENTARY (FEATURE) Strong Island Yance Ford and Joslyn Barnes FALSE
DOCUMENTARY (SHORT SUBJECT) Edith+Eddie Laura Checkoway and Thomas Lee Wright FALSE
DOCUMENTARY (SHORT SUBJECT) Heaven Is a Traffic Jam on the 405 Frank Stiefel TRUE
DOCUMENTARY (SHORT SUBJECT) Heroin(e) Elaine McMillion Sheldon and Kerrin Sheldon FALSE
DOCUMENTARY (SHORT SUBJECT) Knife Skills Thomas Lennon FALSE
DOCUMENTARY (SHORT SUBJECT) Traffic Stop Kate Davis and David Heilbroner FALSE
FILM EDITING Baby Driver Paul Machliss and Jonathan Amos FALSE
FILM EDITING Dunkirk Lee Smith TRUE
FILM EDITING I, Tonya Tatiana S. Riegel FALSE
FILM EDITING The Shape of Water Sidney Wolinsky FALSE
FILM EDITING Three Billboards outside Ebbing, Missouri Jon Gregory FALSE
FOREIGN LANGUAGE FILM A Fantastic Woman Sebasti‡n Lelio TRUE
FOREIGN LANGUAGE FILM The Insult Ziad Doueiri FALSE
FOREIGN LANGUAGE FILM Loveless Andrey Zvyagintsev FALSE
FOREIGN LANGUAGE FILM On Body and Soul Ildik— Enyedi FALSE
FOREIGN LANGUAGE FILM The Square Ruben …stlund FALSE
MAKEUP AND HAIRSTYLING Darkest Hour Kazuhiro Tsuji, David Malinowski and Lucy Sibbick TRUE
MAKEUP AND HAIRSTYLING Victoria & Abdul Daniel Phillips and Lou Sheppard FALSE
MAKEUP AND HAIRSTYLING Wonder Arjen Tuiten FALSE
MUSIC (ORIGINAL SCORE) Dunkirk Hans Zimmer FALSE
MUSIC (ORIGINAL SCORE) Phantom Thread Jonny Greenwood FALSE
MUSIC (ORIGINAL SCORE) The Shape of Water Alexandre Desplat TRUE
MUSIC (ORIGINAL SCORE) Star Wars: The Last Jedi John Williams FALSE
MUSIC (ORIGINAL SCORE) Three Billboards outside Ebbing, Missouri Carter Burwell FALSE
MUSIC (ORIGINAL SONG) Mudbound Mary J. Blige, Raphael Saadiq and Taura Stinson FALSE
MUSIC (ORIGINAL SONG) Call Me by Your Name Sufjan Stevens FALSE
MUSIC (ORIGINAL SONG) Coco Kristen Anderson-Lopez and Robert Lopez FALSE
MUSIC (ORIGINAL SONG) Marshall Diane Warren, Lonnie R. Lynn and Diane Warren FALSE
MUSIC (ORIGINAL SONG) The Greatest Showman Benj Pasek and Justin Paul FALSE
PRODUCTION DESIGN Beauty and the Beast Sarah Greenwood, Katie Spencer FALSE
PRODUCTION DESIGN Blade Runner 2049 Dennis Gassner, Alessandra Querzola FALSE
PRODUCTION DESIGN Darkest Hour Sarah Greenwood, Katie Spencer FALSE
PRODUCTION DESIGN Dunkirk Nathan Crowley, Gary Fettis FALSE
PRODUCTION DESIGN The Shape of Water Paul Denham Austerberry, Shane Vieau and Jeff Melvin TRUE
SHORT FILM (ANIMATED) Dear Basketball Glen Keane and Kobe Bryant TRUE
SHORT FILM (ANIMATED) Garden Party Victor Caire and Gabriel Grapperon FALSE
SHORT FILM (ANIMATED) Lou Dave Mullins and Dana Murray FALSE
SHORT FILM (ANIMATED) Negative Space Max Porter and Ru Kuwahata FALSE
SHORT FILM (ANIMATED) Revolting Rhymes Jakob Schuh and Jan Lachauer FALSE
SHORT FILM (LIVE ACTION) DeKalb Elementary Reed Van Dyk FALSE
SHORT FILM (LIVE ACTION) The Eleven O'Clock Derin Seale and Josh Lawson FALSE
SHORT FILM (LIVE ACTION) My Nephew Emmett Kevin Wilson, Jr. FALSE
SHORT FILM (LIVE ACTION) The Silent Child Chris Overton and Rachel Shenton FALSE
SHORT FILM (LIVE ACTION) Watu Wote/All of Us Katja Benrath and Tobias Rosen FALSE
SOUND EDITING Baby Driver Julian Slater FALSE
SOUND EDITING Blade Runner 2049 Mark Mangini and Theo Green FALSE
SOUND EDITING Dunkirk Richard King and Alex Gibson TRUE
SOUND EDITING The Shape of Water Nathan Robitaille and Nelson Ferreira FALSE
SOUND EDITING Star Wars: The Last Jedi Matthew Wood and Ren Klyce FALSE
SOUND MIXING Baby Driver Julian Slater, Tim Cavagin and Mary H. Ellis FALSE
SOUND MIXING Blade Runner 2049 Ron Bartlett, Doug Hemphill and Mac Ruth FALSE
SOUND MIXING Dunkirk Mark Weingarten, Gregg Landaker and Gary A. Rizzo FALSE
SOUND MIXING The Shape of Water Christian Cooke, Brad Zoern and Glen Gauthier FALSE
SOUND MIXING Star Wars: The Last Jedi David Parker, Michael Semanick, Ren Klyce and Stuart Wilson FALSE
VISUAL EFFECTS Blade Runner 2049 John Nelson, Gerd Nefzer, Paul Lambert and Richard R. Hoover TRUE
VISUAL EFFECTS Guardians of the Galaxy Vol. 2 Christopher Townsend, Guy Williams, Jonathan Fawkner and Dan Sudick FALSE
VISUAL EFFECTS Kong: Skull Island Stephen Rosenbaum, Jeff White, Scott Benza and Mike Meinardus FALSE
VISUAL EFFECTS Star Wars: The Last Jedi Ben Morris, Mike Mulholland, Neal Scanlan and Chris Corbould FALSE
VISUAL EFFECTS War for the Planet of the Apes Joe Letteri, Daniel Barrett, Dan Lemmon and Joel Whist FALSE
WRITING (ADAPTED SCREENPLAY) Call Me by Your Name James Ivory TRUE
WRITING (ADAPTED SCREENPLAY) The Disaster Artist Scott Neustadter and Michael H. Weber FALSE
WRITING (ADAPTED SCREENPLAY) Logan Scott Frank and James Mangold and Michael Green FALSE
WRITING (ADAPTED SCREENPLAY) Molly's Game Aaron Sorkin FALSE
WRITING (ADAPTED SCREENPLAY) Mudbound Virgil Williams and Dee Rees FALSE
WRITING (ORIGINAL SCREENPLAY) The Big Sick Emily V. Gordon and Kumail Nanjiani FALSE
WRITING (ORIGINAL SCREENPLAY) Get Out Jordan Peele TRUE
WRITING (ORIGINAL SCREENPLAY) Lady Bird Greta Gerwig FALSE
WRITING (ORIGINAL SCREENPLAY) The Shape of Water Guillermo del Toro and Vanessa Taylor FALSE
WRITING (ORIGINAL SCREENPLAY) Three Billboards outside Ebbing, Missouri Martin McDonagh FALSE
//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(' + 0 + ',' + height/2 + ')');
const rangeCategory=[],
bandWidth=width/24,
xBandWidth=width/6
for (let i=1;i<25;i++){
rangeCategory.push(24*i);
}
const scaleCategory=d3.scaleOrdinal().range(rangeCategory);
const winCoordinate=d3.scaleOrdinal().range([200,400]).domain(["TURE","FALSE"]);
const x = d3.scaleOrdinal().range([xBandWidth*2,xBandWidth*3,xBandWidth*4]).domain(["category","movie","detail"])
const color = d3.scaleOrdinal().range(["#ff52c8","#55E9B0","#9018F2"]).domain(["movie","category","detail"]);
const tickLabels=["Awards Category","Nominated Movies","Nominated Individuals"]
//load in data/
d3.queue()
.defer(d3.csv,"oscars.csv",parseData)
.await(ready);
function ready (error,oscars) {
//********************************process the data************************************/
//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<oscars.length;i++){
const length=oscars[i].details.length;
for(let j=0;j<length;j++){
flatOscars.push(
{
category:oscars[i].category,
movie:oscars[i].movie,
win:oscars[i].win,
detail:oscars[i].details[j]
}
)
}
}
//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})
})
//****************************************reconstruct movie*****************************************//
let movie=[];
oscars.forEach(
(d,i)=>{
movie.push({movie:d.movie,win:d.win})
}
)
movie=d3.nest().key((d)=>{return d.movie}).entries(movie);
let newMovie=[]
movie.forEach(
(d,i)=>{
d.values.sort(function(a, b) {
var nameA = a.win.toUpperCase();
var nameB = b.win.toUpperCase();
if (nameA > nameB) {
return -1;
}
if (nameA < nameB) {
return 1;
}
return 0;
});
newMovie.push({movie:d.key,win:d.values[0].win})
}
)
newMovie=uniqueArray(newMovie);
console.log(newMovie)
//****************************************reconstruct detail*****************************************//
let detail=[];
flatOscars.forEach(
(d,i)=>{
detail.push({detail:d.detail,win:d.win})
}
)
detail=d3.nest().key((d)=>{return d.detail}).entries(detail);
let newDetail=[]
detail.forEach(
(d,i)=>{
d.values.sort(function(a, b) {
var nameA = a.win.toUpperCase();
var nameB = b.win.toUpperCase();
if (nameA > nameB) {
return -1;
}
if (nameA < nameB) {
return 1;
}
return 0;
});
newDetail.push({detail:d.key,win:d.values[0].win})
}
)
newDetail=uniqueArray(newDetail);
console.log(newDetail)
//***********************************************************************************************************//
const findByMovie={};
for (let i=0;i<newMovie.length;i++){
findByMovie[newMovie[i].movie]=newMovie[i].win
}
const findByDetail={};
for (let i=0;i<newDetail.length;i++){
findByDetail[newDetail[i].detail]=newDetail[i].win
}
console.log(findByMovie)
let nodes=uniqueArray(dot),
links=uniqueArray(line);
function extend(obj, src) {
for (var key in src) {
if (src.hasOwnProperty(key)) obj[key] = src[key];
}
return obj;
}
const newDict=extend(findByMovie,findByDetail);
nodes.forEach(function(d,i){
d.win=newDict[d.id]
})
graph.nodes=nodes;
graph.links=links
//********************************axis*******************************************//
const xAxis= svg.append("g")
.attr("class","x-axis")
.attr("transform","translate("+0+","+height/2+")")
.call(d3.axisTop(x).tickFormat((d,i)=>{return tickLabels[i]}));
//********************************draw graphs************************************/
const link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("stroke-width", "1");
const node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r",(d)=>{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 label = svg.append("g")
.attr("class", "label")
.selectAll("text")
.data(graph.nodes)
.enter()
.append("text")
.text((d)=>{return d.id})
.attr("fill","white").attr("dy","2.5px").attr("dx","10px")
.attr("id","text")
.style("visibility", "hidden")
.on("mouseover", fadeIn(.3))
.on("mouseout", fadeOut(1))
.on("click",(d,i)=>{return console.log(d)})
const simulation = d3.forceSimulation(nodes)
.force("collide",d3.forceCollide().radius(6))
.force("charge",d3.forceManyBody().strength(0))
.force('x', d3.forceX().x(function(d) {
return x(d.type);
}))
.force("y",d3.forceY().y())
.force("links",d3.forceLink().id(function(d){return d.id}).links(graph.links).strength(0))
.on("tick",ticked)
//********************************hover over function************************************/
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;
});
label.style("visibility", function(o) {
thisOpacity = isConnected(d, o) ? "visible" : "hidden";
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)
label.style("visibility", "hidden")
};
};
//******************************************************************************************//
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; });
label
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; });
}
}
function parseData(d){
return{
category:d.Category,
movie:d.Movie,
details:d.Details,
win:d.Win
}
}
body{
font-family: monospace;
font-size: 9px;
font-weight: 200;
background-color: black;
}
.plot{
border: 1px solid black;
height:80vh;
width:90%;
top:10%;
left:5%;
margin:0;
position:absolute;
}
.links line {
stroke: #3d4353;
stroke-opacity: 0.2;
stroke-dasharray:2;
}
.nodes circle {
/* stroke: #fff;*/
stroke-width: 2px;
opacity:.9;
}
.text{
background-color:white;
}
.x-axis .domain{
visibility: hidden
}
.tick line {
visibility: hidden
}
.tick text{
fill:white;
font-family: monospace;
font-size: 10px;
opacity: .5;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment