我正在最终学习D3,我偶然发现了一个我无法找到答案的问题.我不确定我的问题是因为我没有习惯性地使用库,或者是因为我目前没有意识到的程序.我还要提一下,我在6月才开始做与网络相关的事情,所以我对javascript很新.
假设我们正在构建一个工具,为用户提供包含相应图像的食物列表.并且让我们添加额外的约束,每个列表项需要用唯一的ID标记,以便它可以链接到另一个视图.我首先要解决这种直觉是创造名单<div>
每个的用自己的ID,每个div
都有自己的<p>
和<img>
.生成的HTML看起来像:
<div id="chocolate">
<p>Chocolate Cookie</p>
<img src="chocolate.jpg" />
</div>
<div id="sugar">
<p>Sugar Cookie</p>
<img src="sugar.jpg" />
</div>
Run Code Online (Sandbox Code Playgroud)
此工具的数据位于JSON数组中,其中单个JSON如下所示:
{ "label": "sugar", "text": "Sugar Cookie", "img": "sugar.jpg" }
Run Code Online (Sandbox Code Playgroud)
有没有办法一举生成HTML?从添加div的基本情况开始,代码可能类似于:
d3.select(containerId).selectAll('div')
.data(food)
.enter().append('div')
.attr('id', function(d) { return d.label; });
Run Code Online (Sandbox Code Playgroud)
现在,有关将<div>
用<p>
它吗?我最初的想法是做一些像:
d3.select(containerId).selectAll('div')
.data(food)
.enter().append('div')
.attr('id', function(d) { return d.label; })
.append('p').text('somethingHere');
Run Code Online (Sandbox Code Playgroud)
但是,我看到了两个问题:(1)如何从div
元素中获取数据,以及(2)如何在一个声明链中将多个子元素附加到同一个父元素中?我无法想出一种方法来迈出我追加的第三步img
.
我在另一篇文章中找到了嵌套选择的提法,它指向http://bost.ocks.org/mike/nest/.但是嵌套选择,因此将附加分成三个块,适合/惯用于这种情况?或者实际上是否有一种构造良好的方式在一个声明链中形成这个结构?看起来https://github.com/mbostock/d3/wiki/Selections上提到的子选择可能有一种方法,但我对该语言不太熟悉以测试该假设.
从概念层面来看,这三个对象(div
,p
和img
)被视为更像是一个组而不是单独的实体,如果代码也反映出来也会很好.
我的最终目标是在单击按钮时向node.js发送任意JSON.我目前只知道如何从表单发送输入.以下是我汇总发送表单信息的一些代码:
function postForm() {
$('form').submit(function(e) {
e.preventDefault(); // no page reload
$.post(
$(this).attr('action'),
$(this).serialize(),
function(data) { console.log('Code for handling response here.') },
'json'
);
});
}
Run Code Online (Sandbox Code Playgroud)
HTML的外观如下:
<form action='/send' method='post'>
<input name= "foo" type="radio" value=1>
<input type="submit" value="Submit">
</form>
Run Code Online (Sandbox Code Playgroud)
相关的express/node.js代码如下所示:
app.post('/send', function(request, response) {
fs.appendFile('test.txt', JSON.stringify(request.body) + '\n', function(e) {
if(e) throw e;
console.log(request.body);
});
});
Run Code Online (Sandbox Code Playgroud)
但是,我不知道如何调整此示例以使用非来自表单输入的数据.为了给出上下文,我正在构建一个基于Web的用户研究,我想将收集的有关用户的各种信息发送到node.js. 我已尝试过为表单提交工作的变体,但我的尝试都没有成功.我的印象是我可以换掉$(this).serialize()
客户端可以访问的任何其他数据,但我无法让这种想法发挥作用.我也试过改变一些.ajax()
例子,但那些总是重定向页面是不可取的,因为如果页面刷新,我的研究将丢失用户状态信息.
我已经做了大量的客户端和服务器端编程,但我几乎不知道ajax是如何工作的,这对于解决这个问题来说证明是有问题的!而且相当愚蠢,因为,往往,这是将两者粘合在一起:)
我已经看到了在单个页面上创建多个强制布局的解决方案,其中每个布局都包含在自己的SVG中; 但是,我无法找到有关如何在单个SVG中包含多个强制布局的帮助.每个布局都有自己的数据.
我目前正在做的一个例子可以在http://jsfiddle.net/connorgr/SRAJa/找到.我已经包含了下面代码的关键部分.除了最后一个节点/链接数据之外,最终结果看起来非常像强制布局从未激活(或删除).有没有办法防止这种情况发生?
由于我正在构建的可视化的用例,我无法将数据合并在一起并仅使用一个布局.
/**
* Creates a force layout in svgObj for each element in graphs
* (svg) svgObj - The SVG to include the force layouts in
* (json) graphs - An array of {"nodes":[...],"links":[...]} objects
*/
function generateMultiForce(svgObj, graphs) {
for(var i=0; i < graphs.length; i++) {
var graph = graphs[i];
var graphArea = svgObj.append("g");
var force = d3.layout.force()
.charge(-200)
.linkDistance(45)
.size([width, height])
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = graphArea.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link");
var …
Run Code Online (Sandbox Code Playgroud) 有没有办法避免在我的HTML文件中的每个javascript src属性中加上"public","static"等?我正在将一个基本的静态服务器从Node.js转换为Tornado,除此之外一切都很顺利.
我想模拟的等效Node.js/Express代码如下:
var app = express();
app.use(express.static(__dirname + '/public'));
Run Code Online (Sandbox Code Playgroud)
这有效地改变了所有内容的服务目录.这样我可以做一些事情,<script src="js/foo.js">
而不是<script src="public/js/foo.js">
.
我在SO上看到的解决静态文件服务的所有解决方案(就像这个一样)让它处于"只是前置/静态".
这就是我现在所拥有的:
import os
import tornado.ioloop
import tornado.web as web
public_root = os.path.join(os.path.dirname(__file__), 'public')
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.render('index.html')
handlers = [
(r'/public/(.*)', web.StaticFileHandler, {'path': public_root}),
(r'/', MainHandler)
]
settings = dict(
debug=True,
static_path=public_root,
template_path=public_root
)
application = web.Application(handlers, **settings)
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
Run Code Online (Sandbox Code Playgroud)
当我尝试加载index.html
HTML渲染时,我也收到此错误:
WARNING:tornado.access:404 GET /bower_components/d3/d3.min.js (::1) 0.55ms
d3.js ×2
ajax ×1
express ×1
force-layout ×1
javascript ×1
jquery ×1
layout ×1
node.js ×1
python ×1
tornado ×1