Skip to content

Instantly share code, notes, and snippets.

@bakks
Last active December 17, 2015 14:59
Show Gist options
  • Save bakks/5628626 to your computer and use it in GitHub Desktop.
Save bakks/5628626 to your computer and use it in GitHub Desktop.
Chart generated at Commonwealth.io
{
query : {
db : 'bakks',
coll : 'submarine_cables',
param : {query : {}, fields: {name:1, path:1, length:1}}
},
css : {
height : 460,
width : 780
},
earth : {
width : 780,
height : 460,
velocity : .0003,
then : Date.now(),
parallel : 17,
scale : 180,
precision : 0.1,
translate_lon : -180,
translate_lat : -90,
topojson_scale : 0.0001
},
init : function(chart) {
this.custom = {
'type': 'Topology',
'transform': {
'scale': [this.opt.earth.topojson_scale, this.opt.earth.topojson_scale],
'translate': [this.opt.earth.translate_lon, this.opt.earth.translate_lat]
},
'objects': {
},
'arcs': [
]
}
this.added = []
this.earth = {}
this.earth.rotate_start = Math.random() * 360 - 180
this.earth.projection = d3.geo.armadillo()
.scale(this.opt.earth.scale)
.translate([this.opt.earth.width / 2, this.opt.earth.height * .7])
.parallel(this.opt.earth.parallel)
.rotate([this.earth.rotate_start, 0])
.precision(this.opt.earth.precision);
this.earth.path = d3.geo.path()
.projection(this.earth.projection)
var graticule = d3.geo.graticule().step([9, 14]);
var land = topojson.object(world, world.objects.land)
this.earth.infobox = chart.selectChildren('#splash_earth_infobox').data([1])
this.earth.infobox.enter().append('div')
.attr('id', 'splash_earth_infobox')
.style('position', 'absolute')
.style('right', '0px')
.style('bottom', '0px')
.style('margin-right', '4px')
.style('text-align', 'right')
this.earth.svg = chart.selectChildren('svg').data([1])
this.earth.svg.enter().append('svg')
.attr('width', this.opt.earth.width)
.attr('height', this.opt.earth.height);
var defs = this.earth.svg.selectChildren('defs').data([1])
defs.enter().append('defs');
this.earth.def_sphere = defs.selectChildren('#sphere').data([1])
this.earth.def_sphere.enter().append('path')
.datum({type: 'Sphere'})
.attr('id', 'sphere')
.attr('d', this.earth.path)
defs.append('clipPath')
.attr('id', 'clip')
.append('use')
.attr('xlink:href', '#sphere');
this.earth.svg.append('use')
.attr('class', 'splash_earth_stroke')
.attr('xlink:href', '#sphere');
this.earth.svg.append('use')
.attr('class', 'splash_earth_fill')
.attr('xlink:href', '#sphere');
this.earth.path_graticule = this.earth.svg.selectChildren('#graticule').data([1])
this.earth.path_graticule.enter().append('path')
.datum(graticule)
.attr('class', 'splash_earth_graticule')
.attr('clip-path', 'url(#clip)')
this.earth.path_land = this.earth.svg.selectChildren('#land').data([1])
this.earth.path_land.enter().insert('path', '.splash_earth_graticule')
.datum(topojson.object(world, world.objects.land))
.attr('id', 'land')
.attr('class', 'splash_earth_land')
.attr('clip-path', 'url(#clip)')
this.earth.path_countries = this.earth.svg.selectChildren('#countries').data([1])
this.earth.path_countries.enter().insert('path', '.splash_earth_graticule')
.datum(topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; }))
.attr('id', 'countries')
.attr('class', 'splash_earth_boundary')
.attr('clip-path', 'url(#clip)')
this.earth.path_cables = []
},
add_cable : function(tj, cable) {
var transform_lonlat = function(lon, lat) {
return [
(lon - this.earth.translate_lon) / this.earth.topojson_scale,
(lat - this.earth.translate_lat) / this.earth.topojson_scale
]
}.bind(this)
var paths = cable.path
if (paths == undefined) {
console.warn("bad doc " + JSON.stringify(cable))
return
}
var arcs = []
for (var i = 0; i < paths.length; i++) {
var path = paths[i];
var last = transform_lonlat(path[0][0], path[0][1])
var arc = [last]
for (var j = 1; j < path.length; j++) {
var next = transform_lonlat(path[j][0], path[j][1])
arc.push([next[0] - last[0], next[1] - last[1]])
last = next
}
arcs.push([tj.arcs.length])
tj.arcs.push(arc)
}
var id = 'cable_' + cable._id
var obj = {
type: 'MultiLineString',
arcs: arcs,
id: cable._id
}
tj.objects[id] = obj
return id
},
draw : function(chart, model, data) {
if (this.added === undefined)
this.added = []
if (this.added.indexOf(model) == -1) {
this.added.push(model)
for (var i = 0; i < data.length; i++) {
var id = this.opt.add_cable(this.custom, data[i])
var p = this.earth.svg.insert('path', '.splash_earth_graticule')
.datum(topojson.object(this.custom, this.custom.objects[id]))
.attr('class', 'splash_earth_cable2')
.attr('clip-path', 'url(#clip)')
var c = function(data, i) {
return function() {
$('#splash_earth_infobox').html(data[i].length + '<br/><div style="background:#fff; border-radius:4px; padding-left: 3px">' + data[i].name + '</div>')
}
}(data, i)
$(p[0]).mouseover(c)
this.earth.path_cables.push(p)
}
}
var p = this.opt.earth.parallel
var r = (Date.now() - this.opt.earth.then) * this.opt.earth.velocity + this.earth.rotate_start
if (p >= -2 && p <= 2)
return
this.earth.projection.parallel(p)
this.earth.projection.rotate([r, 0])
this.earth.path_graticule.attr('d', this.earth.path)
this.earth.path_land.attr('d', this.earth.path)
this.earth.path_countries.attr('d', this.earth.path)
for (var i = 0; i < this.earth.path_cables.length; i++)
this.earth.path_cables[i].attr('d', this.earth.path)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment