Skip to content

Instantly share code, notes, and snippets.

@allisonking
Last active September 13, 2017 02: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 allisonking/a19d8b5b5549df6abc0272b9e339563b to your computer and use it in GitHub Desktop.
Save allisonking/a19d8b5b5549df6abc0272b9e339563b to your computer and use it in GitHub Desktop.
Bar graph with object constancy- Harry Potter canon vs. fan fiction

Simple bar graph with object constancy that tracks either:

  • how many times a character is mentioned in the seven Harry Potter books (data from here)
  • how many times a character is tagged in fan fiction as being one of the main characters

This dataset was normalized by dividing by the total number out of the top 200 characters. So if there were a total of 20 fan fictions tagged as Sirius Black, and there were a total of 100 fan fictions, Sirius Black fan fictions would show up as 20%. Note that therefore this percentage will add up to be over 100% since fan fictions can tag multiple characters. For example, if our total fan fictions were made entirely out of fan fictions tagged Sirius Black and Remus Lupin, it would be correct to say that 100% of fan fictions are about Sirius Black and 100% of fan fictions are about Remus Lupin.

This is a somewhat reusable graph- see this block for the same graph only colored by gender instead of by increasing and decreasing mentions just by changing the argument in the function call in index.html.

name canon_percentage fanfiction_percentage gender
Harry Potter 0.2835771773928133 0.25926886490636863 M
Ron Weasley 0.09669987732998236 0.06490124984003752 M
Hermione Granger 0.08206923376118241 0.21711214435012585 F
Albus Dumbledore 0.036217574723992466 0.017697393678283498 M
Rubeus Hagrid 0.03027855069862071 0.0012660495670349355 M
Severus Snape 0.029261287137599856 0.08640702981700295 M
Voldemort 0.02688268557580109 0.03387109158384166 M
Sirius Black 0.02200580438620112 0.08102546602397304 M
Draco Malfoy 0.017921790383867396 0.18863626668941688 M
Fred Weasley 0.013762977590282142 0.018277524207652603 M
Remus Lupin 0.012925231128264969 0.06784797167598004 M
George Weasley 0.01228196152350178 0.0203796442434842 M
Neville Longbottom 0.012117404182748408 0.012129846862602907 M
Arthur Weasley 0.011668611435239206 0.0025372179328584225 M
Ginny Weasley 0.011533973610986448 0.07609776905686133 F
Minerva McGonagall 0.01151901385273614 0.012498400375378577 F
Molly Weasley 0.01080094545672142 0.004461886277353581 F
Dolores Umbridge 0.009529366005445352 0.0011141918696412577 F
Alastor Moody 0.008721539059928791 0.0011158981359041078 M
Vernon Dursley 0.007928671872662538 0.0008957897879964168 M
Cornelius Fudge 0.0073751608174011905 0.0002712963357932005 M
Peter Pettigrew 0.007270442509649044 0.008920360022181462 M
Dobby 0.0070161266193938315 0.0007797636821225952 M
Dudley Dursley 0.006986207102893217 0.0024143667619331995 M
Horace Slughorn 0.006462615564132484 0.0003941475067184233 M
Percy Weasley 0.006372857014630644 0.005122211321076654 M
Luna Lovegood 0.005325673937109175 0.020023034594548482 F
Cedric Diggory 0.005280794662358256 0.004139401953674871 M
Petunia Dursley 0.004697364090596296 0.003253849763255556 F
Kreacher 0.004667444574095682 0.00035660964893571644 M
Bill Weasley 0.004517846991592616 0.003084929403233375 M
Barty Crouch Sr. 0.004413128683840469 0.00017574542507358274 M
Argus Filch 0.004308410376088322 0.0008087702085910508 M
Viktor Krum 0.004143853035334949 0.0018820116879239008 M
Gilderoy Lockhart 0.0039194566615803495 0.000945271509619076 M
Sybill Trelawney 0.0039194566615803495 0.0004999360150151432 F
Fleur Delacour 0.003859617628579122 0.0035831591519856674 F
Lucius Malfoy 0.003724979804326362 0.01137397090816022 M
Ludo Bagman 0.003680100529575442 0.0 M
Nymphadora Tonks 0.003620261496574216 0.014527150961907606 F
Gregory Goyle 0.0034108248810699217 0.0005118798788550954 M
Vincent Crabbe 0.003350985848068695 0.0004146227018726272 M
Bellatrix Lestrange 0.0032911468150674684 0.012356780275562002 F
Cho Chang 0.0032163480238159357 0.0037691421746363523 F
Dean Thomas 0.0031714687490650146 0.0023734163716247927 M
Oliver Wood 0.003111629716063789 0.005994113381393168 M
Hedwig 0.0030517906830625613 0.0004112101693469266 F
James Potter 0.002842354067558268 0.08172503519174168 M
Rita Skeeter 0.002812434551057655 0.0005187049439064966 F
Seamus Finnigan 0.002677796726804895 0.003033741415347865 M
Igor Karkaroff 0.0024683601113006013 0.0001740391588107324 M
Peeves 0.002453400353050295 0.00016209529497078018 M
Winky 0.0024234808365496806 0.00018427675638783432 F
Crookshanks 0.0024234808365496806 0.00033442818751866233 M
Madam Pomfrey 0.002333722287047841 0.0005067610800665443 F
Rufus Scrimgeour 0.002288843012296921 0.00010920104082242034 M
Mundungus Fletcher 0.0021990844627950814 0.0001262637034509235 M
Lavender Brown 0.0021093259132932414 0.002436548223350254 F
Griphook 0.0020943661550429345 0.0 M
Filius Flitwick 0.0020943661550429345 0.0004931109499637418 M
Buckbeak 0.002034527122041708 0.0 M
Angelina Johnson 0.002019567363791401 0.0029603719660453013 F
Parvati Patil 0.001989647847290788 0.0011773237213667193 F
Lily Potter 0.001899889297788948 0.07964339035106427 F
Xenophilius Lovegood 0.0018550100230380281 0.000402678838032675 M
Nearly Headless Nick 0.001840050264787721 0.00011602610587382161 M
Quirinus Quirrell 0.0018250905065374144 0.00038732244166702213 M
Moaning Myrtle 0.0017802112317864946 0.0006790939726144265 F
Mr. Ollivander 0.001750291715285881 0.0002559399394275477 M
Katie Bell 0.0017353319570355744 0.003439832785906241 F
Madame Maxime 0.0016754929240343475 0.0 F
Charlie Weasley 0.0016455734075337342 0.004530136927867594 M
Lee Jordan 0.0016306136492834275 0.0006227871859403659 M
Kingsley Shacklebolt 0.0015857343745325073 0.0006586187774602226 M
Fang 0.0015707746162822009 0.0 M
Fenrir Greyback 0.0015258953415312807 0.0007985326110139488 M
Ernie Macmillan 0.001376297759028214 0.0004470417608667833 M
Pomona Sprout 0.0013463782425276007 0.0004214477669240285 F
Phineas Nigellus Black 0.0013314184842772938 0.0 M
Narcissa Malfoy 0.0013314184842772938 0.00944418376487651 F
Stan Shunpike 0.0012715794512760676 0.0 M
Aberforth Dumbledore 0.0011818209017742274 0.0005408864053235507 M
Bathilda Bagshot 0.001151901385273614 0.0 F
Colin Creevey 0.001151901385273614 0.001025466023973041 M
Amos Diggory 0.0011369416270233072 0.0 M
Firenze 0.0011219818687730006 0.0001433263660794267 M
Grawp 0.0011219818687730006 0.0 M
Marge Dursley 0.0010920623522723872 0.0 F
Cormac McLaggen 0.0010920623522723872 0.0002883589984217037 M
Gellert Grindelwald 0.0010920623522723872 0.0014656827197884231 M
Fat Lady 0.0010771025940220806 0.0 F
Salazar Slytherin 0.0010471830775214673 0.002378535170413343 M
Bob Ogden 0.001017263561020854 0.0 M
Pansy Parkinson 0.001017263561020854 0.007251631617113852 F
Marvolo Gaunt 0.001017263561020854 0.0 M
Fawkes 0.0009574245280196274 0.000252527406901847 M
Frank Bryce 0.0009424647697693203 0.0 M
Morfin Gaunt 0.0009424647697693203 0.0 M
Godric Gryffindor 0.0009424647697693203 0.0015987714882907474 M
Elphias Doge 0.0009275050115190136 0.0 M
Pigwidgeon 0.0008975854950184006 0.0 M
Mrs. Norris 0.000882625736768094 0.00016038902870792987 F
Alicia Spinnet 0.0008676659785177872 0.0007200443629228341 F
Wilhelmina Grubbly-Plank 0.0008527062202674804 0.0 F
Aunt Muriel 0.0008377464620171738 0.0 F
Yaxley 0.0008377464620171738 0.0 M
Arabella Figg 0.0008227867037668671 0.00021157701659343942 F
Regulus Black 0.0008078269455165603 0.006111845753529839 M
Madam Hooch 0.0007928671872662537 0.0004129164356097769 F
Mr. Borgin 0.0007629476707656403 0.0 M
Justin Finch-Fletchley 0.0007479879125153338 0.0004692232222838374 M
Ariana Dumbledore 0.0007479879125153338 0.0004760482873352387 F
Madam Rosmerta 0.0007330281542650271 0.00013308876850232478 F
Gregorovitch 0.0007330281542650271 0.0 M
Aragog 0.0007330281542650271 0.0 M
Marietta Edgecombe 0.0007180683960147202 0.00022352088043339164 F
Professor Binns 0.0007180683960147202 0.00010578850829671971 M
Zacharias Smith 0.0007180683960147202 0.000510173612592245 M
Blaise Zabini 0.0007031086377644138 0.006782408394830014 M
Bertha Jorkins 0.0006283098465128804 0.0 F
Travers 0.0006133500882625737 0.0 M
Marcus Flint 0.0005983903300122669 0.0011141918696412577 M
Ted Tonks 0.0005834305717619603 0.0012916435609776904 M
Barty Crouch Jr. 0.0005385512970110403 0.0011858550526809713 M
Norbert 0.0005385512970110403 0.0 F
Amelia Bones 0.0005235915387607336 0.00035319711641001577 F
Ernie Prang 0.000508631780510427 0.0 M
Antonin Dolohov 0.000508631780510427 0.00023887727679904448 M
Montague 0.0004936720222601203 0.00019622062022778646 M
Merope Gaunt 0.0004787122640098137 0.0006569125111973724 F
Nicolas Flamel 0.0004637525057595068 0.0001706266262850318 M
Mary Cattermole 0.0004637525057595068 0.0 F
Roger Davies 0.0004487927475092002 0.00016038902870792987 M
Bane 0.0004487927475092002 0.0 M
Nagini 0.0004487927475092002 0.00025423367316469736 F
Rowena Ravenclaw 0.0004188732310085869 0.0015083393763596807 F
Fluffy 0.00040391347275828016 0.0 M
Dedalus Diggle 0.00040391347275828016 0.0 M
Hepzibah Smith 0.00040391347275828016 0.0 F
Walden Macnair 0.00040391347275828016 0.0 M
Albus Severus Potter 0.00040391347275828016 0.011420040097257177 M
Errol 0.0003889537145079736 0.0 M
Broderick Bode 0.0003889537145079736 0.0 M
Michael Corner 0.0003889537145079736 0.0003446657850957642 M
Hannah Abbott 0.0003889537145079736 0.001685791067696114 F
Madam Malkin 0.0003739939562576669 0.0 F
Augustus Rookwood 0.0003739939562576669 0.0 M
Tom 0.00035903419800736023 0.0 M
Bloody Baron 0.00035903419800736023 0.0002593524719532483 M
Sturgis Podmore 0.0003440744397570535 0.0 M
Reg Cattermole 0.0003440744397570535 0.0 M
Dirk Cresswell 0.0003440744397570535 0.0 M
Padma Patil 0.0003440744397570535 0.0009998720300302864 F
Amycus Carrow 0.0003440744397570535 0.00012967623597662418 M
Sir Cadogan 0.0003440744397570535 0.0 M
Ronan 0.0003440744397570535 0.0 M
Warrington 0.00032911468150674685 0.0 M
Kendra Dumbledore 0.00032911468150674685 0.0 F
Mrs. Cole 0.0003141549232564402 0.0 F
Armando Dippet 0.0003141549232564402 0.0 M
Mr. Roberts 0.00029919516500613347 0.0 M
Leanne 0.00029919516500613347 0.0 F
Pius Thicknesse 0.00029919516500613347 0.0 M
Hokey 0.0002842354067558268 0.0 F
Madam Pince 0.0002842354067558268 0.00017915795759928336 F
Albert Runcorn 0.0002842354067558268 0.0 M
Dawlish 0.0002842354067558268 0.0 M
Griselda Marchbanks 0.00026927564850552014 0.0 F
Trevor 0.00026927564850552014 0.0 M
Tom Riddle Sr. 0.00026927564850552014 0.0006261997184660666 M
Romilda Vane 0.00026927564850552014 0.00027641513458175147 F
Magorian 0.00026927564850552014 0.0 M
Dennis Creevey 0.0002543158902552135 0.0005630678667406047 M
Millicent Bulstrode 0.0002543158902552135 0.0003856161754041719 F
Beedle the Bard 0.0002543158902552135 0.0 M
Scabior 0.0002543158902552135 0.00044021669581538204 M
Aidan Lynch 0.00023935613200490685 0.0 M
Moran 0.00023935613200490685 0.0 F
Piers Polkiss 0.00023935613200490685 0.0 M
Demelza Robins 0.00023935613200490685 0.00012114490466237255 F
Hestia Jones 0.00023935613200490685 0.00021840208164484068 F
Mafalda Hopkirk 0.00023935613200490685 0.0 F
Alecto Carrow 0.00023935613200490685 0.00022010834790769102 F
Walburga Black 0.0002243963737546001 0.0006330247835174679 F
Gabrielle Delacour 0.0002243963737546001 0.0007063942328200315 F
Bogrod 0.0002243963737546001 0.0 M
Marcus Belby 0.00020943661550429344 0.0 M
Terry Boot 0.00020943661550429344 0.0003941475067184233 M
Helga Hufflepuff 0.00020943661550429344 0.0011141918696412577 F
James Sirius Potter 0.00020943661550429344 0.007430789574713134 M
Hassan Mostafa 0.0001944768572539868 0.0 M
Adrian Pucey 0.0001944768572539868 0.00037879111035277055 M
Karkus 0.0001944768572539868 0.0 M
Professor Tofty 0.0001944768572539868 0.0 M
Wilkie Twycross 0.0001944768572539868 0.0 M
Caractacus Burke 0.0001944768572539868 0.0 M
Jimmy Peakes 0.0001944768572539868 0.00013991383355372607 M
Avery 0.0001944768572539868 0.0 M
Troy 0.00017951709900368011 0.0 M
Augusta Longbottom 0.00017951709900368011 0.00022693341295909223 F
OC 0.0 0.05600307127927314 N
Scorpius Malfoy 0.0 0.02356865588875144 M
Rose Weasley 0.0 0.01751652945442136 F
Lily Luna Potter 0.0 0.01002602056050847 F
Teddy Lupin 0.0 0.009053448790683786 M
Andromeda Tonks 0.0 0.0045352557266561426 F
Victoire Weasley 0.0 0.004069445036898008 F
Astoria Greengrass 0.0 0.004021669581538199 F
Theodore Nott 0.0 0.0033732884016550784 M
Daphne Greengrass 0.0 0.0027778014759203174 F
Marlene McKinnon 0.0 0.002554280595486925 F
Dominique Weasley 0.0 0.001955381137226464 F
Rodolphus Lestrange 0.0 0.001783048244678582 M
Alice Longbottom 0.0 0.001685791067696114 F
Hugo Weasley 0.0 0.0016482532099134069 M
Lucy Weasley 0.0 0.0014179072644286141 F
Lysander Scamander 0.0 0.0014093759331143625 M
Lorcan Scamander 0.0 0.0013445378151260507 M
Roxanne Weasley 0.0 0.0011210169346926588 F
Susan Bones 0.0 0.001078360278121401 F
Fred Weasley II 0.0 0.0010544725504414963 M
Frank Longbottom 0.0 0.0009606279059847287 M
Louis Weasley 0.0 0.0008155952736424518 M
Molly Weasley II 0.0 0.0008138890073796016 F
Sorting Hat 0.0 0.0007285756942370856 N
Rabastan Lestrange 0.0 0.0006756814400887258 M
Audrey Weasley 0.0 0.0006381435823060187 F
Dorcas Meadowes 0.0 0.0004999360150151432 F
Eileen Prince 0.0 0.0004743420210723884 F
Penelope Clearwater 0.0 0.0004709294885466877 F
Helena Ravenclaw 0.0 0.0004658106897581368 F
Rolf Scamander 0.0 0.00043509789702683103 M
Abraxas Malfoy 0.0 0.0004180352343983279 M
Tracey Davis 0.0 0.0004129164356097769 F
Orion Black 0.0 0.00037879111035277055 M
Emmeline Vance 0.0 0.00037708484408992016 F
Mary Macdonald 0.0 0.00033954698630721323 F
Fabian Prewett 0.0 0.000332721921255812 M
Gideon Prewett 0.0 0.000332721921255812 M
Aurora Sinistra 0.0 0.0002985965959988057 F
Newt Scamander 0.0 0.0002934777972102547 M
Tobias Snape 0.0 0.0002712963357932005 M
Druella Black 0.0 0.00026617753700464955 F
Mr. Granger 0.0 0.00026617753700464955 M
Anthony Goldstein 0.0 0.00026447127074179927 M
Evan Rosier 0.0 0.0002491148743761464 M
Cygnus Black 0.0 0.00019280808770208592 M
Dementors 0.0 0.0001723328925478821 N
Alphard Black 0.0 0.00016721409375933114 M
Dorea Black Potter 0.0 0.00016380156123363052 F
Mrs. Lovegood 0.0 0.00016209529497078018 F
Mirror of Erised 0.0 0.00016209529497078018 N
Lisa Turpin 0.0 0.00015527022991937894 F
Charlus Potter 0.0 0.00014844516486797765 M
Phineas Nigellus 0.0 0.0001262637034509235 M
Terence Higgs 0.0 0.0001228511709252229 M
Giant Squid 0.0 0.00011773237213667192 N
Charity Burbage 0.0 0.00011773237213667192 F
Merlin 0.0 0.00011602610587382161 M
Cedrella Weasley Black 0.0 0.00011431983961097128 F
Lyall Lupin 0.0 0.00011090730708527062 M
Fay Dunbar 0.0 0.00011090730708527062 F
Benjy Fenwick 0.0 0.00011090730708527062 M
Basilisk 0.0 0.00011090730708527062 N
Eloise Midgen 0.0 0.00010920104082242034 F
Mrs. Zabini 0.0 0.00010408224203386938 F
Marius Black 0.0 9.725717698246812e-05 M
Ignotus Peverell 0.0 9.725717698246812e-05 M
function CharacterFrequency(options) {
var useGender = options.gender;
// set dimensions for the svg
var margin = {top: 70, right: 150, bottom: 200, left: 100},
w = 1200 - margin.left - margin.right,
h = 600 - margin.top - margin.bottom;
// colors
var color = {
'base': d3.rgb('rgb(185, 11, 11)'),
'other' : '#ffd700',
}
var genderMap = {
'M' : color.base,
'F' : color.other,
'N' : 'grey'
};
// create the svg
var svg = d3.select(options.container).append("svg")
.attr('height', h + margin.top + margin.bottom)
.attr('width', w + margin.left + margin.right)
// set the ranges for the scales
var xScale = d3.scaleBand().rangeRound([0, w]).padding(0.1),
yScale = d3.scaleLinear().range([h, 0]);
var focus = svg.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// listen for radio button change
d3.selectAll("input[name='frequency']").on("change", frequencyTypeChanged)
/**
* Handles when the user chooses 'canon' or 'fan fiction'. Called by radio button change.
* Switches out the data and calls update
*/
function frequencyTypeChanged() {
if (this.value == 'ff') {
all_data.forEach(function(character, i) {
character.percentage = character.fanfiction_percentage;
character.last_rank = i;
});
}
else {
all_data.forEach(function(character, i) {
character.percentage = character.canon_percentage;
character.last_rank = i;
});
}
all_data.sort(function(a, b) {
return b.percentage - a.percentage;
});
cur_display = all_data.slice(0,num_characters);
update();
}
/**
* Resets the domains to cur_display
*/
function updateDomains() {
xScale.domain(cur_display.map(function(d) { return d.name; }));
yScale.domain([0, d3.max(cur_display, function(d) { return d.percentage})]);
}
/**
* Resets the axes (normally called after domains have been updated)
*/
function updateAxes() {
focus.select('.axis--y').call(d3.axisLeft(yScale).ticks(10,'%'))
focus.select('.axis--x').transition()
.duration(2000)
.call(d3.axisBottom(xScale))
focus.selectAll('.axis--x')
.selectAll('text')
.style('text-anchor', 'end')
.attr('dx', '-.8em')
.attr('dy', '.15em')
.attr('transform', 'rotate(-65)');
}
function update() {
// get a copy of the old x scale so we can calculate how much a character moved later
oldXScale = xScale.copy();
updateDomains();
// bind the new data
var bar = focus.selectAll('.bar')
.data(cur_display, function(d) { return d.name})
.on('mouseover', handleBarMouseOver)
.on('mouseout', handleBarMouseOut);
// update- calculate if character increased or decreased in frequency and display color
bar.transition()
.duration(2000)
.attr('y', function(d) { return yScale(d.percentage);})
.attr('height', function(d) { return h - yScale(d.percentage);})
.attr('x', function(d) { return xScale(d.name); })
.attr('fill', function(d) {
if (!useGender) {
var difference = oldXScale(d.name) - xScale(d.name);
var scale = difference / w * 6;
var new_color;
if (scale < 0) {
new_color = color.base.darker(Math.abs(scale));
} else if (scale > 0){
new_color = color.base.brighter(Math.abs(scale));
}
else {
return color.base;
}
return new_color;
} else return genderMap[d.gender];
});
// enter- all new characters have a certain color
var barEnter = bar.enter()
.append('rect')
.on('mouseover', handleBarMouseOver)
.on('mouseout', handleBarMouseOut)
.attr('class','bar')
.attr('width', xScale.bandwidth())
.attr('x', function(d) { return xScale(d.name); })
.transition()
.duration(2000)
.attr('y', function(d) { return yScale(d.percentage); })
.attr('height', function(d) { return h - yScale(d.percentage); })
.attr('fill', function(d) {
if (!useGender) return color.other;
else return genderMap[d.gender];
});
// goodbye characters not in the new top num_characters!
bar.exit().transition()
.attr('fill-opacity', 0)
.remove();
updateAxes();
}
// add groups for the axes
focus.append('g')
.attr('class', 'axis axis--x')
.attr('transform', 'translate(0,' + h +')')
focus.append('g')
.attr('class', 'axis axis--y')
// this variable could be changed to show a different number of characters
var num_characters = 50;
var legend_values = [
{color : genderMap['M'], value : 'male'},
{color : genderMap['F'], value : 'female'},
{color : genderMap['N'], value : 'other'},
]
if (!useGender) {
legend_values = [
{color : color.base.darker(1), value : 'lower ranking' },
{color : color.base.brighter(2), value : 'higher ranking' },
{color : color.other, value : 'not in previous top ' + num_characters },
]
}
var legend = focus.append('g')
.attr('transform', 'translate(' + (w-200) + ',0)');
var key = legend.selectAll('g')
.data(legend_values)
.enter().append('g')
.attr('transform', function(d, i) {
return 'translate(0,' +(i*15)+ ')'
});
key.append('rect')
.attr('width', '10px')
.attr('height', '10px')
.attr('fill', function(d) { return d.color; });
key.append('text')
.attr('x', '15px')
.attr('y', '10px')
.text(function(d) { return d.value; });
var cur_display;
var all_data;
// read in the data
d3.csv("char_frequencies_canon_ff.csv", function(d) {
// coerce from string to numbers
d.canon_percentage = +d.canon_percentage;
d.fanfiction_percentage = +d.fanfiction_percentage;
return d;
}, function(error, data) {
if (error) throw error;
// store for access from other functions
all_data = data;
// start with canon- store in new variable 'percentage'
data.forEach(function(character, i) {
character.percentage = character.canon_percentage;
});
// get the top num_characters in frequency
cur_display = data.slice(0,num_characters);
updateDomains();
// to start- all bars will just be the base color
focus.selectAll('.bar')
.data(cur_display, function(d) { return d.name; })
.enter()
.append('rect')
.attr('class','bar')
.attr('fill', function(d, i) {
if (!useGender) return color.base;
else return genderMap[d.gender];
})
.attr('width', xScale.bandwidth())
.attr('x', function(d) { return xScale(d.name); })
.attr('y', function(d) { return yScale(d.percentage); })
.attr('height', function(d) { return h - yScale(d.percentage); })
.on('mouseover', handleBarMouseOver)
.on('mouseout', handleBarMouseOut);
// initialize the axes
focus.select('.axis--y').call(d3.axisLeft(yScale).ticks(10,'%'))
.append('text')
.attr('transform', 'rotate(-90)')
.attr('y', 6)
.attr('dy', '0.71em')
.attr('text-anchor', 'end')
.text('Frequency')
focus.select('.axis--x').call(d3.axisBottom(xScale))
.selectAll('text') // formatting for x axis labels to be slanted
.style('text-anchor', 'end')
.attr('dx', '-.8em')
.attr('dy', '.15em')
.attr('transform', 'rotate(-65)');
});
// now for some titles/labels
focus.append('text')
.attr('text-anchor', 'middle')
.attr('transform', 'translate(' + (w/2) + ',' + (h + margin.bottom * 3/4) +')')
.text('Character');
focus.append('text')
.attr('text-anchor', 'middle')
.attr('transform', 'translate(' + (w/2) + ',' + -margin.top/2 + ')')
.text('Harry Potter Character Frequency');
/**
* Handles user hovering over a bar
*/
function handleBarMouseOver(d, i) {
var group = focus.append('g')
.attr('id', 'id-name');
var text = group.append('text')
.attr('x', xScale(d.name))
.attr('y', yScale(d.percentage)-10)
.attr('text-anchor', 'middle')
.text(function() {
if (typeof d.last_rank != 'undefined') {
var old_rank = +d.last_rank + 1;
if (old_rank > 200) {
old_rank = ">200";
}
var new_rank = i + 1
var t = d.name + ": rank " + old_rank + " to " + new_rank;
return t;
}
else {
return d.name
}
});
// get the bbox so we can place a background
var bbox = text.node().getBBox();
var bboxPadding = 5;
// place the background
var rect = group.insert('rect', ':first-child')
.attr('x', bbox.x - bboxPadding/2)
.attr('y', bbox.y - bboxPadding/2)
.attr('width', bbox.width + bboxPadding)
.attr('height', bbox.height + bboxPadding)
.attr('rx', 10)
.attr('ry', 10)
.attr('class', 'label-background');
};
/**
* Removes the hover text after user stops hovering
*/
function handleBarMouseOut(d, i) {
d3.select('#id-name').remove();
};
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>After All This Time?</title>
<!-- Import D3 -->
<script src="https://d3js.org/d3.v4.min.js"></script>
<link rel="stylesheet" type='text/css' href="style.css">
</head>
<body>
<form class="user-input">
<input type='radio' name='frequency' value='canon' checked> Canon <br>
<input type='radio' name='frequency' value='ff'> Fan Fiction <br><br>
</form>
<div id='frequency-chart'></div>
<script src="character-frequencies.js"></script>
<script>
CharacterFrequency({
container: '#frequency-chart',
gender: false
});
</script>
</body>
</html>
.axis {
font-family: Helvetica, sans-serif;
font-size: 14px;
}
.axis text{
fill: black;
}
svg text{
font-family: Helvetica, sans-serif;
font-size: 14px;
}
.label-background {
fill: white;
fill-opacity: .5;
}
.user-input {
position: absolute;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment