Skip to content

Instantly share code, notes, and snippets.

@jeremycflin
Last active October 12, 2015 23:07
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 jeremycflin/436048b8bbc49e5d1598 to your computer and use it in GitHub Desktop.
Save jeremycflin/436048b8bbc49e5d1598 to your computer and use it in GitHub Desktop.
Taiwanese Exchange Student Visualization
'use strict';
var D2R = Math.PI / 180;
var R2D = 180 / Math.PI;
var Coord = function(lon,lat) {
this.lon = lon;
this.lat = lat;
this.x = D2R * lon;
this.y = D2R * lat;
};
Coord.prototype.view = function() {
return String(this.lon).slice(0, 4) + ',' + String(this.lat).slice(0, 4);
};
Coord.prototype.antipode = function() {
var anti_lat = -1 * this.lat;
var anti_lon = (this.lon < 0) ? 180 + this.lon : (180 - this.lon) * -1;
return new Coord(anti_lon, anti_lat);
};
var LineString = function() {
this.coords = [];
this.length = 0;
};
LineString.prototype.move_to = function(coord) {
this.length++;
this.coords.push(coord);
};
var Arc = function(properties) {
this.properties = properties || {};
this.geometries = [];
};
Arc.prototype.json = function() {
if (this.geometries.length <= 0) {
return {'geometry': { 'type': 'LineString', 'coordinates': null },
'type': 'Feature', 'properties': this.properties
};
} else if (this.geometries.length == 1) {
return {'geometry': { 'type': 'LineString', 'coordinates': this.geometries[0].coords },
'type': 'Feature', 'properties': this.properties
};
} else {
var multiline = [];
for (var i = 0; i < this.geometries.length; i++) {
multiline.push(this.geometries[i].coords);
}
return {'geometry': { 'type': 'MultiLineString', 'coordinates': multiline },
'type': 'Feature', 'properties': this.properties
};
}
};
// TODO - output proper multilinestring
Arc.prototype.wkt = function() {
var wkt_string = '';
var wkt = 'LINESTRING(';
var collect = function(c) { wkt += c[0] + ' ' + c[1] + ','; };
for (var i = 0; i < this.geometries.length; i++) {
if (this.geometries[i].coords.length === 0) {
return 'LINESTRING(empty)';
} else {
var coords = this.geometries[i].coords;
coords.forEach(collect);
wkt_string += wkt.substring(0, wkt.length - 1) + ')';
}
}
return wkt_string;
};
/*
* http://en.wikipedia.org/wiki/Great-circle_distance
*
*/
var GreatCircle = function(start,end,properties) {
if (!start || start.x === undefined || start.y === undefined) {
throw new Error("GreatCircle constructor expects two args: start and end objects with x and y properties");
}
if (!end || end.x === undefined || end.y === undefined) {
throw new Error("GreatCircle constructor expects two args: start and end objects with x and y properties");
}
this.start = new Coord(start.x,start.y);
this.end = new Coord(end.x,end.y);
this.properties = properties || {};
var w = this.start.x - this.end.x;
var h = this.start.y - this.end.y;
var z = Math.pow(Math.sin(h / 2.0), 2) +
Math.cos(this.start.y) *
Math.cos(this.end.y) *
Math.pow(Math.sin(w / 2.0), 2);
this.g = 2.0 * Math.asin(Math.sqrt(z));
if (this.g == Math.PI) {
throw new Error('it appears ' + start.view() + ' and ' + end.view() + " are 'antipodal', e.g diametrically opposite, thus there is no single route but rather infinite");
} else if (isNaN(this.g)) {
throw new Error('could not calculate great circle between ' + start + ' and ' + end);
}
};
/*
* http://williams.best.vwh.net/avform.htm#Intermediate
*/
GreatCircle.prototype.interpolate = function(f) {
var A = Math.sin((1 - f) * this.g) / Math.sin(this.g);
var B = Math.sin(f * this.g) / Math.sin(this.g);
var x = A * Math.cos(this.start.y) * Math.cos(this.start.x) + B * Math.cos(this.end.y) * Math.cos(this.end.x);
var y = A * Math.cos(this.start.y) * Math.sin(this.start.x) + B * Math.cos(this.end.y) * Math.sin(this.end.x);
var z = A * Math.sin(this.start.y) + B * Math.sin(this.end.y);
var lat = R2D * Math.atan2(z, Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
var lon = R2D * Math.atan2(y, x);
return [lon, lat];
};
/*
* Generate points along the great circle
*/
GreatCircle.prototype.Arc = function(npoints,options) {
var first_pass = [];
if (!npoints || npoints <= 2) {
first_pass.push([this.start.lon, this.start.lat]);
first_pass.push([this.end.lon, this.end.lat]);
} else {
var delta = 1.0 / (npoints - 1);
for (var i = 0; i < npoints; ++i) {
var step = delta * i;
var pair = this.interpolate(step);
first_pass.push(pair);
}
}
/* partial port of dateline handling from:
gdal/ogr/ogrgeometryfactory.cpp
TODO - does not handle all wrapping scenarios yet
*/
var bHasBigDiff = false;
var dfMaxSmallDiffLong = 0;
// from http://www.gdal.org/ogr2ogr.html
// -datelineoffset:
// (starting with GDAL 1.10) offset from dateline in degrees (default long. = +/- 10deg, geometries within 170deg to -170deg will be splited)
var dfDateLineOffset = options && options.offset ? options.offset : 10;
var dfLeftBorderX = 180 - dfDateLineOffset;
var dfRightBorderX = -180 + dfDateLineOffset;
var dfDiffSpace = 360 - dfDateLineOffset;
// https://github.com/OSGeo/gdal/blob/7bfb9c452a59aac958bff0c8386b891edf8154ca/gdal/ogr/ogrgeometryfactory.cpp#L2342
for (var j = 1; j < first_pass.length; ++j) {
var dfPrevX = first_pass[j-1][0];
var dfX = first_pass[j][0];
var dfDiffLong = Math.abs(dfX - dfPrevX);
if (dfDiffLong > dfDiffSpace &&
((dfX > dfLeftBorderX && dfPrevX < dfRightBorderX) || (dfPrevX > dfLeftBorderX && dfX < dfRightBorderX))) {
bHasBigDiff = true;
} else if (dfDiffLong > dfMaxSmallDiffLong) {
dfMaxSmallDiffLong = dfDiffLong;
}
}
var poMulti = [];
if (bHasBigDiff && dfMaxSmallDiffLong < dfDateLineOffset) {
var poNewLS = [];
poMulti.push(poNewLS);
for (var k = 0; k < first_pass.length; ++k) {
var dfX0 = parseFloat(first_pass[k][0]);
if (k > 0 && Math.abs(dfX0 - first_pass[k-1][0]) > dfDiffSpace) {
var dfX1 = parseFloat(first_pass[k-1][0]);
var dfY1 = parseFloat(first_pass[k-1][1]);
var dfX2 = parseFloat(first_pass[k][0]);
var dfY2 = parseFloat(first_pass[k][1]);
if (dfX1 > -180 && dfX1 < dfRightBorderX && dfX2 == 180 &&
k+1 < first_pass.length &&
first_pass[k-1][0] > -180 && first_pass[k-1][0] < dfRightBorderX)
{
poNewLS.push([-180, first_pass[k][1]]);
k++;
poNewLS.push([first_pass[k][0], first_pass[k][1]]);
continue;
} else if (dfX1 > dfLeftBorderX && dfX1 < 180 && dfX2 == -180 &&
k+1 < first_pass.length &&
first_pass[k-1][0] > dfLeftBorderX && first_pass[k-1][0] < 180)
{
poNewLS.push([180, first_pass[k][1]]);
k++;
poNewLS.push([first_pass[k][0], first_pass[k][1]]);
continue;
}
if (dfX1 < dfRightBorderX && dfX2 > dfLeftBorderX)
{
// swap dfX1, dfX2
var tmpX = dfX1;
dfX1 = dfX2;
dfX2 = tmpX;
// swap dfY1, dfY2
var tmpY = dfY1;
dfY1 = dfY2;
dfY2 = tmpY;
}
if (dfX1 > dfLeftBorderX && dfX2 < dfRightBorderX) {
dfX2 += 360;
}
if (dfX1 <= 180 && dfX2 >= 180 && dfX1 < dfX2)
{
var dfRatio = (180 - dfX1) / (dfX2 - dfX1);
var dfY = dfRatio * dfY2 + (1 - dfRatio) * dfY1;
poNewLS.push([first_pass[k-1][0] > dfLeftBorderX ? 180 : -180, dfY]);
poNewLS = [];
poNewLS.push([first_pass[k-1][0] > dfLeftBorderX ? -180 : 180, dfY]);
poMulti.push(poNewLS);
}
else
{
poNewLS = [];
poMulti.push(poNewLS);
}
poNewLS.push([dfX0, first_pass[k][1]]);
} else {
poNewLS.push([first_pass[k][0], first_pass[k][1]]);
}
}
} else {
// add normally
var poNewLS0 = [];
poMulti.push(poNewLS0);
for (var l = 0; l < first_pass.length; ++l) {
poNewLS0.push([first_pass[l][0],first_pass[l][1]]);
}
}
var arc = new Arc(this.properties);
for (var m = 0; m < poMulti.length; ++m) {
var line = new LineString();
arc.geometries.push(line);
var points = poMulti[m];
for (var j0 = 0; j0 < points.length; ++j0) {
line.move_to(points[j0]);
}
}
return arc;
};
if (typeof window === 'undefined') {
// nodejs
module.exports.Coord = Coord;
module.exports.Arc = Arc;
module.exports.GreatCircle = GreatCircle;
} else {
// browser
var arc = {};
arc.Coord = Coord;
arc.Arc = Arc;
arc.GreatCircle = GreatCircle;
}
end_lat end_long start_lat start_long end_country start_country count year
35.8592948 104.1361117 23.5 121 大陸地區 台灣 187 101
34.7857324 134.3756902 23.5 121 日本 台灣 97 101
37.6 -95.665 23.5 121 美國 台灣 164 101
35.8615124 127.096405 23.5 121 大韓民國(南韓) 台灣 71 101
51.1719674 10.4541194 23.5 121 德意志聯邦共和國 台灣 99 101
46.2157467 2.2088258 23.5 121 法國 台灣 68 101
55.3632592 -3.4433238 23.5 121 英國 台灣 62 101
52.2129919 5.2793703 23.5 121 荷蘭王國 台灣 54 101
49.8037633 15.4749126 23.5 121 捷克共和國 台灣 37 101
56 -96 23.5 121 加拿大 台灣 36 101
62.1983366 17.5652566 23.5 121 瑞典王國 台灣 42 101
-27.9210555 133.247866 23.5 121 澳大利亞 台灣 33 101
22.3576782 114.1210181 23.5 121 香港 台灣 53 101
40.2085 -3.713 23.5 121 西班牙王國 台灣 24 101
47.696472 13.3457348 23.5 121 奧地利共和國 台灣 43 101
13.03887 101.490104 23.5 121 泰王國(泰國) 台灣 19 101
1.3147308 103.8470128 23.5 121 新加坡共和國 台灣 44 101
4.140634 109.6181485 23.5 121 馬來西亞 台灣 22 101
64.9146659 26.0672553 23.5 121 芬蘭共和國 台灣 20 101
11.6978351 122.6217542 23.5 121 菲律賓共和國 台灣 34 101
35.8592948 104.1361117 23.5 121 大陸地區 台灣 276 102
34.7857324 134.3756902 23.5 121 日本 台灣 81 102
37.6 -95.665 23.5 121 美國 台灣 80 102
35.8615124 127.096405 23.5 121 大韓民國(南韓) 台灣 68 102
51.1719674 10.4541194 23.5 121 德意志聯邦共和國 台灣 48 102
46.2157467 2.2088258 23.5 121 法國 台灣 49 102
55.3632592 -3.4433238 23.5 121 英國 台灣 45 102
52.2129919 5.2793703 23.5 121 荷蘭王國 台灣 46 102
13.03887 101.490104 23.5 121 泰國 台灣 13 102
40.2085 -3.713 23.5 121 西班牙 台灣 20 102
64.9146659 26.0672553 23.5 121 芬蘭 台灣 28 102
22.3576782 114.1210181 23.5 121 香港 台灣 56 102
49.8037633 15.4749126 23.5 121 捷克共和國 台灣 39 102
50.5010789 4.4764594 23.5 121 比利時 台灣 25 102
56 -96 23.5 121 加拿大 台灣 40 102
4.140634 109.6181485 23.5 121 馬來西亞 台灣 45 102
47.696472 13.3457348 23.5 121 奧地利 台灣 42 102
1.3147308 103.8470128 23.5 121 新加坡共和國 台灣 50 102
62.1983366 17.5652566 23.5 121 瑞典 台灣 47 102
-27.9210555 133.247866 23.5 121 澳大利亞 台灣 36 102
35.8592948 104.1361117 23.5 121 大陸 台灣 170 103
34.7857324 134.3756902 23.5 121 日本 台灣 60 103
37.6 -95.665 23.5 121 美國 台灣 45 103
35.8615124 127.096405 23.5 121 南韓 台灣 44 103
51.1719674 10.4541194 23.5 121 德國 台灣 35 103
46.2157467 2.2088258 23.5 121 法國 台灣 36 103
56 -96 23.5 121 加拿大 台灣 31 103
52.2682651 5.5201215 23.5 121 荷蘭 台灣 24 103
55.3632592 -3.4433238 23.5 121 英國 台灣 13 103
40.2085 -3.713 23.5 121 西班牙 台灣 17 103
22.3576782 114.1210181 23.5 121 香港 台灣 35 103
47.696472 13.3457348 23.5 121 奧地利共和國 台灣 24 103
62.1983366 17.5652566 23.5 121 瑞典 台灣 24 103
-27.9210555 133.247866 23.5 121 澳大利亞 台灣 17 103
1.3147308 103.8470128 23.5 121 新加坡共和國 台灣 27 103
51.9189046 19.1343786 23.5 121 波蘭 台灣 13 103
64.9146659 26.0672553 23.5 121 芬蘭 台灣 12 103
46.8131873 8.2242101 23.5 121 瑞士 台灣 15 103
4.140634 109.6181485 23.5 121 馬來西亞 台灣 22 103
<!DOCTYPE html>
<meta charset='utf-8'>
<html>
<style>
body{
font-family: "Helvetica Neue";
}
.baseMap{
stroke-width:0.8px;
stroke:#555;
fill:#555;
opacity:0.5;
}
.globe {
fill: #000;
}
.cities_end{
/*fill:rgba(29, 168, 183, .5);*/
fill:rgba(230, 255, 0, 0.5);
/* 254*/
/* fill:none;*/
stroke-width: 1;
stroke: white;
/* fill:none;*/
}
.line{
stroke:rgba(230, 255, 0, 0.8);
/* stroke:rgba(253,141,3,.3);*/
stroke-width:1.5px;
fill:none;
}
.geo-globe {
fill: rgba(236,249,255,0.8);
/* fill:white;*/
}
.years{
font-size:18px;
font-weight: 600;
font-family: "Helvetica Neue";
fill:black;
opacity: 0.8;
}
.country{
font-size:15px;
font-family: "Helvetica Neue";
fill:black;
opacity: 0.7;
}
.maps{
width: 100%;
max-width: 400px;
position: relative;
display: inline-block;
text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
margin-left: 50px;
}
@media (max-width: 600px) {
.maps {
margin-left: 0px;
}
}
table{
font-family: "新細明體";
}
/*div {
outline: 1px solid black;
}
svg {
outline: 1px solid orange;
position: absolute;
top: 0;
left: 0;
}
g {
outline: 1px solid red;
}*/
.title{
text-align: center;
}
h1{
font-size: 50px;
margin-top: 10px;
/* color:rgb(33, 113, 181);*/
color:#333333;
}
h3{
font-weight: 500;
margin-top: -20px;
color:#333333;
opacity:0.8;
font-size: 15px;
}
.table{
max-width: 1200px;
margin:auto;
font-size: .9em;
color:#333333;
}
a{
background-color: rgba(230, 255, 0, 0.5);
text-decoration: none;
color:black;
}
a:hover{
background-color: rgba(255,179,213,0.4);
-webkit-transition: background-color 300ms linear;
-moz-transition: background-color 300ms linear;
-o-transition: background-color 300ms linear;
-ms-transition: background-color 300ms linear;
transition: background-color 300ms linear;
}
</style>
<body>
<script src='https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/queue-async/1.0.7/queue.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.min.js'></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src='arc.js'></script>
<!-- Latest compiled and minified Bootstrap JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.9/js/jquery.dataTables.min.js"></script>
<script src="script.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.9/css/jquery.dataTables.min.css" />
<h1 class = "title">台灣交換學生資料庫</h1>
<h3 class = "title">民國101至103年台灣交換學生資料,使用者可以移動滑鼠與拖曳地球儀查看詳細資料,<br>也可以利用下方資料庫內進行進階搜尋。資料來源來自教育部。製作人<a href="https://twitter.com/Jeremy_CF_Lin" target="_blank">Jeremy C.F. Lin</a><br>與台灣<a href="http://comm.nccu.edu.tw/index.php" target="_blank">政治大學傳播學院</a>一同合作。</h3>
<div id="main-wrapper" class="">
<div id="main-content" class="container">
<div class="row">
<div id ='map' class="maps col-lg-2"></div>
<div id ='map2' class="maps col-lg-2"></div>
<div id ='map3' class="maps col-lg-2"></div>
</div>
<div class ="row">
<div class="table">
<table id="example" class="display " width="100%"></table>
</div>
</div>
</div>
</div>
<script>
$(".maps").css("height", $("#map").outerWidth() + "px");
var margin = {
top: 15,
right: 20,
bottom: 15,
left: 0
},
width = $(".maps").outerWidth() - margin.left - margin.right,
height = $(".maps").outerHeight() - margin.top - margin.bottom;
//This is the project for the globe
var projection = d3.geo.orthographic()
.scale(height / 2)
.translate([width / 2, height / 2])
.clipAngle(90)
.precision(0.5);
var path = d3.geo.path()
.projection(projection)
.pointRadius(function(d) {
//This is where we set circle radius to show count of attendees
if (d.count) {
return Math.sqrt(d.count / Math.PI) * 1.3;
}
});
var svg = d3.select("#map").append('svg')
// d3.select('#map').append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.attr('class', 'graph-svg-component')
.call(responsivefy) // Call function responsivefy to make the graphic reponsive according to the window width/height
.append('g')
.attr("class", "globe-g")
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var svg2 = d3.select("#map2").append('svg')
// d3.select('#map').append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.attr('class', 'graph-svg-component')
.call(responsivefy) // Call function responsivefy to make the graphic reponsive according to the window width/height
.append('g')
.attr("class", "globe-g")
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var svg3 = d3.select("#map3").append('svg')
// d3.select('#map').append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.attr('class', 'graph-svg-component')
.call(responsivefy) // Call function responsivefy to make the graphic reponsive according to the window width/height
.append('g')
.attr("class", "globe-g")
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var globe = svg.selectAll('path.globe').data([{
type: 'Sphere'
}])
.enter().append('path')
.attr('class', 'globe')
.attr('d', path);
var globe2 = svg2.selectAll('path.globe').data([{
type: 'Sphere'
}])
.enter().append('path')
.attr('class', 'globe')
.attr('d', path);
var globe3 = svg3.selectAll('path.globe').data([{
type: 'Sphere'
}])
.enter().append('path')
.attr('class', 'globe')
.attr('d', path);
queue()
.defer(d3.json, 'world_countries.json')// load geojson/topojson data
.defer(d3.csv, 'exchange_student.csv')
.await(ready);
function ready(error, world, data) {
if (error) throw error;
data.forEach(
function(d) {
d.end_lat = +d.end_lat;
d.end_long = +d.end_long;
d.start_lat = +d.start_lat;
d.start_long = +d.start_long;
d.greatcircle = new arc.GreatCircle({
x: d.start_long,
y: d.start_lat
}, {
x: d.end_long,
y: d.end_lat
});
d.line = d.greatcircle.Arc(100, {
offset: 10
});
d.arc = d.line.json();
}
);
data = data.filter(function(d) {
if (isNaN(d.end_lat) || isNaN(d.end_long)) {
//Do nothing.
} else {
return d;
}
});
svg.selectAll('baseMap')
.data(world.features)
.enter()
.append('path')
.attr('d', path)
// .append("g")
.attr('class', 'baseMap');
svg2.selectAll('baseMap')
.data(world.features)
.enter()
.append('path')
.attr('d', path)
// .append("g")
.attr('class', 'baseMap');
svg3.selectAll('baseMap')
.data(world.features)
.enter()
.append('path')
.attr('d', path)
// .append("g")
.attr('class', 'baseMap');
svg.append("text")
.attr("class","country")
.attr("x", width * 0.70)
.attr("y", height * 0.87)
.text("");
svg2.append("text")
.attr("class","country svg2")
.attr("x", width * 0.70)
.attr("y", height * 0.87)
.text("");
svg3.append("text")
.attr("class","country svg3")
.attr("x", width * 0.70)
.attr("y", height * 0.87)
.text("");
svg.append("text")
.attr("class","country count1")
.attr("x", width * 0.70)
.attr("y", height * 0.93)
.text("");
svg2.append("text")
.attr("class","country count2")
.attr("x", width * 0.70)
.attr("y", height * 0.93)
.text("");
svg3.append("text")
.attr("class","country count3")
.attr("x", width * 0.70)
.attr("y", height * 0.93)
.text("");
svg.selectAll('.cities_end')
.data(data.filter(function(d) { return d.year === "101" }))
.enter().append("path")
.datum(function(d) {
return {
type: "Point",
coordinates: [d.end_long, d.end_lat],
count: +d.count,
country: d.end_country
};
})
.attr("d", path)
.attr('class', 'cities_end')
.on('mouseover',function(d){
d3.select(".country")
.text(d.country)
d3.select(".count1")
.text(d.count + " 名學生")
});
svg2.selectAll('.cities_end')
.data(data.filter(function(d) { return d.year === "102" }))
.enter().append("path")
.datum(function(d) {
return {
type: "Point",
coordinates: [d.end_long, d.end_lat],
count: +d.count,
country: d.end_country
};
})
.attr("d", path)
.attr('class', 'cities_end')
.on('mouseover',function(d){
d3.select(".svg2")
.text(d.country)
d3.select(".count2")
.text(d.count+ " 名學生")
});
svg3.selectAll('.cities_end')
.data(data.filter(function(d) { return d.year === "103" }))
.enter().append("path")
.datum(function(d) {
return {
type: "Point",
coordinates: [d.end_long, d.end_lat],
count: +d.count,
country: d.end_country
};
})
.attr("d", path)
.attr('class', 'cities_end')
.on('mouseover',function(d){
d3.select(".svg3")
.text(d.country)
d3.select(".count3")
.text(d.count+ " 名學生")
});
// console.log(data)
svg.append("g")
.attr("class", "line")
.selectAll(".arc")
.data(data.filter(function(d) { return d.year === "101" })
.map(function(d) {
return d.arc;
}))
.enter()
.append("path")
.attr("class", "arc")
.attr("d", path);
svg.append("text")
.attr("class","years")
.attr("x", width * 0.70)
.attr("y", height * 0.80)
.text('101年');
svg2.append("text")
.attr("class","years")
.attr("x", width * 0.70)
.attr("y", height * 0.80)
.text('102年');
svg3.append("text")
.attr("class","years")
.attr("x", width * 0.70)
.attr("y", height * 0.80)
.text('103年 (上半年)');
svg2.append("g")
.attr("class", "line")
.selectAll(".arc")
.data(data.filter(function(d) { return d.year === "102" }).map(function(d) {
return d.arc;
}))
.enter()
.append("path")
.attr("class", "arc")
.attr("d", path);
// console.log(data);
svg3.append("g")
.attr("class", "line")
.selectAll(".arc")
.data(data.filter(function(d) { return d.year === "103" }).map(function(d) {
return d.arc;
}))
.enter()
.append("path")
.attr("class", "arc")
.attr("d", path);
}
d3.selectAll(".maps").call( //drag on the svg element
d3.behavior.drag()
.origin(function() {
var r = projection.rotate();
return {
x: r[0],
y: -r[1]
}; //starting point
})
.on("drag", function() {
var r = projection.rotate();
/* update retation angle */
projection.rotate([d3.event.x, -d3.event.y, r[2]]);
/* redraw the map and circles after rotation */
svg.selectAll(".baseMap").attr("d", path);
svg.selectAll(".arc").attr("d", path);
svg.selectAll('.cities_end')
.attr("d", path);
svg2.selectAll(".baseMap").attr("d", path);
svg2.selectAll(".arc").attr("d", path);
svg2.selectAll('.cities_end')
.attr("d", path);
svg3.selectAll(".baseMap").attr("d", path);
svg3.selectAll(".arc").attr("d", path);
svg3.selectAll('.cities_end')
.attr("d", path);
})
);
function responsivefy(svg) {
var container = d3.select(svg.node().parentNode),
width = parseInt(svg.style('width')),
height = parseInt(svg.style('height')),
aspect = width / height;
svg.attr('viewBox', '0 0 ' + width + ' ' + height)
.attr('perserveAspectRatio', 'xMinYMid')
.call(resize);
d3.select(window).on('resize', resize);
function resize() {
var targetWidth = parseInt(container.style('width'));
svg.attr('width', targetWidth);
svg.attr('height', Math.round(targetWidth / aspect));
}
}
</script>
</body>
</html>
var dataSet = [
["大陸地區",101,"上海交通大學",65,"http://www.sjtu.edu.cn/"],
["大陸地區",101,"北京大學",82,"http://www.pku.edu.cn/"],
["大陸地區",101,"廈門大學",40,"http://www.xmu.edu.cn/"],
["日本",101,"大阪大學",35,"http://www.osaka-u.ac.jp/"],
["日本",101,"立命館大學",32,"http://www.ritsumei.jp/index_j.html"],
["日本",101,"東北大學",30,"http://www.tohoku.ac.jp/en/"],
["美國",101,"加州大學柏克萊分校",63,"http://www.berkeley.edu/"],
["美國",101,"史丹福大學",56,"http://www.stanford.edu/"],
["美國",101,"西來大學",45,"http://www.uwest.edu/site/"],
["大韓民國(南韓)",101,"東亞大學",25,"http://www.donga.ac.kr/"],
["大韓民國(南韓)",101,"成均館大學",24,"http://www.skku.edu/index_pc.jsp"],
["大韓民國(南韓)",101,"又松大學",22,"http://www.wsu.ac.kr/site/main/intro/intro.html"],
["德意志聯邦共和國",101,"海德堡大學",51,"http://www.uni-heidelberg.de/"],
["德意志聯邦共和國",101,"漢堡大學",29,"http://www.uni-hamburg.de/"],
["德意志聯邦共和國",101,"柏林自由大學",19,"http://www.fu-berlin.de/"],
["法國",101,"里爾天主教大學",34,"http://www.univ-catholille.fr/"],
["法國",101,"里昂大三大學",23,"http://www.univ-lyon3.fr/"],
["法國",101,"特魯瓦高等商學院",11,"http://www.educations.com/study-abroad/groupe-esc-troyes-school-of-management/"],
["英國",101,"牛津大學哈福特學院",39,"http://www.ox.ac.uk/"],
["英國",101,"北安普頓大學",13,"http://www.northampton.ac.uk/"],
["英國",101,"愛丁堡大學",10,"http://www.ed.ac.uk/home"],
["荷蘭王國",101,"烏特列茲大學",25,"http://www.uu.nl/"],
["荷蘭王國",101,"葛洛寧恩大學",21,"http://www.rug.nl/"],
["荷蘭王國",101,"萊登大學",8,"http://www.leidenuniv.nl/"],
["捷克共和國",101,"布爾諾科技大學",18,"https://www.vutbr.cz/en/"],
["捷克共和國",101,"捷克科技大學",11,"http://www.cvut.cz/"],
["捷克共和國",101,"哈德克.卡爾威大學",8,"https://www.uhk.cz/en-GB/UHK"],
["加拿大",101,"漢堡學院",15,"http://www.humber.ca/"],
["加拿大",101,"布洛克大學",11,"http://www.brocku.ca/"],
["加拿大",101,"維多利亞大學",10,"http://www.uvic.ca/"],
["瑞典王國",101,"林雪平大學",20,"http://www.liu.se/?l=en"],
["瑞典王國",101,"皇家理工學院",12,"http://www.kth.se/"],
["瑞典王國",101,"查爾默大學",10,"http://www.chalmers.se/en/Pages/default.aspx"],
["澳大利亞",101,"迪肯大學",15,"http://www.deakin.edu.au/"],
["澳大利亞",101,"昆士蘭大學",10,"http://www.uq.edu.au/"],
["澳大利亞",101,"昆士蘭科技大學",8,"https://www.qut.edu.au/"],
["香港",101,"香港中文大學",26,"http://www.cuhk.edu.hk/chinese/"],
["香港",101,"香港城市大學",15,"http://www.cityu.edu.hk/cityu/index-tc.htm"],
["香港",101,"樹仁大學",12,"http://www.hksyu.edu/"],
["西班牙王國",101,"馬德里自治大學",9,"http://www.uam.es/ss/Satellite/es/home/"],
["西班牙王國",101,"納瓦拉大學",8,"http://www.unav.edu/web/biblioteca"],
["西班牙王國",101,"卡斯提亞拉曼查大學",7,"https://www.uclm.es/english/"],
["奧地利共和國",101,"林茲大學",20,"http://www.jku.at/content"],
["奧地利共和國",101,"茵斯堡大學",15,"http://www.uibk.ac.at/"],
["奧地利共和國",101,"維也納大學",8,"http://www.univie.ac.at/"],
["泰王國(泰國)",101,"湄州大學",7,"http://www.mju.ac.th/about/mju-about-2004/INDEX.html"],
["泰王國(泰國)",101,"曼谷大學",6,"http://www.bu.ac.th/tha/"],
["泰王國(泰國)",101,"清邁大學",6,"http://www.cmu.ac.th/"],
["新加坡共和國",101,"南洋理工大學",19,"http://www.ntu.edu.sg/Pages/home.aspx"],
["新加坡共和國",101,"新加坡國立大學",18,"http://www.nus.edu.sg/"],
["新加坡共和國",101,"新加坡管理大學",7,"http://www.smu.edu.sg/"],
["馬來西亞",101,"馬來亞大學",13,"https://www.um.edu.my/"],
["馬來西亞",101,"馬來西亞新紀元學院",7,"http://www.newera.edu.my/"],
["馬來西亞",101,"馬來西亞理工大學(UTM)",2,"http://www.utm.my/"],
["芬蘭共和國",101,"阿爾托大學",13,"http://www.aalto.fi/fi/"],
["芬蘭共和國",101,"拉瑞爾科技應用大學",4,"https://www.laurea.fi/"],
["芬蘭共和國",101,"坦佩利大學",3,"http://www.uta.fi/en/"],
["菲律賓共和國",101,"馬尼拉安特雷歐大學",14,"http://www.ateneo.edu/"],
["菲律賓共和國",101,"瑪布阿科學技術學院",10,"http://www.mapua.edu.ph/"],
["菲律賓共和國",101,"新英格蘭大學",10,"http://www.une.edu.au/"],
["大陸地區",102,"復旦大學",99,"http://www.fudan.edu.cn/index.html"],
["大陸地區",102,"同濟大學",93,"http://www.tongji.edu.cn/"],
["大陸地區",102,"南京大學",84,"http://www.nju.edu.cn/"],
["日本",102,"大阪大學",31,"http://www.osaka-u.ac.jp/"],
["日本",102,"早稻田大學",27,"http://www.waseda.jp/top/en"],
["日本",102,"同志社大學",23,"https://www.doshisha.ac.jp/"],
["日本",102,"東北大學",23,"http://www.tohoku.ac.jp/en/"],
["美國",102,"西來大學",35,"http://www.uwest.edu/site/"],
["美國",102,"天普大學",26,"http://www.temple.edu/"],
["美國",102,"波莫納加州州立理工大學",19,"http://www.cpp.edu/"],
["大韓民國(南韓)",102,"梨花女子大學",23,"http://www.ewha.ac.kr/mbs/ewhakr/index.jsp"],
["大韓民國(南韓)",102,"首爾教育大學",23,"http://www.snue.ac.kr/index_intro.jsp"],
["大韓民國(南韓)",102,"成均館大學",22,"http://www.skku.edu/index_pc.jsp"],
["德意志聯邦共和國",102,"杜賓根大學",21,"http://www.uni-tuebingen.de/"],
["德意志聯邦共和國",102,"慕尼黑工業大學",16,"http://www.tum.de/"],
["德意志聯邦共和國",102,"曼漢姆大學",11,"http://www.uni-mannheim.de/1/"],
["法國",102,"里昂第三大學",21,"http://www.univ-lyon3.fr/"],
["法國",102,"法國雷恩商學院",18,"https://www.esc-rennes.fr/"],
["法國",102,"巴黎高等政治學院",10,"http://www.sciencespo.fr/"],
["英國",102,"英國劍橋大學",25,"http://www.cam.ac.uk/"],
["英國",102,"曼徹斯特大學",12,"http://www.manchester.ac.uk/"],
["英國",102,"英國女皇大學",8,"http://www.qub.ac.uk/"],
["荷蘭王國",102,"荷蘭萊頓大學",21,"http://www.leidenuniv.nl/"],
["荷蘭王國",102,"葛洛寧恩大學",18,"http://www.rug.nl/"],
["荷蘭王國",102,"鹿特丹管理學院",7,"http://www.rsm.nl/home/"],
["泰國",102,"湄州大學",6,"http://www.mju.ac.th/about/mju-about-2004/INDEX.html"],
["泰國",102,"清邁皇家大學",4,"http://www.satitschool.cmru.ac.th/"],
["泰國",102,"曼谷大學",3,"http://www.bu.ac.th/tha/"],
["西班牙",102,"胡安卡洛斯國王大學",7,"http://www.urjc.es/"],
["西班牙",102,"瓦倫西亞科技大學",7,"http://www.upv.es/"],
["西班牙",102,"哈恩大學",6,"http://www10.ujaen.es/"],
["芬蘭",102,"阿爾托大學",18,"http://www.aalto.fi/fi/"],
["芬蘭",102,"拉瑞爾科技應用大學",6,"https://www.laurea.fi/"],
["芬蘭",102,"育華斯基里拉大學 ",4,"https://www.jyu.fi/en/"],
["香港",102,"香港中文大學",23,"http://www.cuhk.edu.hk/chinese/"],
["香港",102,"香港城市大學",17,"http://www.cityu.edu.hk/cityu/index-tc.htm"],
["香港",102,"香港大學",16,"https://www.hku.hk/c_index.html"],
["捷克共和國",102,"捷克科技大學",18,"http://www.cvut.cz/"],
["捷克共和國",102,"奧斯特拉瓦科技大學",11,"https://www.vsb.cz/en"],
["捷克共和國",102,"布爾諾科技大學",10,"https://www.vutbr.cz/en/"],
["比利時",102,"天主教魯汶大學",11,"http://www.uclouvain.be/index.html"],
["比利時",102,"布魯塞爾自由大學",8,"http://www.ulb.ac.be/"],
["比利時",102,"安特衛普大學",6,"https://www.uantwerpen.be/nl/"],
["加拿大",102,"漢堡學院",15,"http://www.humber.ca/"],
["加拿大",102,"紐芬蘭紀念大學",13,"http://www.mun.ca/"],
["加拿大",102,"不列顛哥倫比亞大學",12,"http://www.ubc.ca/"],
["馬來西亞",102,"馬來亞大學",26,"https://www.um.edu.my/"],
["馬來西亞",102,"雙威大學",12,"http://www.sunway.edu.my/"],
["馬來西亞",102,"新紀元學院",7,"http://www.newera.edu.my/"],
["奧地利",102,"林茲大學",20,"http://www.jku.at/content"],
["奧地利",102,"茵斯堡大學",17,"http://www.uibk.ac.at/"],
["奧地利",102,"約翰克卜勒大學",5,"http://www.jku.at/content"],
["新加坡共和國",102,"南洋理工大學",22,"http://www.ntu.edu.sg/Pages/home.aspx"],
["新加坡共和國",102,"新加坡國立大學",19,"http://www.nus.edu.sg/"],
["新加坡共和國",102,"新加坡管理大學",9,"http://www.smu.edu.sg/"],
["瑞典",102,"林雪平大學",22,"http://www.liu.se/?l=en"],
["瑞典",102,"查默斯理工大學",18,"http://www.chalmers.se/en/Pages/default.aspx"],
["瑞典",102,"哈勒姆斯塔德大學",7,"http://www.hh.se/"],
["澳大利亞",102,"昆士蘭科技大學",13,"https://www.qut.edu.au/"],
["澳大利亞",102,"新南威爾斯大學",13,"https://www.unsw.edu.au/"],
["澳大利亞",102,"格里菲斯大學",10,"https://www.griffith.edu.au/"],
["大陸地區",103,"復旦大學",67,"http://www.fudan.edu.cn/index.html"],
["大陸地區",103,"南京大學",56,"http://www.nju.edu.cn/"],
["大陸地區",103,"北京大學",47,"http://www.pku.edu.cn/"],
["日本",103,"東北大學",22,"http://www.tohoku.ac.jp/en/"],
["日本",103,"大阪大學",21,"http://www.osaka-u.ac.jp/ja"],
["日本",103,"北海道大學",17,"http://www.hokudai.ac.jp/"],
["美國",103,"西來大學",18,"http://www.uwest.edu/site/"],
["美國",103,"印第安纳大學-普渡大學維恩堡分校",14,"https://www.ipfw.edu/"],
["美國",103,"天普大學",13,"http://www.temple.edu/"],
["南韓",103,"梨花女子大學",19,"http://www.ewha.ac.kr/mbs/ewhakr/index.jsp"],
["南韓",103,"中央大學",13,"http://www.cau.ac.kr/index.php"],
["南韓",103,"東亞大學",12,"http://www.donga.ac.kr/"],
["德國",103,"曼漢姆大學",16,"http://www.uni-mannheim.de/1/"],
["德國",103,"杜賓根大學",12,"http://www.uni-tuebingen.de/"],
["德國",103,"福茲堡應用科技大學",7,"http://www.fhws.de/"],
["法國",103,"里昂第三大學",15,"http://www.univ-lyon3.fr/"],
["法國",103,"里爾天主教大學",12,"http://www.univ-catholille.fr/"],
["法國",103,"特魯瓦高等商學院",9,"http://www.utt.fr/fr/index.html"],
["加拿大",103,"曼尼托巴大學",15,"http://umanitoba.ca/"],
["加拿大",103,"漢堡學院",10,"http://www.humber.ca/"],
["加拿大",103,"西門菲沙大學",6,"http://www.sfu.ca/"],
["荷蘭",103,"葛洛寧恩大學",10,"http://www.rug.nl/gradschooleb/index"],
["荷蘭",103,"萊登大學",9,"http://www.leidenuniv.nl/"],
["荷蘭",103,"漢斯應用科技大學",5,"https://www.hanze.nl/eng/"],
["英國",103,"蘭卡斯特大學",5,"http://www.lancaster.ac.uk/"],
["英國",103,"倫敦政經學院",4,"http://www.lse.ac.uk/home.aspx"],
["英國",103,"桑德蘭大學",4,"http://www.sunderland.ac.uk/"],
["西班牙",103,"瓦倫西亞科技大學",6,"http://www.upv.es/"],
["西班牙",103,"薩拉曼卡大學",6,"http://www.usal.es/webusal/"],
["西班牙",103,"哈恩大學",5,"http://www10.ujaen.es/"],
["香港",103,"香港城市大學",14,"http://www.cityu.edu.hk/cityu/index-tc.htm"],
["香港",103,"香港中文大學",12,"http://www.cuhk.edu.hk/chinese/"],
["香港",103,"香港大學",9,"https://www.hku.hk/c_index.html"],
["奧地利共和國",103,"林茲大學",11,"http://www.jku.at/content"],
["奧地利共和國",103,"茵斯堡大學",7,"http://www.uibk.ac.at/"],
["奧地利共和國",103,"維也納大學",6,"http://www.univie.ac.at/"],
["瑞典",103,"林雪平大學",11,"http://www.liu.se/?l=en"],
["瑞典",103,"哈勒姆斯塔德",7,"http://www.hh.se/"],
["瑞典",103,"查默斯理工大學",6,"http://www.chalmers.se/en/Pages/default.aspx"],
["澳大利亞",103,"昆士蘭科技大學",10,"https://www.qut.edu.au/"],
["澳大利亞",103,"南天大學",4,"http://www.nantien.edu.au/"],
["澳大利亞",103,"昆士蘭大學",3,"http://www.uq.edu.au/"],
["新加坡共和國",103,"新加坡國立大學",11,"http://www.nus.edu.sg/"],
["新加坡共和國",103,"南洋理工大學",9,"http://www.ntu.edu.sg/Pages/home.aspx"],
["新加坡共和國",103,"新加坡管理大學",7,"http://www.smu.edu.sg/"],
["波蘭",103,"華沙經濟大學",5,"http://www.sgh.waw.pl/index_en.html"],
["波蘭",103,"華沙大學",4,"http://www.uw.edu.pl/"],
["波蘭",103,"亞捷隆大學",4,"http://www.uj.edu.pl/"],
["芬蘭",103,"阿爾托大學",6,"http://www.aalto.fi/fi/"],
["芬蘭",103,"JAMK應用科技大學",3,"www.jamk.fi/fi/Etusivu"],
["芬蘭",103,"于韋斯屈萊大學",3,"https://www.jyu.fi/"],
["瑞士",103,"蘇黎世應用科學大學",8,"http://www.sml.zhaw.ch/en"],
["瑞士",103,"聖加崙大學",4,"http://www.unisg.ch/"],
["瑞士",103,"蘇黎世大學",3,"http://www.uzh.ch/index.html"],
["瑞士",103,"洛桑大學",3,"http://www.unil.ch/index.html"],
["馬來西亞",103,"馬來亞大學",21,"https://www.um.edu.my/"],
["馬來西亞",103,"拉曼大學",1,"http://www.tarc.edu.my/"]
];
$(document).ready(function() {
$('#example').DataTable( {
data: dataSet,
"columnDefs": [
{ "visible": false }
],
"scrollY": "600px",
"scrollCollapse": true,
"paging": false,
"order": [[ 2, 'asc' ]],
columns: [
{ title: "國家" },
{ title: "年度" },
{ title: "學校" },
{ title: "人數" },
{ title: "網址" }
]
} );
} );
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment