Javascript 使用 D3.js 加载本地数据进行可视化

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11411280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 05:45:37  来源:igfitidea点击:

Loading local data for visualization using D3.js

javascriptjsond3.js

提问by posdef

I am working on a project which requires me to visualize a rather complicated type of data (see this older question). In short, I have a large chunk of data which I can export to JSON, CSV or some other arbitrary flat format although I prefer to avoid XML if possible (see the linked question above for in-detail explanation of the underlying data).

我正在开展一个项目,该项目要求我可视化相当复杂的数据类型(请参阅这个较旧的问题)。简而言之,我有大量数据可以导出为 JSON、CSV 或其他任意平面格式,尽管我更愿意尽可能避免使用 XML(有关基础数据的详细说明,请参阅上面的链接问题)。

I have started working on a visualization using D3, the layout I wrote seems to work OK so far when I test it with some very simple data that I hardcode in the Javascript as an array. The tutorials I read on data binding in D3 have been a bit confusing in the sense that some use JSON and some use TXT/CSV format while some others use hardcoded arrays/matrices.

我已经开始使用 D3 进行可视化工作,到目前为止,当我使用一些我在 Javascript 中硬编码为数组的非常简单的数据对其进行测试时,我编写的布局似乎可以正常工作。我在 D3 中阅读的有关数据绑定的教程有些令人困惑,因为有些使用 JSON,有些使用 TXT/CSV 格式,而有些使用硬编码数组/矩阵。

In the case of JSON, I watched a tutorial where the narrator firmly advises to host the JSON file on a webserver and get it using a HTTP request instead of a local file read. I realize that this is due to cross domain request limitations, which I believe I have to work-around somehow. At this point I am not sure how to proceed since:

在 JSON 的情况下,我观​​看了一个教程,其中叙述者坚决建议将 JSON 文件托管在网络服务器上,并使用 HTTP 请求而不是读取本地文件来获取它。我意识到这是由于跨域请求限制,我相信我必须以某种方式解决。在这一点上,我不确定如何继续,因为:

  1. The D3-powered visualization will be on a series of HTML reports which are created as results of an analysis tool I wrote. The analysis is done on the users computer, and the HTML reports are also created locally on the client-side.

  2. The intended users are most definitely not tech-savvy, so it is not an option to instruct them to run an webserver on their computer to be able to serve JSON or any other type or resource via localhost

  1. D3 驱动的可视化将基于一系列 HTML 报告,这些报告是我编写的分析工具的结果。分析在用户计算机上完成,HTML 报告也在客户端本地创建。

  2. 目标用户绝对不精通技术,因此不能指示他们在他们的计算机上运行网络服务器以便能够通过本地主机提供 JSON 或任何其他类型或资源

For the record, I have tried running the python SimpleHTTPServer module to try it out, and again everything works fine. I then tried to hard-code the data in the generated HTML reports, then call on the JSON object from my script which uses D3,

作为记录,我已经尝试运行 python SimpleHTTPServer 模块进行尝试,并且一切正常。然后我尝试对生成的 HTML 报告中的数据进行硬编码,然后从使用 D3 的脚本调用 JSON 对象,

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

which fails since in that case I end up sending in a JSON object while D3.js is expecting a URL.

这失败了,因为在这种情况下,我最终发送了一个 JSON 对象,而 D3.js 需要一个 URL。

What can I do to avoid/solve this problem?

我能做些什么来避免/解决这个问题?

回答by Edgar

To load data local files without using a server, append a script tag to the body with the source data assigned to a variable or object element that you are expecting. In the example below, I load data for a certain country from a [COUNTRY_ISO3CODE].js file. Specifically, an Afghanistan data file might have the content in the format:

要在不使用服务器的情况下加载数据本地文件,请将脚本标记附加到正文中,并将源数据分配给您期望的变量或对象元素。在下面的示例中,我从 [COUNTRY_ISO3CODE].js 文件加载某个国家/地区的数据。具体来说,阿富汗数据文件可能具有以下格式的内容:

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

The calling file will have something like:

调用文件将包含以下内容:

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)

回答by pilavdzice

For JSON:

对于 JSON:

var data = JSON.parse(JavascriptStringVariableThatContainsJSON);

For CSV:

对于 CSV:

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

//then add data to the graph and call enter, something like:

//然后将数据添加到图形并调用回车,例如:

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

回答by Mike

So you want to load the local data through a FileReader call, the stuff below is taken from Reading local files in JavaScript. However, building on the example from above, this code loads a image file into an svg without linking the file, but actually inserting the raster data into the svg. And feel free to replace raster data with anyother data, just add the correct processing to it...

所以你想通过 FileReader 调用加载本地数据,下面的内容取自在 JavaScript 中读取本地文件。但是,在上面的示例的基础上,此代码将图像文件加载到 svg 中,但并未链接该文件,而是将栅格数据实际插入到 svg 中。并随意用任何其他数据替换栅格数据,只需向其添加正确的处理...

First off the supporting html elements in the <body>section:

首先关闭部分中的支持 html 元素<body>

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

Then you want to link the <input ... />element to some code in the <script>section:

然后你想将<input ... />元素链接到部分中的一些代码<script>

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

Now the code behind the file read in the event handling code (Now in this case I want to load a local image into a D3JS svg):

现在文件背后的代码在事件处理代码中读取(现在在这种情况下我想将本地图像加载到 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]);
}

And for completeness the D3JS sauce behind the image:

为了完整起见,图像背后的 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)");

回答by Joseph Boyle

If you are generating HTML each time, you can put data as JSON either in right in your HTML or in a .js file that you can reference from the HTML, probably via a generated unique URL.

如果您每次都生成 HTML,您可以将数据作为 JSON 放在您的 HTML 中或您可以从 HTML 中引用的 .js 文件中,可能是通过生成的唯一 URL。

回答by David Burrows

d3.json loads external json files via ajax calls - the myjsonvariable in your example is already a javascript object so you don't need to load it, just use it directly in your nodeDataassignment.

d3.json 通过 ajax 调用加载外部 json 文件 -myjson您示例中的变量已经是一个 javascript 对象,因此您不需要加载它,只需在您的nodeData任务中直接使用它即可。

nodeData = myjson.elements;

回答by PhoebeB

D3 has some great tools for importing data and manipulating it. Having always served json in the past (and that is sometimes a hassle to create) I'm going more towards serving csv and manipulating it in javascript/d3 but would be interested to see how others respond to your question.

D3 有一些很棒的工具来导入和操作数据。过去一直提供 json 服务(有时创建起来很麻烦)我更倾向于提供 csv 服务并在 javascript/d3 中操作它,但有兴趣看看其他人如何回应您的问题。

This is a simple example showing csv to nested json here: https://gist.github.com/3053667

这是一个简单的示例,显示 csv 到嵌套的 json:https: //gist.github.com/3053667

Also lots of tools for manipulating data: https://github.com/mbostock/d3/wiki/Arrays

还有很多用于操作数据的工具:https: //github.com/mbostock/d3/wiki/Arrays

And then there is Crossfilter if you want to slice and dice. Looks well worth getting to grips with but am waiting for the dummies guide to come out! http://square.github.com/crossfilter/

如果你想切片和切块,还有 Crossfilter。看起来很值得一试,但我正在等待傻瓜指南出来! http://square.github.com/crossfilter/