|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<style> |
|
#circle circle { |
|
fill: none; |
|
pointer-events: all; |
|
} |
|
.group path { |
|
fill-opacity: 1; |
|
} |
|
.label { |
|
font: 8px sans-serif; |
|
} |
|
.fade { |
|
opacity: 0; |
|
} |
|
.family { |
|
fill: tomato; |
|
} |
|
.attention { |
|
font-weight: bold; |
|
fill: red; |
|
stroke: #000; |
|
stroke-width: .25px; |
|
} |
|
#circle:hover path.fade { |
|
display: none; |
|
} |
|
</style> |
|
<body> |
|
<script src="http://d3js.org/d3.v3.js"></script> |
|
<script> |
|
|
|
var width = 620, |
|
height = 620, |
|
padding = 650, |
|
outerRadius = Math.min(width, height) / 2 - 10, |
|
innerRadius = outerRadius - 24; |
|
|
|
/* the 3 pieces needed for Chord Diagram */ |
|
// arc generator |
|
var arc = d3.svg.arc() |
|
.innerRadius(innerRadius) |
|
.outerRadius(outerRadius); |
|
|
|
// chord layout |
|
var layout = d3.layout.chord() |
|
.padding(.04) |
|
.sortSubgroups(d3.ascending) |
|
.sortChords(d3.ascending) |
|
|
|
// chord generator |
|
var path = d3.svg.chord() |
|
.radius(innerRadius); |
|
|
|
var svg = d3.select("body").append("svg") |
|
.attr("width", width + padding) |
|
.attr("height", height + padding) |
|
.append("g") |
|
.attr("id", "circle") // #circle |
|
.attr("transform", "translate(" + (width + padding) / 2 + "," + (height + padding) / 2 + ")"); |
|
|
|
svg.append("circle") |
|
.attr("r", outerRadius); |
|
|
|
var key = ["Sharyn Vaught","Caryn Vaught","Miles Penn","Jeffrey J. Penn","Ann Kittenplan","Esteban Reyes", |
|
"Guglielmo Redondo","\"Sleepy TP\" Peterson","John \"N.R.\" Wayne","Kieran McKenna", |
|
"Eliot Kornspan","Jennie Bash","Erica Siress","Cisne","Brian van Vleck","Tunnel Club", |
|
"\"Axhandle\" Axford","Lamont Chu","Amy Wingo","Shoshana Abrams","Lori Clow", |
|
"Audern Tallat-Kelpsa","Keith B. \"The Viking\" Freer","Philip Traub","Carol Spodek", |
|
"Frances L. Unwin","Diane Prins","Josh Gopnik","Younger Players","Tina Echt","Gretchen Holt", |
|
"Bernadette Longley","Carl \"Mobes\" Whale","Jolene Criess","Virgilio","Kyle D. Coyle", |
|
"Felicity Zweig","Evan Ingersoll","Peter Beak","Zoltan Csikzentmihalyi","Bernard Makulic", |
|
"Idris \"Id\" Arslanian","Jeff Wax","Stephen Wagenknecht","Chip Sweeny","Graham \"Yard-Guard\" Rader", |
|
"Petropolis Kahn","Ortho \"The Darkness\" Stice","Todd \"Postal Weight\" Postalthwaite", |
|
"\"U.S.S.\" Milicent Kent","Kent Blott","Anton \"Booger\" Doucette","Otis P. Lord","Players", |
|
"Dymphna","Univ. of Arizona","Coach Kirk White","Dean of Admissions","Gerhardt Schtitt", |
|
"Mario","Dir. of Composition","Lyle","The Moms","Militant Grammarians of Mass.", |
|
"Dean of Academic Affairs","Dean of Athletic Affairs","Theirry Poutrincourt","Mary Esther Thode", |
|
"Ruth","Barry Loach","\"Lateral\" Alice Moore","Elizabeth Tavis","Therese Loach","Aubrey deLint", |
|
"Rik Dunkel","Charles Tavis","Ken N. Johnson","Tony Nwangi","E.T.A","Prorectors","Corbett Thorp", |
|
"Cantrell","Mrs. Clarke","Dr. E. Zegarelli","Neil Hartigan","Tex Watson","Donnie Stott", |
|
"Veach","Dolores Rusk","Syrian Satellite Pro","Slodoban","Miriam Prickett","Meniscus Films, Ltd.", |
|
"Teachers","Flottman","Fentress","Poor Yorick Entertainment Unltd.","Latrodectus Mactans Prod.", |
|
"Heliotrope Films, Ltd.","Disney R. Leith","Urguhart Oglivie Jr.","Lingley","Pettijohn", |
|
"Soma Richardson-Levy-O'Bryne Chawaf","Ibn-Said Chawaf","Molly Cantrell Notkin","Melinda", |
|
"Vogelsong","Notkin's Party","Rutherford Keck","Crosby Baum","Reeves Mainwaring","Iaccarrino", |
|
"Kenkle","Calvin Thrust","Otto Brandt","Dave \"Fall Down Very\" Harde","ETA Physical Plant & Maintenance", |
|
"WETA","Fully Functional Phil","Fond du Lac NoCoat Inc","LipoVac Unltd.","Nunhagen Aspirin", |
|
"Tenuate","Am. Council of Disseminators of Cable","Viney and Veals","Bernard Wayne","James Struck Jr.", |
|
"Jim Troeltsch","Gloeckner","Stockhausen","P. Tom Veals","Carl E. \"Buster\" Yee","Van Slack", |
|
"Hugh Pemberton","Tall Paul Shaw","Marueen Hooley","Interlace","Noreen Lace-Forche","Ted Schacht", |
|
"Seniors (18s)","Michael Pemulis","Albertan Mogul","Glad","Canadian P.M","Mexican President","Johhny Gentle, Famous Crooner", |
|
"O.N.A.N","Acme Inc.","Neil in Spin","Harv","Clean U.S. Party","Dick Desai","Inner Infant Group","Jim", |
|
"Bridget C. Boone","Thomas M. Flatto","Input/Output","Rodney Tine Sr.","Rodney Tine Jr.", |
|
"O.U.S","Kevin Bane","Bain's Sister","Dick Willis","Vienna VA Szech. Steakhouse", |
|
"Saprogenic Greetings","Marlon K. Bain","Luria Perec","Henri F. Hoyne","at ETA","Hal","Smothergill", |
|
"Miriam Hoyne","Fortier","Dwight Flechette","Helen/Hugh Steeply","Broullime","Other Members","Balbalis", |
|
"Steeply's father","Nickerson","B.U.","Orin","Mo Cheery","Muminsky","R. Ossowiecke","Joubet","Desjardins", |
|
"Tassigny","Beausoleil","Moment Mag.","\"Jethro Bodine\"","Eric Clipperton","Bain Parents","Marathe", |
|
"Marathe's father","Heart in Purse","Gertraud","Ross Reat","Himself","James I. Sr.","St. Abt. L'Ist, QC", |
|
"Mario Sr.","engineer","\"Dark Star\" McNair","The Filmography","Miss Diagnosis","The Entertainment", |
|
"Dr. Wo","60 Minutes +/-","WYYY","MIT","A.Y. Rickey","U.H.I.D","Joelle van Dyne","Joe Lon van Dyne", |
|
"Medical Attache's Wife","Saudi Minister of Home Entertainment","Medical Attache","\"Uncle\" Lum Riney","\"Madame Psychosis\"", |
|
"Lady Delphina","Pamela Hoffman-Jeep","Stavros Lobokulas","Sir Osis of Thuliver","Gately","Gately's Mom", |
|
"former Navy M.P.","Doshka Bulat","Vinnie Nucci","Mrs. Waite","St. Elizabeth's Hospital","\"Fax\" Fackelmann", |
|
"\"Quo Vadis\" Kite","White Flag","\"Ferocious\" Francis Gehaney","Revere ADA","The wraith","Dr. Pendleton", |
|
"Dr. Pressburger or Prissburger","Cathy or Kathy","Tooty","Crocodiles","T.S.B.Y.S.C.D","Robert F. \"Bob Death\"", |
|
"Whitey Sorkin","Gwendine O'Shay","Eighties Bill","Dr. Robert \"Sixties Bob\" Monroe","John L.","Louise B.", |
|
"Tamara N.","Dickey N.","Jack J.","Sven S.","Bud O.","Glenn K.","Danielle Steenbok","Didi Neaves","Clenette Henderson", |
|
"Clenette's momma","Dolores Epps","Columbus Epps","Clenette's father/Roy Tony's brother","Reginald","Reginald's momma", |
|
"Wardine","Antitois","Wade McDade","Alfonso Parias-Carbo","Dwayne R. \"Doony\" Glynn","\"The Madame\"","Roy Tony", |
|
"William","Shantell","Roy","Wardine's momma","Calgarian Pro-Canada Phalanx","Jeu Du Prochain Train","Le Bloc QC", |
|
"Les Fils de Montcalm","La Culte de Baiser Sans Fin","Brandeis","Sepratisteurs Quebecois","Les Fils de Papineau", |
|
"Le Parti Quebecois","Guillaume Duplessis","Quebec Liberation Front","Wheelchair Assassins","Test Subjects", |
|
"Sheraton Commander","Da","Matty Pemulis","Lucien","Bertraund","Antitoi Entertainment","Susan T. Cheese", |
|
"Bridget Tenderhole","Lolasister","Equus Reese","Kate Gompert","Ken Erdedy","\"Poor Tony\" Krause","Ruth Van Cleve", |
|
"Dr. Garton","Ernest Feaster","Burt F. Smith","Emil \"yrstrly\" Minty","Bobby C.","DesMont(e)s","Purpleboy","Randy Lenz", |
|
"\"Wild Conceits\"","Mrs. Lenz","Tommy Doocey","Kely Vinoy","Yolanda Willis","2 Chinese Ladies","Residents", |
|
"Geoffrey T. Day","Bruce Green Sr.","Harriet Bonk Green","Mildred Bonk Green","Bruce Green","Ennet House", |
|
"Guy w/o First Name","Ennet House Staff","Johnette Marie Foltz","Eugenio Martinez","Ennet House Admin.", |
|
"Ennet House Unit 6","Ennet House Unit 5 \"The Shed\"","Tree Lady","Mrs. Lopate","Mars Montesian", |
|
"Pat Montesian","Annie Parrot","Janice","Ennet House Counselors","Enfield Marine Public Health Hospital Complex", |
|
"Maureen N.","Pointgrave","Enfield Marine Public Health Hospital Complex Unit 4","Retired Air Force Nurse Who Asks For Help", |
|
"Charlotte Treat","Tiny Ewell","\"Franklin W. Dixon\"","Money Stealers Club","Gavin Diehl","Nell Gunther", |
|
"Glenn K. Kubitz","Hester Thrale","Selwyn","Jennifer Belbin","Morris Hanley","Chandler Foss", |
|
"David Krane","April Cortelyu","Skull","Amy Johnson","Tingley"]; |
|
|
|
d3.csv("IJ.csv", form_the_data, function(error, data) { |
|
var matrix = data; |
|
|
|
// compute the chord layout |
|
layout.matrix(matrix); |
|
|
|
// add a group per character |
|
// each group is a row in the matrix |
|
|
|
var group = svg.selectAll(".group") |
|
.data(layout.groups) |
|
.enter() |
|
.append("g") |
|
.attr("class", "group") |
|
.on("mouseover", mouseover) |
|
.on("mouseout", mouseout); |
|
|
|
// add the group arc |
|
var groupPath = group.append("path") |
|
.attr("id", function(d, i) { |
|
return "group" + i; |
|
}) |
|
.attr("d", arc) |
|
.style("fill", "#2171b5"); |
|
|
|
// add a text label |
|
var x; // offset variable |
|
var labels = svg.selectAll(".label") |
|
.data(layout.groups); |
|
|
|
labels.enter() |
|
.append("g") |
|
.attr("class", "label") |
|
.attr("transform", function(d) { |
|
return "rotate(" + (d.startAngle * 180 / Math.PI - 90) + ")" |
|
+ "translate(" + outerRadius + ",0)"; |
|
}) |
|
.append("text") |
|
.attr("x", function(d, i){ // stagger the labels on both sides of circle |
|
if (d.startAngle > Math.PI) { // left side of circle |
|
x = [8, -70, -148, -226]; |
|
} else if (d.startAngle < Math.PI) { // right side of circle |
|
x = [8, 86, 164, 242]; |
|
} |
|
return x[(i % 4)]; |
|
}) |
|
.attr("dy", function(d, i){ |
|
if (d.startAngle > Math.PI) { // left side of circle |
|
return (i % 2 == 0) ? "-.35em" : ".35em"; |
|
} else if (d.startAngle < Math.PI) { // right side of circle |
|
return (i % 2 == 0) ? ".35em" : "-.35em"; |
|
} |
|
}) |
|
.attr("transform", function(d) { return d.startAngle > Math.PI ? "rotate(180)translate(-16)" : null; }) |
|
.style("text-anchor", function(d) { return d.startAngle > Math.PI ? "end" : null; }) |
|
.text(function(d, i){ return key[i]; }) |
|
.on("mouseover", mouseover) |
|
.on("mouseout", mouseout); |
|
|
|
|
|
/* fix specific overlaps */ |
|
// right side of circle |
|
x = [8, 86, 164, 242]; |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 62; }) // the moms |
|
.attr("x", x[0]); // first row |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 59; }) // mario |
|
.attr("x", x[1]); // second row |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 80; }) // corbett thorp |
|
.attr("x", x[2]); // third row |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 73; }) // aubrey delint |
|
.attr("x", x[3]); // fourth row |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 97; }) // lactrodectus mactans prod. |
|
.attr("x", x[2]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 117; }) // eta physical plant & maint. |
|
.attr("x", x[2]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 164; }) // vienna va steakhouse |
|
.attr("x", x[1]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 173; }) // fortier |
|
.attr("x", x[0]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 163; }) // dick willis |
|
.attr("x", x[1]) |
|
.attr("dy", ".1em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 161; }) // kevin bane |
|
.attr("x", x[2]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 158; }) // rodney tine sr |
|
.attr("x", x[1]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 103; }) // soma richardson-.... |
|
.attr("x", x[2]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 64; }) // dean of academic affairs |
|
.attr("dy", "-.1em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 128; }) // jim troeltsch |
|
.attr("dy", "-.1em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 146; }) // johnny gentle, f.c. |
|
.attr("x", x[1]); |
|
|
|
// left side of circle |
|
x = [8, -70, -148, -226]; |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 174; }) // dwight flechtte |
|
.attr("x", x[3]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 178; }) // balbalis |
|
.attr("x", x[3]) |
|
.attr("dy", "-.5em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 209; }) // 60 min +/- |
|
.attr("x", x[2]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 206; }) // miss diagnosis |
|
.attr("x", x[3]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 203; }) // engineer |
|
.attr("x", x[0]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 200; }) // james I. sr. |
|
.attr("x", x[3]) |
|
.attr("dy", ".5em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 197; }) // gertraud |
|
.attr("dy", "-.5em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 204; }) // dark star mcnair |
|
.attr("dy", "-.7em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 216; }) // medical attache's wife |
|
.attr("x", x[3]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 211; }) // MIT |
|
.attr("dy", "-.3em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 225; }) // gately |
|
.attr("x", x[2]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 170; }) // hal |
|
.attr("dy", "-.5em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 181; }) // b.u. |
|
.attr("dy", ".5em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 226; }) // gately's mom |
|
.attr("dy", ".1em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 242; }) // crocodiles |
|
.attr("dy", ".1em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 249; }) // john l. |
|
.attr("x", x[2]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 263; }) // clenette's father/roy tony's brother |
|
.attr("x", x[0]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 265; }) // reginald's momma |
|
.attr("x", x[2]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 264; }) // reginald |
|
.attr("dy", "-1em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 278; }) // prochain train |
|
.attr("dy", "-1em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 289; }) // test subjects |
|
.attr("x", x[2]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 292; }) // matty pemulis |
|
.attr("dy", ".3em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 303; }) // ruth van cleve |
|
.attr("x", x[2]) |
|
.attr("dy", ".1em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 301; }) // ken erdedy |
|
.attr("dy", "-.1em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 296; }) // susan t. cheese |
|
.attr("dy", "-.5em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 306; }) // burt f. smith |
|
.attr("dy", "-.5em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 312; }) // wild conceits |
|
.attr("dy", ".4em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 325; }) // guy w/o first name |
|
.attr("x", x[2]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 313; }) // mrs. lenz |
|
.attr("dy", ".7em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 322; }) // mildred bonk green |
|
.attr("x", x[1]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 314; }) // tommy doocey |
|
.attr("dy", ".1em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 327; }) // johnette marie foltz |
|
.attr("x", x[0]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 329; }) // ennet house admin. |
|
.attr("x", x[2]); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 328; }) // eugenio martinez |
|
.attr("x", x[1]) |
|
.attr("dy", "-.1em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 339; }) // ennet marine public health... |
|
.attr("x", x[2]) |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 338; }) // ennet house counselors |
|
.attr("x", x[1]) |
|
.attr("dy", "-1em"); |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 343; }) // retired air force nurse... |
|
.attr("x", x[0]) |
|
|
|
labels.selectAll("text").filter(function(p) { return p.index == 360; }) // tingley |
|
.attr("dy", ".5em") |
|
|
|
// add the chords |
|
var chord = svg.selectAll(".chord") |
|
.data(layout.chords) |
|
.enter() |
|
.append("path") |
|
.attr("class", "chord") |
|
.style("fill", function(d, i) { |
|
if ((d.source.value == 2) && (d.target.value == 2)) { // family |
|
return "tomato"; |
|
} else { |
|
return "#1a9850"; |
|
} |
|
}) |
|
.attr("d", path); |
|
|
|
function mouseover(d, i) { |
|
var active_chords = d3.selectAll(".chord") |
|
.filter(function(p) { |
|
return p.source.index == d.index || |
|
p.source.subindex == d.index; |
|
}) |
|
|
|
// all the indices of labels the active chords touch |
|
var active_labels = []; |
|
active_chords.data().forEach(function(s) { |
|
active_labels.push(s.source.index); |
|
active_labels.push(s.target.index); |
|
}) |
|
|
|
// destination labels the active chords touch |
|
var dest_labels = d3.selectAll(".label") |
|
.filter(function(p) { |
|
return active_labels.indexOf(p.index) != -1; |
|
}) |
|
|
|
// family labels |
|
var family_labels_indices = []; |
|
active_chords.data().forEach(function(s) { |
|
if ((s.source.value == 2) && (s.target.value == 2)) { // family |
|
family_labels_indices.push(s.source.index); |
|
family_labels_indices.push(s.target.index); |
|
} |
|
}) |
|
|
|
var family_labels = d3.selectAll(".label") |
|
.filter(function(p) { |
|
return family_labels_indices.indexOf(p.index) != -1; |
|
}) |
|
|
|
// fade everything |
|
chord.classed("fade", true) |
|
labels.classed("fade", true) |
|
|
|
// show this label, active chords, and destination labels. |
|
active_chords.classed("fade", false) |
|
dest_labels.classed("fade", false) |
|
|
|
// specify family labels (hard to see what orange lines point to exactly in diagram) |
|
family_labels.classed("family", true); |
|
|
|
// make this label red & bold so you can tell which one is showing |
|
svg.selectAll(".label") |
|
.filter(function(p) { |
|
return p.index == d.index; |
|
}) |
|
.classed("attention", true); |
|
} |
|
|
|
function mouseout(d, i) { |
|
chord.classed("fade", false) |
|
labels.classed("fade", false) |
|
|
|
svg.selectAll(".label") |
|
.filter(function(p) { |
|
return p.index == d.index; |
|
}) |
|
.classed("attention", false); |
|
|
|
labels.classed("family", false); |
|
} |
|
|
|
}); |
|
|
|
function form_the_data(d) { |
|
var i = 0; |
|
for (i = 0; i <= 360; i++){ |
|
d[i] = +d[i]; |
|
} |
|
return d; |
|
} |
|
d3.select(self.frameElement).style("height", (height + padding) + "px").style("width", (width + padding) + "px"); |
|
</script> |