Lines on Maps in JavaScript

How to draw D3.js-based lines, great circles, and contours on maps in JavaScript. Lines on maps can show distance between geographic points or be contour lines (isolines, isopleths, or isarithms).


Plotly Studio: Transform any dataset into an interactive data application in minutes with AI. Try Plotly Studio now.

d3.csv('https://raw.githubusercontent.com/plotly/datasets/master/globe_contours.csv', function(err, rows){

    function unpack(rows, key) {
        return rows.map(function(row) { return row[key]; });
    }

    var data = [];
    var scl =['rgb(213,62,79)','rgb(244,109,67)','rgb(253,174,97)','rgb(254,224,139)','rgb(255,255,191)','rgb(230,245,152)','rgb(171,221,164)','rgb(102,194,165)','rgb(50,136,189)'];
    var allLats = [];
    var allLons = [];

    for ( var i = 0 ; i < scl.length; i++){
        var latHead = 'lat-'+i;
        var lonHead = 'lon-'+i;
        var lat = unpack(rows, latHead);
        var lon = unpack(rows, lonHead);
        allLats.push(lat);
        allLons.push(lon);
    }

    for ( var i = 0 ; i < scl.length; i++) {
        var current = {
            type:'scattergeo',
            lon: allLons[i],
            lat: allLats[i],
            mode: 'lines',
            line: {
                width: 2,
                color: scl[i]
            }
        }
        data.push(current);
    };


    var layout = {
        geo: {
            projection: {
                type: 'orthographic',
                rotation: {
                    lon: -100,
                    lat: 40
                },
            },
            showocean: true,
            oceancolor: 'rgb(0, 255, 255)',
            showland: true,
            landcolor: 'rgb(230, 145, 56)',
            showlakes: true,
            lakecolor: 'rgb(0, 255, 255)',
            showcountries: true,
            lonaxis: {
                showgrid: true,
                gridcolor: 'rgb(102, 102, 102)'
            },
            lataxis: {
                showgrid: true,
                gridcolor: 'rgb(102, 102, 102)'
            }
        }
    };

    Plotly.newPlot("myDiv", data, layout, {showLink: false});
});
</script>\n\t<script src="/?originalUrl=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fd3%2F3.5.17%2Fd3.min.js"></script>\n</head>\n\n<body>\n\t<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>\n</body>","js":"d3.csv('https://raw.githubusercontent.com/plotly/datasets/master/globe_contours.csv', function(err, rows){\n\n function unpack(rows, key) {\n return rows.map(function(row) { return row[key]; });\n }\n\n var data = [];\n var scl =['rgb(213,62,79)','rgb(244,109,67)','rgb(253,174,97)','rgb(254,224,139)','rgb(255,255,191)','rgb(230,245,152)','rgb(171,221,164)','rgb(102,194,165)','rgb(50,136,189)'];\n var allLats = [];\n var allLons = [];\n\n for ( var i = 0 ; i < scl.length; i++){\n var latHead = 'lat-'+i;\n var lonHead = 'lon-'+i;\n var lat = unpack(rows, latHead);\n var lon = unpack(rows, lonHead);\n allLats.push(lat);\n allLons.push(lon);\n }\n\n for ( var i = 0 ; i < scl.length; i++) {\n var current = {\n type:'scattergeo',\n lon: allLons[i],\n lat: allLats[i],\n mode: 'lines',\n line: {\n width: 2,\n color: scl[i]\n }\n }\n data.push(current);\n };\n\n\n var layout = {\n geo: {\n projection: {\n type: 'orthographic',\n rotation: {\n lon: -100,\n lat: 40\n },\n },\n showocean: true,\n oceancolor: 'rgb(0, 255, 255)',\n showland: true,\n landcolor: 'rgb(230, 145, 56)',\n showlakes: true,\n lakecolor: 'rgb(0, 255, 255)',\n showcountries: true,\n lonaxis: {\n showgrid: true,\n gridcolor: 'rgb(102, 102, 102)'\n },\n lataxis: {\n showgrid: true,\n gridcolor: 'rgb(102, 102, 102)'\n }\n }\n };\n\n Plotly.newPlot(\"myDiv\", data, layout, {showLink: false});\n});\n"}">
var data = [{
    type: 'scattergeo',
    lat: [ 40.7127, 51.5072 ],
    lon: [ -74.0059, 0.1275 ],
    mode: 'lines',
    line:{
        width: 2,
        color: 'blue'
    }
  }];

var layout = {
  title: {text: 'London to NYC Great Circle'},
  showlegend: false,
  geo: {
      resolution: 50,
      showland: true,
      showlakes: true,
      landcolor: 'rgb(204, 204, 204)',
      countrycolor: 'rgb(204, 204, 204)',
      lakecolor: 'rgb(255, 255, 255)',
      projection: {
        type: 'equirectangular'
      },
      coastlinewidth: 2,
      lataxis: {
        range: [ 20, 60 ],
        showgrid: true,
        tickmode: 'linear',
        dtick: 10
      },
      lonaxis:{
        range: [-100, 20],
        showgrid: true,
        tickmode: 'linear',
        dtick: 20
      }
    }
};

Plotly.newPlot('myDiv', data, layout);

</script>\n</head>\n\n<body>\n\t<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>\n</body>","js":"var data = [{\n type: 'scattergeo',\n lat: [ 40.7127, 51.5072 ],\n lon: [ -74.0059, 0.1275 ],\n mode: 'lines',\n line:{\n width: 2,\n color: 'blue'\n }\n }];\n\nvar layout = {\n title: {text: 'London to NYC Great Circle'},\n showlegend: false,\n geo: {\n resolution: 50,\n showland: true,\n showlakes: true,\n landcolor: 'rgb(204, 204, 204)',\n countrycolor: 'rgb(204, 204, 204)',\n lakecolor: 'rgb(255, 255, 255)',\n projection: {\n type: 'equirectangular'\n },\n coastlinewidth: 2,\n lataxis: {\n range: [ 20, 60 ],\n showgrid: true,\n tickmode: 'linear',\n dtick: 10\n },\n lonaxis:{\n range: [-100, 20],\n showgrid: true,\n tickmode: 'linear',\n dtick: 20\n }\n }\n};\n\nPlotly.newPlot('myDiv', data, layout);\n\n"}">
d3.csv('https://raw.githubusercontent.com/plotly/datasets/c34aaa0b1b3cddad335173cb7bc0181897201ee6/2011_february_aa_flight_paths.csv', function(err, rows){
    function unpack(rows, key) {
        return rows.map(function(row) { return row[key]; });}

    function getMaxOfArray(numArray) {
        return Math.max.apply(null, numArray);
    }

    var data = [];
    var count = unpack(rows, 'cnt');
    var startLongitude = unpack(rows, 'start_lon');
    var endLongitude = unpack(rows, 'end_lon');
    var startLat = unpack(rows, 'start_lat');
    var endLat = unpack(rows, 'end_lat');

    for ( var i = 0 ; i < count.length; i++ ) {
        var opacityValue = count[i]/getMaxOfArray(count);

        var result = {
            type: 'scattergeo',
            locationmode: 'USA-states',
            lon: [ startLongitude[i] , endLongitude[i] ],
            lat: [ startLat[i] , endLat[i] ],
            mode: 'lines',
            line: {
                width: 1,
                color: 'red'
            },
            opacity: opacityValue
        };

        data.push(result);
    };

    var layout = {
        title: {text: 'Feb. 2011 American Airline flight paths'},
        showlegend: false,
        geo:{
            scope: 'north america',
            projection: {
                type: 'azimuthal equal area'
            },
            showland: true,
            landcolor: 'rgb(243,243,243)',
            countrycolor: 'rgb(204,204,204)'
        }
    };

    Plotly.newPlot("myDiv", data, layout, {showLink: false});

});
</script>\n\t<script src="/?originalUrl=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fd3%2F3.5.17%2Fd3.min.js"></script>\n</head>\n\n<body>\n\t<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>\n</body>","js":"d3.csv('https://raw.githubusercontent.com/plotly/datasets/c34aaa0b1b3cddad335173cb7bc0181897201ee6/2011_february_aa_flight_paths.csv', function(err, rows){\n function unpack(rows, key) {\n return rows.map(function(row) { return row[key]; });}\n\n function getMaxOfArray(numArray) {\n return Math.max.apply(null, numArray);\n }\n\n var data = [];\n var count = unpack(rows, 'cnt');\n var startLongitude = unpack(rows, 'start_lon');\n var endLongitude = unpack(rows, 'end_lon');\n var startLat = unpack(rows, 'start_lat');\n var endLat = unpack(rows, 'end_lat');\n\n for ( var i = 0 ; i < count.length; i++ ) {\n var opacityValue = count[i]/getMaxOfArray(count);\n\n var result = {\n type: 'scattergeo',\n locationmode: 'USA-states',\n lon: [ startLongitude[i] , endLongitude[i] ],\n lat: [ startLat[i] , endLat[i] ],\n mode: 'lines',\n line: {\n width: 1,\n color: 'red'\n },\n opacity: opacityValue\n };\n\n data.push(result);\n };\n\n var layout = {\n title: {text: 'Feb. 2011 American Airline flight paths'},\n showlegend: false,\n geo:{\n scope: 'north america',\n projection: {\n type: 'azimuthal equal area'\n },\n showland: true,\n landcolor: 'rgb(243,243,243)',\n countrycolor: 'rgb(204,204,204)'\n }\n };\n\n Plotly.newPlot(\"myDiv\", data, layout, {showLink: false});\n\n});\n"}">