Skip to content

Instantly share code, notes, and snippets.

@tomcardoso
Last active April 19, 2016 20:18
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 tomcardoso/1aa4e5a2d3912e178bd3 to your computer and use it in GitHub Desktop.
Save tomcardoso/1aa4e5a2d3912e178bd3 to your computer and use it in GitHub Desktop.
[
["title","time","singlePerson","group","race","gender","quote" ],
["Lucille Teasdale","1960s","Yes","No","White","Female","" ],
["Laura Secord","1810s","Yes","No","White","Female","Take me to Fitzgibbon." ],
["Peacemaker","Unknown","Yes","No","Indigenous","Male","Does the great peace still have power? You're here, aren't you?" ],
["Vikings","1980s","No","Yes","White","Male","" ],
["John Cabot","1490s","Yes","No","White","Male","Fishes enough to feed this kingdom - o, sire, until the end of time!" ],
["Jacques Cartier","1530s","Yes","No","White","Male","But I'm sure it means the houses, the village." ],
["Jean Nicollet","1630s","Yes","No","White","Male","Mississippi! The sea! China!" ],
["Syrup","Unknown","No","Yes","Indigenous","Both","" ],
["Governor Frontenac","1690s","Yes","No","White","Male","I will reply from the mouth of my cannon!" ],
["Hart & Papineau","1800s","No","Yes","White","Male","" ],
["Etienne Parent","1830s","Yes","No","White","Male","Our two races can live side by side without one side enslaving the other." ],
["Baldwin & Lafontaine","1840s","No","Yes","White","Male","Mr. Lafontaine, think of the history we'll make when a French-Canadian runs and wins in York." ],
["Responsible gov't","1840s","Yes","No","White","Female","Responsible government. ... It's a Canadian idea." ],
["Orphans","1850s","No","No","White","Both","" ],
["Underground Railroad","1840s","No","No","Black","Both","Liza!" ],
["Joseph Casavant","1830s","Yes","No","White","Male","I call it the Marching Thunder!" ],
["The Paris Crew","1860s","No","Yes","White","Male","" ],
["Saguenay Fire","1870s","No","No","White","Both","His hair's on fire!" ],
["Jennie Trout","1870s","Yes","No","White","Female","There's no place for women in medical school!" ],
["Sitting Bull","1870s","Yes","No","Indigenous","Male","I do not want lies! These men ... are the first white men who never lied to us!" ],
["Les Voltigeurs de Quebec","1880s","No","Yes","White","Male","Gentlemen, this piece deserves better!" ],
["Sir Sandford Fleming","1860s","Yes","No","White","Male","We aren't just building a railroad, gentlemen! We are building a country!" ],
["Rural Teacher","1880s","No","Yes","White","Female","" ],
["Soddie","1890s","No","No","White","Both","" ],
["Midwife","Unknown","No","Yes","White","Female","" ],
["Basketball","1900s","Yes","No","White","Male","Is this some kind of Canadian joke, sir?" ],
["Sam Steele","1890s","Yes","No","White","Male","Why didn't I shoot him?" ],
["Frontier College","1920s","No","No","White","Male","" ],
["Marconi","1900s","Yes","No","White","Male","Through the air, across the ocean. The first time - ever." ],
["Grey Owl","Unknown","Yes","No","White","Male","Men become what they dream. You have dreamed well." ],
["Valour Road","1910s","No","No","White","Male","" ],
["Winnie","1910s","No","No","White","Male","Oh, Daddy. I just love Winnie. Couldn't we take him home with us?" ],
["Nitro","1880s","No","Yes","Asian","Male","You see, there is one dead Chinese man for every mile of the track!" ],
["John McCrae","1910s","Yes","No","White","Male","John McCrae died in the war, but his poem is still read when children gather to remember." ],
["J.S. Woodworth","1920s","Yes","No","White","Male","Is it too much to ask that Canada take care of poor people, 70 years of age, who helped build this country?" ],
["Halifax Explosion","1910s","No","No","White","Male","" ],
["Joseph-Armand Bombardier","1920s","Yes","No","White","Male","" ],
["Emily Murphy","1920s","Yes","No","White","Female","I, Emily Murphy of Alberta, and all Canadian women after me ... Persons, under the law." ],
["Superman","1930s","Yes","No","White","Male","No ones going to read a comic strip about a superhero in tights, Joe. It'll never fly." ],
["Myrnam Hospital","1930s","No","No","White","Both","" ],
["La Bolduc","1930s","Yes","No","White","Female","" ],
["Inukshuk","1930s","No","No","Indigenous","Both","Now the people will know we were here." ],
["Wilder Penfield","1930s","Yes","No","White","Male","Dr. Penfield, I can smell burnt toast!" ],
["Agnes Macphail","1930s","Yes","No","White","Female","Is this normal?" ],
["Bluenose","1930s","No","Yes","White","Male","Just once more, old girl. Then you can rest." ],
["Emily Carr","Unknown","Yes","No","White","Female","At last, I knew I must see through the eye of the totem itself ... The mythic eye of the forest." ],
["Pauline Vanier","1930s","Yes","No","White","Female","" ],
["Marion Orr","1940s","Yes","No","White","Female","You know what my dream is? To go home when this is all over. Find a grass strip somewhere in Ontario ... Teach flying." ],
["Maurice \"Rocket\" Richard","1940s","Yes","No","White","Male","" ],
["Jackie Robinson","1940s","Yes","No","Black","Male","" ],
["John Humphrey","1940s","Yes","No","White","Male","Say, isn't that the Canadian who actually wrote the declaration of human rights?" ],
["Avro Arrow","1950s","No","No","White","Both","" ],
["Stratford","1950s","No","Yes","White","Both","" ],
["Paule Emile Borduas","1940s","Yes","No","White","Male","Life goes on. The important thing is to be able to create - isn't it?" ],
["Le Reseau","1950s","Yes","No","White","Male","" ],
["Maurice Ruddick","1950s","Yes","No","Black","Male","Closed now ... So much death. But my, didn't we sing those hymns ... Together?" ],
["Jacques Plante","1950s","Yes","No","White","Male","You're a great man, Mr. Plante - standing up to 'em like that." ],
["Marshall McLuhan","1960s","Yes","No","White","Male","It's obvious. The medium IS the message." ],
["Flags","1960s","Yes","No","White","Male","" ],
["Expo 67","1960s","No","Yes","White","Male","" ],
["Nat Taylor","1950s","Yes","No","White","Male","" ],
["Water Pump","1980s","No","Yes","White","Both","Well, maybe today's technology is the problem." ],
["Nellie McClung","1910s","Yes","No","White","Female","Madam Speaker, take it from me ... Nice men don't want the vote." ],
["Louis Riel","1880s","Yes","No","Indigenous","Male","We have a right to God's lands. ... Perhaps I am a prophet. I've suffered enough." ],
["Maple Leaf Gardens","1920s","No","No","White","Male","" ],
["Andrew Mynarski","1940s","Yes","No","White","Male","" ],
["Mona Parsons","1940s","Yes","No","White","Female","Gentlemen, good morning." ],
["Tommy Prince","1970s","Yes","No","Indigenous","Male","" ],
["Vimy Ridge","1910s","No","No","White","Male","And Mother, I thought ... We are a nation! This is us!" ],
["Osborn of Hong Kong","1940s","Yes","No","White","Male","Grenades! Grenades! Grenaaaaaaaaaaaaaaaaa ...!!" ],
["Home from the Wars","1940s","No","Yes","White","Both","Is that any way to treat citizens that have gone through what we have gone through?" ],
["Detraze in the Congo","1960s","Yes","No","White","Male","" ],
["Juno Beach","1940s","No","No","White","Male","" ],
["Richard Pierpoint","1810s","Yes","No","Black","Male","With respect, sir, I was born a free man and I intend to die one." ],
["Queenston Heights","1810s","No","Yes","Indigenous","Male","Comrades and brothers, remember the fame of ancient warriors." ],
["Winnipeg Falcons","1920s","No","Yes","White","Male","This is the game we've been saving it for. For us. For Canada." ],
["Terry Fox","1980s","Yes","No","White","Male","I want to set an example that'll never be forgotten." ],
["Nursing Sisters","1910s","No","Yes","White","Female","If this war doesn't end soon't be a man living on the face of the earth. But don't worry. These nurses continue. I continue." ],
["John A. Macdonald","1860s","Yes","No","White","Male","Gentlemen, the time for union is now. I ask you to take the dare!" ],
["George-Etienne Cartier","1880s","Yes","No","White","Male","Bold as a lion, Confederation could not have happened but for him." ],
["Joseph Tyrell","1880s","Yes","No","White","Male","The blackfoot called them the grandfather of the buffalo. It would prove to be one of the richest dinosaur deposits in the world." ]
]
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<body>
<style type="text/css">
body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans serif;
color: #333;
line-height: 1.1;
}
.wrapper {
width: 620px;
margin: 40px auto;
}
.gi-heading {
font-family: 'Helvetica Neue';
font-weight: bold;
font-size: 22px;
padding-bottom: 0px;
margin-bottom: 12px;
}
.gi-chart_text {
padding: 10px;
background-color: #f9f9f9;
}
.gi-chart_text div {
padding: 0;
margin: 0;
}
.gi-legend {
text-anchor: middle;
font-weight: bold;
}
.gi-circle:hover {
stroke: #CE2A23;
stroke-width: 1px;
cursor: pointer;
}
.gi-title,
.gi-quote {
font-size: 20px;
color: #333;
}
.gi-title {
font-weight: bold;
}
.gi-title:empty:before {
content: "Heritage Moment title";
color: #cacaca;
}
.gi-quote.gi-text_active:empty:before, .gi-title.gi-text_active:empty:before {
content: "";
}
.gi-quote:empty:before {
content: "Quote";
color: #cacaca;
}
.gi-svg {
background-color: #f9f9f9;
}
.gi-circle {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
.gi-circle_active {
stroke: #CE2A23;
stroke-width: 2px;
}
.gi-selected {
stroke: #CE2A23;
stroke-width: 2px;
}
.gi-btngroup {
margin-bottom: 16px;
}
.gi-btngroup_button {
font-size: 17px;
display: inline-block;
padding: 7px;
border-radius: 5px;
border: 1px solid #333;
margin-right: 8px;
cursor: pointer;
opacity: 0.2;
}
.gi-btngroup_button:hover {
opacity: 0.8;
border-color: #CE2A23;
color: #CE2A23;
}
.gi-btngroup_button.gi-btngroup_button-active {
opacity: 1;
}
.gi-footer {
text-transform: uppercase;
font-size: 12px;
margin-top: 4px;
}
.gi-footer p {
margin: 0;
}
</style>
<div class="wrapper">
<div class="gi-heading">All previous Heritage Minutes, by race and gender</div>
<div class="gi-btngroup">
</div>
<div class="gi-chart_text">
<div class="gi-title"></div>
<div class="gi-quote"></div>
</div>
<div class="gi-chart"></div>
</div>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="main.js"></script>
</body>
</html>
var data = [];
var margin = {
top: 10,
right: 10,
bottom: 10,
left: 10
};
var width = d3.select(".gi-chart").node().getBoundingClientRect().width - margin.left - margin.right;
var screenScale = d3.scale.linear()
.domain([300, 900])
.range([0.6, 0.4]);
var dotScale = d3.scale.linear()
.domain([300, 620])
.range([0.6, 1]);
if (width > screenScale.domain()[1]) {
screenScale.domain([300, width]);
};
var height = (width * screenScale(width)) - margin.top - margin.bottom,
maxRadius = 8 * dotScale(width),
padding = 1.5,
clusterPadding = 0;
var raceExt = [],
genderExt = [];
var svg = d3.select(".gi-chart").append("svg")
.attr({
"width": width + margin.left + margin.right,
"height": height + margin.top + margin.bottom,
"class": "gi-svg"
})
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.json("data.json", function(err, jsonData) {
if (err) { console.log(err); }
var header = jsonData.shift();
jsonData.forEach(function(d, i) {
var obj = {};
for (var i = 0; i < d.length; i++) {
obj[this[i]] = d[i];
};
data.push(obj);
}, header);
d3.map(data, function(d) {
if (raceExt.indexOf(d.race) < 0) { raceExt.push(d.race); }
if (genderExt.indexOf(d.gender) < 0) { genderExt.push(d.gender); }
});
var color = d3.scale.ordinal()
.domain(raceExt)
.range(["#CCC", "#636363", "#CE2A23", "#252525"]);
var circleGroup = svg.append("g")
.attr({
"transform": "translate(0," + (height * 0.08 * -1) + ")",
"class": "gi-circle-group"
});
var circle = circleGroup.selectAll("circle").data(data);
circle.enter().append("circle")
.attr({
"class": "gi-circle",
"fill": function(d) { return color(d.race); }
})
.on("click", function(d) {
d3.selectAll(".gi-circle_active").classed("gi-circle_active", false);
d3.select(this).classed("gi-circle_active", true);
d3.select(".gi-title")
.classed("gi-text_active", true)
.text(d.title);
var quote = (d.quote !== "") ? "&ldquo;" + d.quote + "&rdquo;" : "";
d3.select(".gi-quote")
.classed("gi-text_active", true)
.html(quote);
});
var labelGroup = svg.append("g")
.attr("class", "gi-legend");
var buttons = d3.select(".gi-btngroup").selectAll(".gi-btngroup_button")
.data(["race", "gender"]).enter()
.append("div")
.text(function(d) { return d === "race" ? "Race" : "Gender"; })
.attr("class", function(d) {
var str = "";
if (d === "race") { str += "gi-btngroup_button-active " }
return str += "gi-btngroup_" + d;
})
.classed("gi-btngroup_button", true)
.on("click", function(d) {
buttons.classed("gi-btngroup_button-active", false);
d3.select(this).classed("gi-btngroup_button-active", true);
updateChart(d)
});
var force = d3.layout.force();
updateChart("race");
function updateChart(type) {
var extent = (type === "race") ? raceExt : genderExt;
var x = d3.scale.ordinal()
.domain(d3.range(extent.length))
.rangePoints([0, width], 1);
data = data.map(function(d, i) {
var i = extent.indexOf(d[type]);
d.radius = maxRadius;
d.cx = x(i);
d.cy = height / 2;
return d;
});
circle
.data(data)
.attr("r", function(d) { return d.radius; })
.call(force.drag);
force
.nodes(data)
.size([width, height])
.gravity(0)
.charge(0)
.on("tick", tick)
.start();
labels(extent);
}
function labels(extent) {
svg.selectAll(".gi-legend_text").remove();
var textScale = d3.scale.ordinal()
.domain(d3.range(extent.length))
.rangeRoundBands([0, width]);
labelGroup.selectAll("text")
.data(extent)
.enter().append("text")
.attr({
"x": function(d, i) { return (textScale.rangeBand() / 2) + (textScale.rangeBand() * i); },
"y": height - (height * 0.1),
"class": "gi-legend_text"
})
.text(function(d) { return d; });
}
function tick(e) {
circle
.each(gravity(.2 * e.alpha))
.each(collide(.5))
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}
// Move nodes toward cluster focus.
function gravity(alpha) {
return function(d) {
d.y += (d.cy - d.y) * alpha;
d.x += (d.cx - d.x) * alpha;
};
}
// Resolve collisions between nodes.
function collide(alpha) {
var quadtree = d3.geom.quadtree(data);
return function(d) {
var r = d.radius + maxRadius + Math.max(padding, clusterPadding),
nx1 = d.x - r,
nx2 = d.x + r,
ny1 = d.y - r,
ny2 = d.y + r;
quadtree.visit(function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== d)) {
var x = d.x - quad.point.x,
y = d.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = d.radius + quad.point.radius + (d.color === quad.point.color ? padding : clusterPadding);
if (l < r) {
l = (l - r) / l * alpha;
d.x -= x *= l;
d.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
});
};
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment