Home > Enterprise >  How to Create Blank Lower 48 Map in Django JS
How to Create Blank Lower 48 Map in Django JS

Time:07-13

I'm trying to create a blank map in a Django app (via a JS script) to fill in some data. I'm not looking for anything more than a div with statelines drawn.

This tutorial attempts to do exactly that with d3. Unfortunately, it appears that the local file reference to a json file here is outdated and no longer works.

All things considered, I gave it a shot with the modular -m flag from tghe command line. My code for loading the basemap and json file looks like this (the json file is stashed in the saem directory as the html that calls this)

/*
Functions for graphing Terra data on basemap
Uses d3 library
*/
async function init() {
    let data = [0, 1, 2, 3, 4]
    // Set some specifications for the basemap
    let basemap_width = 960
    let basemap_height = 500
   
    // Build d3 projection
    // Scale in size to fit entire US
    let projection = d3.geo.albersUsa()
        .translate([basemap_width/2, basemap_height/2])
        .scale([1000]);         
        
    // Define path generator
    let path = d3.geo.path()               
        .projection(projection)  
        
    // Define scale and legend for basemap
    let color = d3.scale.linear()
        .range(["rgb(213,222,217)","rgb(69,173,168)","rgb(84,36,55)","rgb(217,91,67)"]);
    let legendText = ["Some range of values"];

    // Create SVG element and append map to the SVG
    let svg = d3.select("body")
        .append("svg")
        .attr("width", basemap_width)
        .attr("height", basemap_height);
        
    // Append Div for tooltip to SVG
    let div = d3.select("body")
        .append("div")   
        .attr("class", "tooltip")               
        .style("opacity", 0);
    
    // Load GeoJSON data into basemap
    d3.json("../us-states.json", function(json) { // I've tried this without the .. in the relative path as well
        // Loop through each state data value in the .csv file
        for (var i = 0; i < data.length; i  ) {
            // Find the corresponding state inside the GeoJSON
            for (var j = 0; j < json.features.length; j  )  {
                var jsonState = json.features[j].properties.name;

                if (dataState == jsonState) {
                    // Copy the data value into the JSON
                    json.features[j].properties.visited = dataValue; 

                   // Stop looking through the JSON
                   break;
                  }               
             }
        }
            
        // Bind the data to the SVG and create one path per GeoJSON feature
        svg.selectAll("path")
            .data(json.features)
            .enter()
            .append("path")
            .attr("d", path)
            .style("stroke", "#fff")
            .style("stroke-width", "1")
            //.style("fill", function(d) {
               // Some code to fill in color
            //});
    });
}
init();

What's the simplest way to accomplish this so I can start rtrying to load in my data?

CodePudding user response:

The code fails to work because the url path is incorrect. You are stating the location of file like a file in local hard drive. ../ is not a valid url path for async request.

d3.json("../us-states.json", () => { /* ... */})

d3.json() is just an asynchronous data fetcher. Internally, d3.json is a stupidly simple wrapper. Looking at the code, it is not outdated at all. Even the D3 team does not say it is outdated.

// https://github.com/d3/d3-fetch/blob/main/src/json.js
function responseJson(response) {
  if (!response.ok) throw new Error(response.status   " "   response.statusText);
  if (response.status === 204 || response.status === 205) return;
  return response.json();
}

export default function(input, init) {
  return fetch(input, init).then(responseJson);
}

Solution

Check how the local json file is served over url path. It can't be a relative directory(folder). Javascript and your web browser does not know the file location of javascript that is running. It only knows the absolute root of given domain.

"../file.json" --> wrong❌

"/resources/file.json" --> correct✅ the absolute root(/) of current domain is understood.
"https://example.com/resources/file.json" --> correct✅ full url was given.

before running the code, try check if the file is correctly served by accessing them from browser or try download it via shell.

$ curl https://example.com/resources/file.json

CodePudding user response:

I have checked your question regarding below code.

/*
Functions for graphing Terra data on basemap
Uses d3 library
*/
async function init() {
    let data = [0, 1, 2, 3, 4]
    // Set some specifications for the basemap
    let basemap_width = 960
    let basemap_height = 500
   
    // Build d3 projection
    // Scale in size to fit entire US
    let projection = d3.geo.albersUsa()
        .translate([basemap_width/2, basemap_height/2])
        .scale([1000]);         
        
    // Define path generator
    let path = d3.geo.path()               
        .projection(projection)  
        
    // Define scale and legend for basemap
    let color = d3.scale.linear()
        .range(["rgb(213,222,217)","rgb(69,173,168)","rgb(84,36,55)","rgb(217,91,67)"]);
    let legendText = ["Some range of values"];

    // Create SVG element and append map to the SVG
    let svg = d3.select("body")
        .append("svg")
        .attr("width", basemap_width)
        .attr("height", basemap_height);
        
    // Append Div for tooltip to SVG
    let div = d3.select("body")
        .append("div")   
        .attr("class", "tooltip")               
        .style("opacity", 0);
    
    // Load GeoJSON data into basemap
    d3.json("../us-states.json", function(json) { // I've tried this without the .. in the relative path as well
        // Loop through each state data value in the .csv file
        for (var i = 0; i < data.length; i  ) {
            // Find the corresponding state inside the GeoJSON
            for (var j = 0; j < json.features.length; j  )  {
                var jsonState = json.features[j].properties.name;

                if (dataState == jsonState) {
                    // Copy the data value into the JSON
                    json.features[j].properties.visited = dataValue; 

                   // Stop looking through the JSON
                   break;
                  }               
             }
        }
            
        // Bind the data to the SVG and create one path per GeoJSON feature
        svg.selectAll("path")
            .data(json.features)
            .enter()
            .append("path")
            .attr("d", path)
            .style("stroke", "#fff")
            .style("stroke-width", "1")
            //.style("fill", function(d) {
               // Some code to fill in color
            //});
    });
}
init();
  • Related