Проблема с динамической загрузкой данных JSON с помощью d3. js в карту Leaflet - PullRequest
0 голосов
/ 23 февраля 2020

У меня есть листовка с географическим указанием c точек с использованием d3. js. Карта считывается в файл JSON и отображается в виде точки на карте.

Я хочу, чтобы карта могла динамически загружаться в различные JSON файлы на основе пользовательского ввода. (По сути, каждый JSON содержит геоданные для другого города). Я понимаю, что могу использовать базу данных, но пока не хочу go этот маршрут.

Вот мой код:

// JSON for NYC
var nyc_events = [{"Address": "200 Varick St, New York, NY 10014", "Artist": "Roll Call", "ArtistImage": "https://photos.bandsintown.com/thumb/172269.jpeg", "Coordinates": [-74.00478, 40.72826], "Date": "Tue Feb 11 2020", "EventDate": "2020-02-11", "Genre": "No genre available", "Time": "8:30 PM", "Venue": "SOB's", "moreBioInfo": "No artist bio available", "otherInfo": "No other event info available"}, {"Address": 

// JSON for San Francisco
var sf_events = [{"Address": "220 Ellis St, San Francisco, CA 90014", "Artist": "Young Jeezy", "ArtistImage": "https://photos.bandsintown.com/thumb/172269.jpeg", "Coordinates": [-89.00478, 39.72826], "Date": "Tue Feb 11 2020", "EventDate": "2020-02-11", "Genre": "No genre available", "Time": "8:30 PM", "Venue": "Slim's", "moreBioInfo": "No artist bio available", "otherInfo": "No other event info available"}, {"Address":

//Define data
var sfData = "./data/sf_events.json" 
var nycData = "./data/nyc_events.json" 


//function to dynamically load in data.  Function called with event listeners in readyLeaflet function below.
function changeData(data, parameter) {

    d3.queue()
        .defer(d3.csv,data, function(d) { 
    })
    .await(readyLeaflet(parameter));
}

//call function to populate map with data
changeData(sfData, sf_events)


function readyLeaflet(eventArray) {

    //construct datepicker element
    const picker = datepicker(document.querySelector('#datepicker'), {

        // Event callbacks.
        onSelect: function(instance) {

            var instanceSplit = instance.dateSelected.toString().split(" " ,4)
            var dayofMonth = instanceSplit[2]

            //check if date selected on datepicker is equal to date in JSON data
            //if equal, filter JSON data that matches current date
            //.........
            //.........
            //.........
            update()

        },

        onShow: function(instance) {
        },
        onHide: function(instance) {
        },
        onMonthChange: function(instance) {
        },

        // Customizations.
        formatter: function(el, date, instance) {
            el.value = date.toDateString();
            dat = new Date()
        },

        customDays: ['S', 'M', 'T', 'W', 'Th', 'F', 'S'],
        customMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],

        dateSelected: new Date(), // Today is selected.
        startDate: new Date(), // This month.

    });

    //Build leaflet map
    var map = L.map('map')

    var gl = L.mapboxGL({
        accessToken: token,
        style: 'mapbox://styles/mapbox/dark-v8'
    }).addTo(map);

    var svgLayer = L.svg()
        svgLayer.addTo(map);

    var svgMap = d3.select("#map").select("svg");
        var mapG = svgMap.select('g');


     //Add points using d3
    eventArray.forEach(function(d) {

        d.latLong = new L.LatLng(d.Coordinates[1],
              d.Coordinates[0]);
    })

    var events = mapG.selectAll("circle")
        .data(eventArray)
        .enter().append("circle")
        .attr("class", 'events')
        .style("fill", '#ffba00')
        .attr("r", 17.5)



    //Add event listener.  If button clicked, call new data.
    //This fails
    d3.selectAll("#changeData").on("change", function() {

        changeData(nycData, nyc_events)

    });

 }

Первоначальный вызов changeData () работает очень хорошо и заполняет карту данными, как и ожидалось. Это дает мне следующую ошибку, но карта по-прежнему отображает данные:

d3.v4.min.js:2 Uncaught Error: invalid callback
at Zo.await (d3.v4.min.js:2)
at changeData (main.js:59)
at HTMLDocument.<anonymous> (main.js:62)

Однако вызов changeData (nycData, nyc_events) в функции листовки (с кнопкой прослушивания события #changeData button) полностью завершается неудачей. Я получаю сообщение об ошибке:

Uncaught A datepicker already exists on that element.

Чтобы попытаться решить эту проблему, я добавил $("#datepicker").datepicker("destroy"); в функцию changeData (), чтобы она удаляла средство выбора даты перед вызовом новых данных, но это ничего. Фактически, даже когда я полностью удаляю средство выбора даты из DOM, я получаю серию ошибок:

d3.v4.min.js:2 Uncaught Error: invalid callback
at Zo.await (d3.v4.min.js:2)
at changeData (main.js:59)
at HTMLDocument.

И:

leaflet-src.js:3251 Uncaught Error: Map container is already initialized.
at e._initContainer (leaflet-src.js:3251)
at e.initialize (leaflet-src.js:2370)

Я подозреваю, что я установил динамическая c JSON загрузка в changeData () не работает должным образом. Есть ли лучший / более простой способ выполнить sh, что я пытаюсь сделать? Интуиция подсказывает мне, что ошибка выбора даты - это признак ошибки при попытке динамической загрузки новых данных, а не root проблемы.

Спасибо!

...