使用D3.js加载本地数据以进行可视化 [英] Loading local data for visualization using D3.js

查看:174
本文介绍了使用D3.js加载本地数据以进行可视化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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



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


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


  2. 目标用户绝对不是技术人员 - 精明,所以不能指示他们在他们的计算机上运行网络服务器,以便能够通过localhost提供JSON或任何其他类型或资源


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

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

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



我该怎么做才能避免/解决这个问题?

解决方案

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



首先关闭< body> 部分:

 < input type =fileid =filesname =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 canceled');};
var imageObj = new Image(); //用于保存本地文件内容的图像对象。

//并且给定异步性质,设置事件以便在加载图像时使用它做一些事情:
imageObj.onload = function(){image.datum(imageObj) .src).attr(xlink:href,function(d){return d})};

//类似于文件读取:
reader.onload = function(e){imageObj.src = reader.result};

//设置好所有事件后,让我们开始阅读文件。
//秘密酱是DataURL
reader.readAsDataURL(evt.target.files [ 0]);
}

为了完整性,图像背后的D3JS酱:

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

var image = svg.append(defs)
.append(pattern)$​​ b $ b .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));


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).

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.

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:

  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

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,

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

What can I do to avoid/solve this problem?

解决方案

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 any other data, just add the correct processing to it...

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

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

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

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):

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:

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)");

这篇关于使用D3.js加载本地数据以进行可视化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆