{"id":13481455,"url":"https://github.com/earthjs/earthjs","last_synced_at":"2025-03-27T12:31:01.068Z","repository":{"id":54246549,"uuid":"88688418","full_name":"earthjs/earthjs","owner":"earthjs","description":"D3 Earth JS","archived":false,"fork":false,"pushed_at":"2023-01-12T08:22:27.000Z","size":44602,"stargazers_count":166,"open_issues_count":13,"forks_count":32,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-03-20T13:34:37.925Z","etag":null,"topics":["3d","canvas","d3","globe","orthographic","svg","threejs","visualization","webgl"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/earthjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-19T01:53:05.000Z","updated_at":"2024-10-31T13:46:47.000Z","dependencies_parsed_at":"2023-02-09T10:46:28.118Z","dependency_job_id":null,"html_url":"https://github.com/earthjs/earthjs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/earthjs%2Fearthjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/earthjs%2Fearthjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/earthjs%2Fearthjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/earthjs%2Fearthjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/earthjs","download_url":"https://codeload.github.com/earthjs/earthjs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245844840,"owners_count":20681789,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["3d","canvas","d3","globe","orthographic","svg","threejs","visualization","webgl"],"created_at":"2024-07-31T17:00:51.977Z","updated_at":"2025-03-27T12:30:57.904Z","avatar_url":"https://github.com/earthjs.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","3d","Maps"],"sub_categories":[],"readme":"# Earthjs\n\n#### Live Example\n* [3D Flight Line](https://earthjs.github.io/16-threejs-demo/3-small_arms_3_.html)\n\n![alt #D Flight Line](https://raw.githubusercontent.com/earthjs/earthjs.github.io/master/images/3d-globe.gif)\n\nEarthjs is a javascript library for easy building orthographic globe. Originally inspired by [planetary.js](https://github.com/BinaryMuse/planetary.js) (canvas) and [Faux-3d Shaded Globe](http://bl.ocks.org/dwtkns/4686432) (svg) and both were created using D3-v3.\n\nEarthjs is created using D3-v4, design as pluggable modules.\n\nAwesome interactive globe can be created, drag to rotate, scroll mouse zooming. Multi layer of globe, combination between SVG, Canvas and Threejs. Multiple globe as a twin globe with same or different layer. Solid or transparent globe in SVG, Canvas or Threejs, hide/show some features balancing between smooth rendering and cpu utilization. point/mark of location, bar chart on globe \u0026 tooltips.\n\nSVG for quickly prototyping the globe as it used standard SVG DOM element so event \u0026 css can be applied to each element. the downside will come when the need to create so much SVG element, the responsiveness or jaggering drag will show.\n\nCanvas for more data point that need to be render and UX experience stay in good shape. Interactivity or mouse detection are available for hovering, click \u0026 double click. detect country or point of location.\n\nWebGL/Threejs is a way to go if eye catchy of globe is needed and lots of data, or want to be better CPU utilization by moving some intensive calculation to GPU.\n\nInteresting Data Visualization can be created by combining SVG, Canvas \u0026 Threejs(WebGL) like: choropleth globe using Canvas or Threejs, heatmap globe by rendering heatmap on canvas and use that canvas as a texture in Threejs, flightLine to connect two datapoint using Threejs and coloring target location (usually country) using Canvas. flashy bullet that travel along the way of flightLine is there including the mouse event using Threejs.\n\n## Internal Plugins (more than 60)\nSelected plugins bundled into library:\n\n* baseCsv,\n* baseGeoJson,\n* worldJson,\n* world3dJson,\n* choroplethCsv,\n* countryNamesCsv,\n* colorScale,\n* dotRegion,\n* hoverCanvas,\n* clickCanvas,\n* mousePlugin,\n* canvasPlugin,\n* inertiaPlugin,\n* countryCanvas,\n* threejsPlugin,\n* dblClickCanvas,\n* autorotatePlugin,\n* oceanSvg,\n* sphereSvg,\n* zoomPlugin,\n* fauxGlobeSvg,\n* graticuleSvg,\n* dropShadowSvg,\n* dotTooltipSvg,\n* dotSelectCanvas,\n* graticuleCanvas,\n* dotTooltipCanvas,\n* countrySelectCanvas,\n* countryTooltipCanvas,\n* countryTooltipSvg,\n* barTooltipSvg,\n* worldCanvas,\n* centerSvg,\n* placesSvg,\n* worldSvg,\n* barSvg,\n* mapSvg,\n* haloSvg,\n* dotsSvg,\n* pingsSvg,\n* pinCanvas,\n* dotsCanvas,\n* pingsCanvas,\n* centerCanvas,\n* flattenSvg,\n* barThreejs,\n* hmapThreejs,\n* dotsThreejs,\n* dotsCThreejs,\n* iconsThreejs,\n* canvasThreejs,\n* pointsThreejs,\n* textureThreejs,\n* graticuleThreejs,\n* flightLineThreejs,\n* oceanThreejs,\n* imageThreejs,\n* inertiaThreejs,\n* worldThreejs,\n* globeThreejs,\n* sphereThreejs,\n* world3dThreejs,\n* world3dThreejs2,\n* commonPlugins,\n* selectCountryMix,\n* selectCountryMix2,\n\n## Requirements\n* [D3 version 4](http://d3js.org/)\n* [topojson version 3](https://github.com/topojson/topojson)\n\n##### Optional\n* [threejs revision 8x](https://threejs.org/) for Threejs type of globe\n\n## Quick Start\nThis sample need to run on the webserver, you can use [nodejs web-server](https://www.npmjs.com/package/http-server) or [python simple http server](http://2ality.com/2014/06/simple-http-server.html).\n```html\n\u003chtml\u003e\n\u003chead\u003e\n  \u003cscript type='text/javascript' src='http://d3js.org/d3.v4.min.js'\u003e\u003c/script\u003e\n  \u003cscript type='text/javascript' src='http://d3js.org/topojson.v3.min.js'\u003e\u003c/script\u003e\n  \u003cscript type='text/javascript' src='../dist/earthjs.js'\u003e\u003c/script\u003e\n  \u003cstyle media=\"screen\"\u003e\n  .countries path {\n      fill: rgb(117, 87, 57);\n      stroke: rgb(80, 64, 39);\n      stroke-linejoin: round;\n      stroke-width: 1.5;\n      opacity: 1;\n  }\n  .graticule path {\n      fill: none;\n      opacity: 0.2;\n      stroke: black;\n      stroke-width: 0.5;\n  }\n\u003c/style\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003csvg id=\"earth\"\u003e\u003c/svg\u003e\n  \u003cscript\u003e\n    const g = earthjs()\n    .register(earthjs.plugins.graticuleSvg())\n    .register(earthjs.plugins.autorotatePlugin(10))\n    .register(earthjs.plugins.worldSvg('./d/world-110m.json'));\n    g.ready(function(){\n        g.create();\n    })\n  \u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n## Writing Plugins\nPlugins is a function created in \"earthjs.plugins\" namespace, return with javascript object. Some of the keys have a special meaning, \"name\" property will be define **plugin namespace** in \"earthjs\", \"urls\" property is an ajax url and six(6) functions start with \"on\" are event handler. Other functions that define in the plugin will be live on the **plugin namespace**. Function defined in the plugin will become **proxy function** in which they have a **context of earthjs instance**.\n```javascript\nexport default (url) =\u003e {\n    //.... private code\n    return {\n        name: 'samplePlugin',\n        urls: [url],     // ajax url\n        onReady   () {}, // ajax handler\n        onInit    () {},\n        onCreate  () {},\n        onResize  () {},\n        onRefresh () {},\n        onInterval() {}\n    }\n}\n```\n**If necessary** when the plugin is in use, _onReady()_ can be superseded by _ready()_ function, created in the plugin namespace.\n\n```javascript\n// example:\ng.register(earthjs.plugins.worldSvg('./d/world-110m.json'));\ng.worldSvg.ready = function(err, json) {\n    //+++collpased code\n    g.worldSvg.data(json);\n}\n```\n**Plugin example**\n```javascript\nearthjs.plugins.graticuleSimple = () =\u003e {\n    const grat = d3.geoGraticule(), $ = {};\n\n    function create() {\n        this._.svg.selectAll('.graticule').remove();\n        $.grat = this._.svg.append(\"path\").datum(grat).attr(\"class\", \"graticule\");\n        refresh.call(this);\n    }\n\n    function refresh() {\n        $.grat.attr(\"d\", this._.path);\n    }\n\n    return {\n        name: 'graticuleSimple',\n        onCreate()  {create .call(this);},\n        onRefresh() {refresh.call(this);}\n    }\n}\n\n//... plugin in use\nconst g = earthjs()\n.register(earthjs.plugins.graticuleSimple())\n.create();\n```\n**Convention**\n\nFor SVG create function:\n* removing element should be removing same element that created from same plugin.\n* attributes often get updated (ex:\"d\"), it should be placed in refresh function.\n* at the end of create function, it should call refresh function.\n\nin general, return value should be a simple object whereby body of functions are kept in the private place with same name, and use **.call(this,...)** to execute the private function.\n\nFor Canvas, it always recreate the whole canvas, mean that onCreate \u0026 onRefresh should be using same (logic of drawing) function.\n\nFor Threejs, the concept of refresh is different compare with SVG or Canvas, when globe rotate the internal state of projection is changed, to reflect the changes in UI, SVG or Canvas need to refresh or redraw the path, as for Threejs the D3 projection state change need to be transfer to Threejs main container object, so less need to create onRefresh function.   \n\n## Building\nBuilding earthjs requires [Node.js](https://nodejs.org/en/). Once you've installed the project's dependencies with npm install, you can build earthjs to the dist directory with npm run build.\n\n## License\nearthjs.js is licensed under the **MIT license**. See the LICENSE file for more information.\n\n```\nMIT License\n\nCopyright (c) 2017 Widi Harsojo\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fearthjs%2Fearthjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fearthjs%2Fearthjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fearthjs%2Fearthjs/lists"}