【发布时间】:2016-08-02 20:51:57
【问题描述】:
我正在使用 Flask 和 Python 构建一个应用程序,并且我想将一些 Python 生成的结果传递到 JSON 中,以便它们可以在容器流体下使用 D3 进行可视化。为此,我尝试使用 Jinja 方法var myjson = {{jsonDict|tojson }};。这里jsonDict 是我的Python 代码中的一个变量,它是一个dict 字符串,其中单引号已替换为带有正则表达式的双引号,因此它看起来像正确的JSON。我也在用JS方法root = JSON.parse( myjson );。我相信这两者的结合应该可以解决我的问题,但是当我运行代码时,我得到了错误:
(index):2222
Uncaught SyntaxError: Unexpected token y in JSON at position 0
uo @ d3.v3.min.js:3
i @ d3.v3.min.js:1
这是我尝试使用的 D3 模板: http://bl.ocks.org/mbostock/7607535
这是我对这个 D3 的实现(只是相关脚本):
<script>
var margin = 20,
diameter = 960;
var color = d3.scale.linear()
.domain([-1, 5])
.range(["hsl(152,80%,80%)", "hsl(228,30%,40%)"])
.interpolate(d3.interpolateHcl);
var pack = d3.layout.pack()
.padding(2)
.size([diameter - margin, diameter - margin])
.value(function(d) { return d.size; })
var svg = d3.select("#dan").append("svg") //#dan is name of my container fluid
.attr("width", diameter)
.attr("height", diameter)
.append("g")
.attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");
//this is the part of the code I have added //
var myjson = {{ jsonDict|tojson }};
root = JSON.parse( myjson );
//this is the part of the code I have added //
d3.json("root", function(error, root) {
if (error) throw error; //this is index 2222
var focus = root,
nodes = pack.nodes(root),
view;
var circle = svg.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; })
.style("fill", function(d) { return d.children ? color(d.depth) : null; })
.on("click", function(d) { if (focus !== d) zoom(d), d3.event.stopPropagation(); });
var text = svg.selectAll("text")
.data(nodes)
.enter().append("text")
.attr("class", "label")
.style("fill-opacity", function(d) { return d.parent === root ? 1 : 0; })
.style("display", function(d) { return d.parent === root ? "inline" : "none"; })
.text(function(d) { return d.name; });
var node = svg.selectAll("circle,text");
d3.select("#dan")
.style("background", color(-1))
.on("click", function() { zoom(root); });
zoomTo([root.x, root.y, root.r * 2 + margin]);
function zoom(d) {
var focus0 = focus; focus = d;
var transition = d3.transition()
.duration(d3.event.altKey ? 7500 : 750)
.tween("zoom", function(d) {
var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]);
return function(t) { zoomTo(i(t)); };
});
transition.selectAll("text")
.filter(function(d) { return d.parent === focus || this.style.display === "inline"; })
.style("fill-opacity", function(d) { return d.parent === focus ? 1 : 0; })
.each("start", function(d) { if (d.parent === focus) this.style.display = "inline"; })
.each("end", function(d) { if (d.parent !== focus) this.style.display = "none"; });
}
function zoomTo(v) {
var k = diameter / v[2]; view = v;
node.attr("transform", function(d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; });
circle.attr("r", function(d) { return d.r * k; });
}
});
d3.select(self.frameElement).style("height", diameter + "px");
</script>
如你所见,我从 D3 代码中替换了原来的 JS 行:
d3.json("flare.json", function(error, root) {
if (error) throw error;
与:
var myjson = {{ jsonDict|tojson }};
root = JSON.parse( myjson );
d3.json("root", function(error, root) {
由于我现在有我的代码,如果我检查页面,svg 会显示在网页上的正确位置,但它是空白的。
我是 D3 和 Javascript 的新手。任何帮助将非常感激!谢谢!
编辑 - 控制台日志
如果我执行 console.log(myjson),控制台会正确打印 JSON 字符串(见下文)
如果我执行 console.log(root),控制台会打印
Object {children: Array[2], name: "flare"}
children:Array[2]
name:"flare"
__proto__:Object
__defineSetter__: __defineSetter__()
__lookupGetter__:__lookupGetter__()
__lookupSetter__:__lookupSetter__()
constructor:Object()
hasOwnProperty:hasOwnProperty()
isPrototypeOf:isPrototypeOf()
propertyIsEnumerable:propertyIsEnumerable()
toLocaleString:toLocaleString()
toString:toString()
valueOf:valueOf()
get __proto__:__proto__()
set __proto__:__proto__()
所以看来JSON.parse 方法在某种程度上让我失望了。
编辑——我的 JSON 字符串从 Python 传递到 var myjson
{"name": "flare", "children": [{"name": "concept0", "children": [{"name": "intermediate host", "size": 700}, {"name": "abstrusus brevior", "size": 700}, {"name": "stage larva", "size": 700}, {"name": "anterior extremity", "size": 700}, {"name": "crenosoma vulpi", "size": 700}]}, {"name": "concept1", "children": [{"name": "infected cat", "size": 700}, {"name": "abstrusus infection", "size": 700}, {"name": "domestic cat", "size": 700}, {"name": "feline aelurostrongylosis", "size": 700}, {"name": "cat infect", "size": 700}]}]}
console.log(myjson) 的页面源
{"name": "flare", "children": [{"name": "concept0", "children": [{"size": 700, "name": "intermediate host"}, {"size": 700, "name": "abstrusus brevior"}, {"size": 700, "name": "stage larva"}, {"size": 700, "name": "anterior extremity"}, {"size": 700, "name": "crenosoma vulpi"}]}, {"name": "concept1", "children": [{"size": 700, "name": "infected cat"}, {"size": 700, "name": "abstrusus infection"}, {"size": 700, "name": "domestic cat"}, {"size": 700, "name": "feline aelurostrongylosis"}, {"size": 700, "name": "cat infect"}]}]}
编辑 - 我认为问题可以在 console.log(root) 中看到。我检查了其他 D3 可视化,日志通常应如下所示:
Object {name: "flare", children: Array[5]}
children: Array[5]
depth:0
name:"flare"
r:470
value:21000
x:470
y:470
__proto__:Object
【问题讨论】:
-
使用console.log(root) 查看您使用的任何浏览器的开发者控制台中的root 是什么。验证您的 root 是正确的 JSON,并且是 D3 所期望的正确格式。
-
@SnarkShark 谢谢 - 这正是它在页面源代码中列出的方式吗?您介意复制以
var myjson =开头的输出行吗? -
您在 jinja 模板中使用了
tojson()。 此函数将给定对象转换为 JSON 表示形式。 那么为什么之后需要使用JSON.parse()?不能直接传myjson吗? -
d3.json以 url 作为其参数,本质上它是一个 ajax 请求,但您已经有您的数据,所以不需要调用它。尝试在没有d3.json()函数的情况下运行您的代码 -
@Craicerjack,如果您愿意,您可以复制/粘贴您对
d3.json()函数的回复作为对我问题的回答,这样我就可以接受它作为最佳答案,而您回答问题将获得荣誉:)
标签: javascript python json d3.js flask