我正在使用 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
最佳答案
因为您已经通过 Flask 应用程序将 json 传递给客户端,所以无需使用 d3 的 d3.json()
方法。 d3.json()
本质上是一个 ajax
GET
请求,它从服务器请求文件。
d3.json(url[, callback])
Creates a request for the JSON file at the specified url with the mime type "application/json". If a callback is specified, the request is immediately issued with the GET method, and the callback will be invoked asynchronously when the file is loaded or the request fails; the callback is invoked with two arguments: the error, if any, and the parsed JSON. The parsed JSON is undefined if an error occurs. If no callback is specified, the returned request can be issued using xhr.get or similar, and handled using xhr.on.
您已经将数据存储在 javascript 的一个变量中,因此无需从服务器请求它。
此外,当您尝试请求它时,您传递了一个无效的 url。
删除 d3.json()
函数并运行其余代码应该可以。
关于javascript - 为 D3 解析 JSON 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38730227/