UNPKG

earthjs

Version:

D3 Earth JS using SVG, Canvas & THREE js, build with some plugins.

259 lines (253 loc) 9.85 kB
<!DOCTYPE html> <html> <head> <link type="text/css" rel="stylesheet" href="../css/earthjs.css"> <script type='text/javascript' src="../js/d3.min.js"></script> <script type='text/javascript' src='../js/three.min.js'></script> <script type='text/javascript' src='../js/THREE.MeshLine.js'></script> <script type='text/javascript' src="../js/topojson.min.js"></script> <script type='text/javascript' src='../js/earthjs.js'></script> <style> body { background: #393c54; /*background-image: url("../images/tiles.png");*/ } #three-js { pointer-events: all; } .top-ten { background-color: rgba(183, 183, 183,0.2); position: absolute; padding: 20px; right: 0; height: 100vh; z-index: 4; } .top-ten select { text-align: right; width: 220px; } .top-ten>* { z-index: 99; } h1,h2 { padding: 0; color: #ff0; } </style> </head> <body> <div class="input-area"> <input id="year" type="range" min="1992" max="2014" step="1" value="2014"/><br> <input id="frm" type="range" min="0.06" max="1" step="0.01" value="1"/> </div> <div class="top-ten"> <h1 id="title"></h1> <h2>Export:</h2> <select class="top-export" name="topExport" multiple></select><br> <h2>Import:</h2> <select class="top-import" name="topImport" multiple></select><br> </div> <svg id="earth-js" class="ej-center"></svg> <canvas id="three-js" class="ej-center"></canvas> <canvas class="ej-canvas ej-center"></canvas> <script type='text/javascript'> function smallArmsJson( json1='../d/country_iso3166.json', json2='../d/country_lat_lon.json', json3='../data/small-arms.json', json4='../d/country_nm_to_id.json', json5='../d/world-110m-country-names.json') { /*eslint no-console: 0 */ const _ = { countryIso: null, countryLLg: null, dataYearly: null, countryNmToId: null }; window._ = _; return { name: 'smallArmsJson', urls: [json1,json2,json3, json4, json5], onReady(err, countryIso, countryLLg, dataYearly, countryNmToId, countryName) { _.me.allData({countryIso, countryLLg, dataYearly, countryNmToId, countryName}); }, onInit(me) { _.me = me; }, allData(all) { if (all) { _.countryIso = all.countryIso; _.countryLLg = all.countryLLg; _.dataYearly = all.dataYearly; _.countryNmToId= all.countryNmToId; _.countryName = all.countryName; _.t = all.dataYearly.map(x=> x.t).sort()[0]; //.pop(); } else { const {countryIso, countryLLg, dataYearly, countryNmToId, countryName} = _; return {countryIso, countryLLg, dataYearly, countryNmToId, countryName}; } }, getData(cc,type='all',t=_.t) { _.total = [0,0]; _.sum_i = {}; _.sum_e = {}; _.all_i = []; _.all_e = []; if (cc) { _.cc = cc; _.cx = _.countryName.find(x=> x.cid===cc); } const ar = []; const ll = _.countryLLg.countries; const f1 = _.dataYearly.filter(x=> x.t===t)[0]; f1.data.forEach(x=> { const te = (x.e===_.cc); const ti = (x.i===_.cc); if (te || ti) { const key = x.e+x.i; if (te) { if (_.sum_e[key]===undefined) { _.sum_e[key] = x;_.sum_e[key].v = 0; } _.sum_e[key].v = _.sum_e[key].v + x.v; _.total[0] = _.total[0] + x.v; //ttl export _.all_e.push(x); } else { if (_.sum_i[key]===undefined) { _.sum_i[key] = x;_.sum_i[key].v = 0; } _.sum_i[key].v = _.sum_i[key].v + x.v; _.total[1] = _.total[1] + x.v; //ttl import _.all_i.push(x); } } }); _.sum_e2 = Object.keys(_.sum_e).map(key=> _.sum_e[key]).filter(x=> x.v>0); _.sum_i2 = Object.keys(_.sum_i).map(key=> _.sum_i[key]).filter(x=> x.v>0); _.sum_e2.sort((a,b)=> b.v-a.v).forEach(x=> { const s = ll[x.e]; const t = ll[x.i]; if (s && t) ar.push([s.lat, s.lon, t.lat, t.lon, x.v]); }); _.sum_i2.sort((a,b)=> b.v-a.v).forEach(x=> { const s = ll[x.e]; const t = ll[x.i]; if (s && t) ar.push([s.lat, s.lon, t.lat, t.lon, x.v]); }); _.cids = _.sum_e2.map(x=> x.i).concat( _.sum_i2.map(x=> x.e)).filter(x=> x!==_.cc && x); _.cids = [...new Set(_.cids)]; return ar; }, getCountryId(cname) { return _.countryNmToId[cname.toUpperCase()]; }, ids() { const cl=this.countryTooltipCanvas.data(); return _.cids.map(x=> { const lx = cl.find(t=> t.cid===x); return lx && lx.id; }) }, topTen() { fm = d3.format("($.2s"); cc = g.smallArmsJson.allData().countryIso; d3.select('#title').html(_.cx.name); const tpExport = d3.select('.top-export'); tpExport.attr('size', _.sum_e2.length>25 ? 25 : _.sum_e2.length); tpExport.html(_.sum_e2.map(x=> { return `<option value="${x.i}">${cc[x.i]} - ${fm(x.v)}</option>` }).join('')) const tpImport = d3.select('.top-import'); tpImport.attr('size', _.sum_i2.length>25 ? 25 : _.sum_i2.length); tpImport.html(_.sum_i2.map(x=> { return `<option value="${x.e}">${cc[x.e]} - ${fm(x.v)}</option>` }).join('')) } } } d3.select('.top-export').on('click',()=> { const cc = d3.event.target.value; reload(cc); g.flightLineThreejs.reload(); }) d3.select('.top-import').on('click',()=> { const cc = d3.event.target.value; reload(cc); g.flightLineThreejs.reload(); }) const {offsetWidth, offsetHeight} = d3.select('body').node(); const g = earthjs({width: offsetWidth, height: offsetHeight, padding:5}) .register(smallArmsJson()) .register(earthjs.plugins.dropShadowSvg()) .register(earthjs.plugins.selectCountryMix2()) .register(earthjs.plugins.oceanThreejs()) .register(earthjs.plugins.world3dThreejs('../d/world.geometry.json','../globe/gold.jpg',0.975)) .register(earthjs.plugins.flightLineThreejs(null,'../globe/point3.png')) .register(earthjs.plugins.countryTooltipCanvas()); g.inertiaPlugin.selectAll('#three-js'); function reload(cc) { const csv = g.smallArmsJson.getData(cc); const arr = g.smallArmsJson.ids(); const data= g.worldJson.data(); const countries = topojson.feature(data, data.objects.countries).features; g.canvasThreejs.countries(countries.filter(x=>arr.indexOf(x.id)>-1)); g.flightLineThreejs.data(csv, ['#aaffff','#88ff11'], [80,150],100,1); g.smallArmsJson.topTen(); const cl = g.countryTooltipCanvas.data(); const xd = cl.find(t=> t.cid===cc); if (xd) { g.canvasThreejs.selectedCountries(countries.filter(x=> x.id===xd.id)); } g.canvasThreejs.reload(); } g.worldJson.ready = function(err, json) { g.canvasThreejs.data(json); g.worldJson.data(json); } let s,o,w,scale; g.ready(function(){ g.countryTooltipCanvas.data(g.smallArmsJson.allData().countryName); delete g._.options.showBorder; reload('SG'); g.create(); s = g._.proj.scale()-4; w = g.world3dThreejs.sphere(); o = g.oceanThreejs.sphere(); o.scale.set(0.95,0.95,0.95); o.material.transparent = true; w.scale.set(s,s,s); scale = d3.scaleLinear().domain([0.03,1]).range([3,s]); }) g.clickCanvas.onCountry({ chgCountry(event, country) { if (!country) return; const countries = g.countryTooltipCanvas.data(); const obj = countries.filter(x=> x.id===country.id)[0]; if (obj) { const cc = g.smallArmsJson.getCountryId(obj.name); if (cc) { reload(cc); g.flightLineThreejs.reload(); } } console.log(obj, name); } }) var canvas = d3.selectAll('canvas').nodes(); d3.select('#year').on('input', function() { _.t = +this.value;reload(); g.flightLineThreejs.reload(); }); d3.select('#frm').on('input', function() { const v = +this.value; let ww = scale(v); let oo = v - 0.05; console.log(ww,oo); w.scale.set(ww,ww,ww); o.scale.set(oo,oo,oo); }) </script> </body> </html>