Как создать пустую карту Lower 48 в Django JS

Я пытаюсь создать пустую карту в приложении Django (через JS скрипт), чтобы заполнить некоторые данные. Мне не нужно ничего больше, чем div с нарисованными линиями.

В этом руководстве сделана попытка сделать именно это с помощью d3. К сожалению, похоже, что локальная ссылка на json-файл здесь устарела и больше не работает.

В общем, я попробовал с модульным флагом -m из командной строки. Мой код для загрузки basemap и json файла выглядит следующим образом (json файл спрятан в каталоге saem как html, который вызывает это)

/*
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();

Какой самый простой способ сделать это, чтобы я мог начать пытаться загрузить свои данные?

Я проверил ваш вопрос относительно приведенного ниже кода.

/*
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();

Код не работает из-за неправильного пути url. Вы указываете местоположение файла как файла на локальном жестком диске. ../ не является правильным url-путем для асинхронного запроса.

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

d3.json() - это просто асинхронный сборщик данных. Внутри d3.json - это тупо простая обертка. Если посмотреть на код, он совсем не устарел. Даже команда D3 не говорит, что он устарел

// 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);
}

Решение

Проверьте, как локальный json-файл обслуживается по url-пути. Это не может быть относительный каталог (папка). Javascript и ваш веб-браузер не знают местоположение файла запущенного javascript. Он знает только абсолютный корень заданного домена.

"../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.

прежде чем запускать код, попробуйте проверить, правильно ли обслуживается файл, обратившись к нему через браузер или попробуйте загрузить его через shell.

$ curl https://example.com/resources/file.json
Вернуться на верх