Skip to content

Instantly share code, notes, and snippets.

@kylefeng28
Last active February 26, 2017 06:52
Show Gist options
  • Save kylefeng28/0dac1640cb6e54cb97aac5144612e594 to your computer and use it in GitHub Desktop.
Save kylefeng28/0dac1640cb6e54cb97aac5144612e594 to your computer and use it in GitHub Desktop.
Lexical Distance Among the Languages of Europe
.DS_Store
.*.swp
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.links line {
stroke: #999;
stroke-width: 1px;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: #fff;
stroke-width: 1px;
}
.labels text {
pointer-events: none;
}
width = window.innerWidth || +svg.attr("width"),
height = window.innerHeight || +svg.attr("height");
</style>
<svg width="960" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
width = window.innerWidth || +svg.attr("width"),
height = window.innerHeight || +svg.attr("height");
// Set width and height
svg.attr("width", width).attr("height", height);
var color = d3.scaleOrdinal(d3.schemeCategory20);
// Zoom
svg.call(d3.zoom().on("zoom", function () {
svg.selectAll("g").attr("transform", d3.event.transform); // Austin wrote this
}));
// Tooltip
var tooltip = d3.select("body")
.append("div")
.attr("class", "d3-tip")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden");
var simulation = d3.forceSimulation()
.force("link",
d3.forceLink()
.id((d) => d.abbrev)
.distance((d) => d.dist * 10)
)
.force("charge", d3.forceManyBody().strength(-1)) // d.mass?
.force("collide", d3.forceCollide((d) => d.radius))
.force("center", d3.forceCenter(width / 2, height / 2));
d3.json("languages.json", function(error, graph) {
if (error) throw error;
window.graph = graph;
// Links
var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("stroke-width", function(d) { return Math.sqrt(d.dist); });
// Nodes
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.each(function (d, i, nodes) {
// Set custom properties
d.color = color(d.family);
d.radius = (d.diameter < 0.3 ? 0.3 : d.diameter) * 10; // TODO
})
.attr("r", (d) => d.radius )
.attr("fill", (d) => d.color)
// Mouse events
.call(d3.drag()
.on("start", ondragstart)
.on("drag", ondrag)
.on("end", ondragend))
.on("mouseover", onmouseover)
.on("mouseout", onmouseout)
.on("mousemove", onmousemove);
node.append("title")
.text(function(d) { return d.abbrev; });
// Add label text
var text = svg.append("g")
.attr("class", "labels")
.selectAll("text")
.data(graph.nodes)
.enter()
.append("text");
simulation
.nodes(graph.nodes)
.on("tick", ticked);
simulation.force("link")
.links(graph.links);
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; });
text
.attr("x", function(d) { return d.x - this.getBBox().width/2; })
.attr("y", function(d) { return d.y; })
.text((d) => d.abbrev)
.attr("font-family", "Helvetica")
// Set size according to zoom
.attr("font-size", (90 / svg.select("g").each(function() {
if(this.transform.baseVal[0]) {
return this.transform.baseVal[0].matrix.e;
} else { return 1; }
})[0]) + "px")
.attr("fill", "#000000");
}
});
function ondragstart(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function ondrag(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
moveTooltip(d);
}
function ondragend(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
function onmouseover(d) {
d3.select(this).transition()
.attr("style", (d) => "stroke: black; stroke-width: " + 1);
showTooltip(d);
}
function onmouseout(d) {
d3.select(this).transition()
// .attr("style", (d) => "stroke: " + d.color + "; stroke-width: 0");
.attr("style", (d) => "stroke: black; stroke-width: 0");
hideTooltip();
}
function onmousemove(d) {
moveTooltip(d);
}
function showTooltip(d) {
var html = "Language: " + d.lang + "<br>";
html += "Family: " + d.family + "</span><br>";
html += "Speakers: " + d.speakers + "</span><br>";
tooltip.style("visibility", "visible").html(html);
}
function moveTooltip(d) {
// TODO put directly above node
tooltip.style("top", (event.pageY-10)+"px").style("left",(event.pageX+10)+"px");
}
function hideTooltip() {
tooltip.style("visibility", "hidden");
}
</script>
<!doctype html>
<meta charset="utf-8">
<style>
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: #fff;
stroke-width: 1.5px;
}
.d3-tip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
}
</style>
<svg width="960" height="600"></svg>
<!--jQuery 3.1.1-->
<script
src="https://code.jquery.com/jquery-3.1.1.min.js"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
crossorigin="anonymous"></script>
<!--d3 v4-->
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="main.js"></script>
<script>
</script>
{
"nodes": [
{
"abbrev": "deu",
"lang": "German",
"family": "Germanic",
"speakers": "95 000 000",
"diameter": 4.75
},
{
"abbrev": "rus",
"lang": "Russian",
"family": "Slavic",
"speakers": "95 000 000",
"diameter": 4.75
},
{
"abbrev": "fra",
"lang": "French",
"family": "Italic-Romance",
"speakers": "60 000 000",
"diameter": 3
},
{
"abbrev": "ita",
"lang": "Italian",
"family": "Italic-Romance",
"speakers": "57 700 000",
"diameter": 2.89
},
{
"abbrev": "eng",
"lang": "English",
"family": "Germanic",
"speakers": "55 600 000",
"diameter": 2.78
},
{
"abbrev": "spa",
"lang": "Spanish",
"family": "Italic-Romance",
"speakers": "45 000 000",
"diameter": 2.25
},
{
"abbrev": "pol",
"lang": "Polish",
"family": "Slavic",
"speakers": "38 663 000",
"diameter": 1.93
},
{
"abbrev": "ukr",
"lang": "Ukrainian",
"family": "Slavic",
"speakers": "37 000 000",
"diameter": 1.85
},
{
"abbrev": "ron",
"lang": "Romanian",
"family": "Italic-Romance",
"speakers": "23 782 000",
"diameter": 1.19
},
{
"abbrev": "nld",
"lang": "Dutch",
"family": "Germanic",
"speakers": "21 944 000",
"diameter": 1.1
},
{
"abbrev": "grk",
"lang": "Greek",
"family": "Hellenic",
"speakers": "13 420 000",
"diameter": 0.67
},
{
"abbrev": "hun",
"lang": "Hungarian",
"family": "Uralic",
"speakers": "12 606 000",
"diameter": 0.63
},
{
"abbrev": "ces",
"lang": "Czech",
"family": "Slavic",
"speakers": "10 619 000",
"diameter": 0.53
},
{
"abbrev": "cat",
"lang": "Catalan",
"family": "Italic-Romance",
"speakers": "10 000 000",
"diameter": 0.5
},
{
"abbrev": "por",
"lang": "Portuguese",
"family": "Italic-Romance",
"speakers": "10 000 000",
"diameter": 0.5
},
{
"abbrev": "swe",
"lang": "Swedish",
"family": "Germanic",
"speakers": "9 197 090",
"diameter": 0.46
},
{
"abbrev": "srp",
"lang": "Serbian",
"family": "Slavic",
"speakers": "8 957 906",
"diameter": 0.45
},
{
"abbrev": "bul",
"lang": "Bulgarian",
"family": "Slavic",
"speakers": "8 157 770",
"diameter": 0.41
},
{
"abbrev": "sqi",
"lang": "Albanian",
"family": "Albanian",
"speakers": "7 400 000",
"diameter": 0.37
},
{
"abbrev": "hrv",
"lang": "Croatian",
"family": "Slavic",
"speakers": "5 752 090",
"diameter": 0.29
},
{
"abbrev": "dan",
"lang": "Danish",
"family": "Germanic",
"speakers": "5 522 490",
"diameter": 0.28
},
{
"abbrev": "fin",
"lang": "Finnish",
"family": "Uralic",
"speakers": "5 392 180",
"diameter": 0.27
},
{
"abbrev": "slk",
"lang": "Slovak",
"family": "Slavic",
"speakers": "5 187 740",
"diameter": 0.26
},
{
"abbrev": "nob",
"lang": "Norwegian Bokmål",
"family": "Germanic",
"speakers": "3 854 000",
"diameter": 0.19
},
{
"abbrev": "bel",
"lang": "Belarusian",
"family": "Slavic",
"speakers": "3 312 610",
"diameter": 0.17
},
{
"abbrev": "lit",
"lang": "Lithuanian",
"family": "Baltic",
"speakers": "3 001 860",
"diameter": 0.15
},
{
"abbrev": "glg",
"lang": "Galician",
"family": "Italic-Romance",
"speakers": "2 355 000",
"diameter": 0.12
},
{
"abbrev": "bos",
"lang": "Bosnian",
"family": "Slavic",
"speakers": "2 225 290",
"diameter": 0.11
},
{
"abbrev": "slv",
"lang": "Slovene",
"family": "Slavic",
"speakers": "2 085 000",
"diameter": 0.1
},
{
"abbrev": "lav",
"lang": "Latvian",
"family": "Baltic",
"speakers": "1 752 260",
"diameter": 0.09
},
{
"abbrev": "mkd",
"lang": "Macedonian",
"family": "Slavic",
"speakers": "1 407 810",
"diameter": 0.07
},
{
"abbrev": "srd",
"lang": "Sardinian",
"family": "Italic-Romance",
"speakers": "1 200 000",
"diameter": 0.06
},
{
"abbrev": "est",
"lang": "Estonian",
"family": "Uralic",
"speakers": "1 165 400",
"diameter": 0.06
},
{
"abbrev": "nno",
"lang": "Norwegian Nynorsk",
"family": "Germanic",
"speakers": "846 000",
"diameter": 0.04
},
{
"abbrev": "wln",
"lang": "Walloon",
"family": "Italic-Romance",
"speakers": "600 000",
"diameter": 0.0
},
{
"abbrev": "eus",
"lang": "Basque",
"family": "Basque",
"speakers": "545 872",
"diameter": 0.03
},
{
"abbrev": "cym",
"lang": "Welsh",
"family": "Celtic",
"speakers": "536 890",
"diameter": 0.03
},
{
"abbrev": "mlt",
"lang": "Maltese",
"family": "Semitic",
"speakers": "522 000",
"diameter": 0.03
},
{
"abbrev": "szl",
"lang": "Silesian",
"family": "Slavic",
"speakers": "510 000",
"diameter": 0.03
},
{
"abbrev": "mis1",
"lang": "Montenegrin",
"family": "Slavic",
"speakers": "510 000",
"diameter": 0.03
},
{
"abbrev": "fry",
"lang": "Western Frisian",
"family": "Germanic",
"speakers": "467 000",
"diameter": 0.02
},
{
"abbrev": "ltz",
"lang": "Luxembourgish",
"family": "Germanic",
"speakers": "336 710",
"diameter": 0.02
},
{
"abbrev": "isl",
"lang": "Icelandic",
"family": "Germanic",
"speakers": "300 000",
"diameter": 0.02
},
{
"abbrev": "gle",
"lang": "Irish",
"family": "Celtic",
"speakers": "276 310",
"diameter": 0.01
},
{
"abbrev": "oci",
"lang": "Occitan",
"family": "Italic-Romance",
"speakers": "220 000",
"diameter": 0.01
},
{
"abbrev": "bre",
"lang": "Breton",
"family": "Celtic",
"speakers": "206 000",
"diameter": 0.01
},
{
"abbrev": "pcd",
"lang": "Picard",
"family": "Italic-Romance",
"speakers": "200 000",
"diameter": 0.01
},
{
"abbrev": "frp",
"lang": "Franco-Provençal",
"family": "Italic-Romance",
"speakers": "140 000",
"diameter": 0.01
},
{
"abbrev": "rup",
"lang": "Aromanian",
"family": "Italic-Romance",
"speakers": "114 340",
"diameter": 0.01
},
{
"abbrev": "ast",
"lang": "Asturian",
"family": "Italic-Romance",
"speakers": "110 000",
"diameter": 0.01
},
{
"abbrev": "gla",
"lang": "Scottish Gaelic",
"family": "Celtic",
"speakers": "68 130",
"diameter": 0
},
{
"abbrev": "fao",
"lang": "Faroese",
"family": "Germanic",
"speakers": "66 150",
"diameter": 0
},
{
"abbrev": "lat",
"lang": "Latin",
"family": "Italic-Romance",
"speakers": "30 000",
"diameter": 0
},
{
"abbrev": "wen",
"lang": "Sorbian",
"family": "Slavic",
"speakers": "30 000",
"diameter": 0
}
],
"links": [
{ "source": "eng", "target": "fra", "dist": 56 },
{ "source": "eng", "target": "cym", "dist": 80 },
{ "source": "eng", "target": "nld", "dist": 37 },
{ "source": "eng", "target": "isl", "dist": 50 },
{ "source": "eng", "target": "deu", "dist": 49 },
{ "source": "eng", "target": "dan", "dist": 50 },
{ "source": "eng", "target": "nno", "dist": 49 }
]
}
View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment