Подтвердить что ты не робот

Загрузка локальных данных для визуализации с использованием D3.js

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

Я начал работать над визуализацией с использованием D3, макет, который я написал, кажется, работает нормально до сих пор, когда я тестирую его с помощью очень простых данных, которые я жестко кодирует в Javascript как массив. Учебники, которые я прочитал о привязке данных в D3, были немного запутанными в том смысле, что некоторые используют JSON, а некоторые используют формат TXT/CSV, а некоторые другие используют жестко заданные массивы/матрицы.

В случае JSON я просмотрел учебник, в котором рассказчик твердо советует размещать файл JSON на веб-сервере и получать его с использованием HTTP-запроса вместо локального файла. Я понимаю, что это связано с ограничениями, связанными с перекрестными доменами, и я считаю, что мне нужно как-то обойтись. На данный момент я не уверен, как действовать, начиная с:

  • Визуализация, основанная на D3, будет представлена ​​в серии отчетов HTML, которые создаются в качестве результатов инструмента анализа, который я написал. Анализ выполняется на компьютере пользователя, а отчеты HTML также создаются локально на стороне клиента.

  • Предполагаемые пользователи наиболее определенно не разбираются в технологиях, поэтому не обязательно указывать им запускать веб-сервер на своем компьютере, чтобы иметь возможность обслуживать JSON или любой другой тип или ресурс через localhost

Для записи я попытался запустить модуль python SimpleHTTPServer, чтобы попробовать, и снова все работает нормально. Затем я попытался жестко закодировать данные в сгенерированных отчетах HTML, а затем вызвать объект JSON из моего script, который использует D3,

//d3.json("mydata.json", function(json){
d3.json(myjson, function(json){
    nodeData = json.elements;
....
}

так как в этом случае я заканчиваю отправку в объект JSON, а D3.js ожидает URL.

Что я могу сделать, чтобы избежать/решить эту проблему?

4b9b3361

Ответ 1

Чтобы загрузить локальные файлы данных без использования сервера, добавьте тег script в тело с исходными данными, назначенными переменной или объекту, который вы ожидаете. В приведенном ниже примере я загружаю данные для определенной страны из файла [COUNTRY_ISO3CODE].js. В частности, файл данных Афганистана может содержать содержимое в формате:

data[AFG] = {"name": "Afghanistan", "estimate": 9.003, ... }

В вызывающем файле будет что-то вроде:

if (!data[iso3]) { //only load the needed data-script as needed

    // if using jQuery
    $('body').append("<script type='text/javascript' src='jdb/"+ iso3 +".js'></script>")

    //If not using jQuery
    /*var script   = document.createElement("script");
    script.type  = "text/javascript";
    script.src   = "jdb/"+iso3+".js"; //?_="+ (new Date()); URL might have to be randomized to avoid cached data
    document.body.appendChild(script);
    */

    // call the data-handling function only after 
    // the desired data has fully loaded
    // in this case, I check every 100 milliseconds
    var intervalId = setInterval( function () {
        if (data[iso3]) {    //once data is detected, process data
            clearInterval(intervalId); //stop checking for data
            prepData(mainWrapper, iso3)
            drawCharts(mainWrapper, iso3)
        }
    }, 100)
}
else drawCharts(mainWrapper, iso3)

Ответ 2

Для JSON:

var data = JSON.parse(JavascriptStringVariableThatContainsJSON);

Для CSV:

 var data = d3.csv.parseRows(JavascriptStringVariableThatContainsMyCSVdata);

//затем добавьте данные в график и вызовите enter, что-то вроде:

 var dataEnter = svg.selectAll("rect").data(data).enter();

Ответ 3

Итак, вы хотите загрузить локальные данные с помощью вызова FileReader, материал ниже берется из Чтение локальных файлов в JavaScript. Однако, опираясь на пример сверху, этот код загружает файл изображения в svg без связывания файла, но фактически вставляет растровые данные в svg. И не стесняйтесь заменять растровые данные любыми другими данными, просто добавляйте к нему правильную обработку...

Сначала откройте поддерживающие html-элементы в разделе <body>:

<input type="file" id="files" name="files[]" multiple />

Затем вы хотите связать элемент <input ... /> с некоторым кодом в разделе <script>:

document.getElementById('files').addEventListener('change', handleFileSelect, false);

Теперь код за файлом, прочитанным в коде обработки событий (теперь в этом случае я хочу загрузить локальное изображение в D3JS svg):

function handleFileSelect(evt) {
    reader = new FileReader();
    reader.onabort = function(e) {alert('File read cancelled');};
    var imageObj = new Image();  //image object to hold the local file contents.

    //and given the asynchronous nature, set up the event so that when the image is loaded, do something with it:
    imageObj.onload = function() {image.datum(imageObj.src).attr("xlink:href", function(d) {return d})};

    //similarly for the file reading:
    reader.onload = function(e) {imageObj.src = reader.result};

    //With all the events set up, lets start reading the file in.
    //the secret sauce is the DataURL
    reader.readAsDataURL(evt.target.files[0]);
}

И для полноты соус D3JS за изображением:

var svg = d3.select("body").append("svg");

var image = svg.append("defs")
    .append("pattern")
    .attr("id", "venus")
    .attr('patternUnits', 'userSpaceOnUse')
    .attr("width", 200)
    .attr("height", 200)
    .append("image")
    .attr("width", 200)
    .attr("height", 200);

var image2 = svg.append("rect")
    .attr("x", "0")
    .attr("y", "0")
    .attr("width", 200)
    .attr("height", 200)
    .attr("fill", "url(#venus)");

Ответ 4

Если вы каждый раз генерируете HTML-код, вы можете поместить данные как JSON либо прямо в свой HTML файл, либо в .js файл, который вы можете ссылаться на HTML, возможно, через сгенерированный уникальный URL-адрес.

Ответ 5

У D3 есть отличные инструменты для импорта данных и управления им. Всегда служил json в прошлом (и это иногда сложно создать). Я собираюсь больше обслуживать csv и манипулировать им в javascript/d3, но было бы интересно посмотреть, как другие отвечают на ваш вопрос.

Это простой пример, показывающий csv для вложенного json здесь: https://gist.github.com/3053667

Также имеется множество инструментов для управления данными: https://github.com/mbostock/d3/wiki/Arrays

И тогда есть Crossfilter, если вы хотите нарезать кубиками. Выглядит хорошо, чтобы справиться с этим, но я жду, когда манекен выйдет! http://square.github.com/crossfilter/

Ответ 6

d3.json загружает внешние json файлы через ajax-вызовы - переменная myjson в вашем примере уже является объектом javascript, поэтому вам не нужно ее загружать, просто используйте ее непосредственно в назначении nodeData.

nodeData = myjson.elements;