如何使用python flask应用程序在d3js图表中动态加载json数据 [英] how to dynamically load json data in d3js chart using python flask application
问题描述
我正在开发这个用于创建树形图的d3JS示例。该示例使用flare.json作为包含json数据的文件。
但是我希望从我的python flask应用程序发送这个json数据并加载到javascript中。 / p>
这是当前从flare.json文件加载JSON的方式:
d3.json(flare.json,function(error,root){
var node = div.datum(root).selectAll(。node)
.data(treemap.nodes) )
.enter()。append(div)
.attr(class,node)
.call(position)
.style(background ,function(d){return d.children?color(d.name):null;})
.text(function(d){return d.children?null:d.name;});
d3.selectAll(input)。on(change,function change(){
var value = this.value ===count
?function() {return 1;}
:function(d){return d.size;};
node
.data(treemap.value(value).nodes)
.transition()
.duration(1500)
。电话(职位);
});
});
我想以某种方式修改它并实现这样的目标:
//加载数据。
var callback = function(data,error,root){
var node = div.datum(root).selectAll(。node)
.data(treemap.nodes)
.enter()。append(div)
.attr(class,node)
.call(position)
.style(background,function( d){return d.children?color(d.name):null;})
.text(function(d){return d.children?null:d.name;});
d3.selectAll(input)。on(change,function change(){
var value = this.value ===count
?function (){return 1;}
:function(d){return d.size;};
node
.data(treemap.value(value).nodes)
.transition()
.duration(1500)
.call(position);
});
};
d3.json(/ data,回调);
目前这对我不起作用。
在我的app.py文件中,这是我的一些代码:
app = flask.Flask(__ name__)
@ app.route(/)
def index():
当你请求根路径时,你会获取index.html模板。
返回flask.render_template(index.html)
@ app.route( / data)
@ app.route(/ data /< int:ndata>)
def data():
d3js_chart_data = json.dumps(
{// JSON here}
)
返回d3js_chart_data
如果__name__ ==__ main__:
import os
port = 80
#打开指向应用程序的Web浏览器。
os.system(open http:// localhost:{0}。format(port))
#在端口8000上设置开发服务器。
app。 debug = True
app.run(host ='0.0.0.0',port = port)
我认为您只需要在 d3.json(url,function(...)
中添加网址到您的服务器并且它应该适合你。没有必要单独回调,但如果你愿意的话你可以单独回调。
在你的回调中我认为你不需要添加 data
参数,因为数据是root。
(如果你是要求来自不同站点的数据,服务器需要启用CORS以允许跨源请求。)
请在下面的mocky.io中找到包含数据的工作演示。这正是树形图演示中的代码,只是数据来自不同的位置,并在点击回调后加载。
你可以鳍d同样也出现在 jsFiddle 。
var margin = {top:40,right:10,bottom:10,left:10},width = 960 - margin.left - margin.right,height = 500 - margin.top - margin。 bottom; var color = d3.scale.category20c(); var treemap = d3.layout.treemap()。size([width,height])。stemy(true).value(function(d){return d.size; }); var div = d3.select(body)。append(div)。style(position,relative)。style(width,(width + margin.left + margin.right) +px)。style(height,(height + margin.top + margin.bottom)+px)。style(left,margin.left +px)。style(top, margin.top +px); var url =http://www.mocky.io/v2/5491ee0450e288460f8b77a5\";var dispatcher = d3.dispatch('jsonLoad'); d3.select('#loadData')。在('CLIC k',function(){d3.json(url,callback);}); //可选的dispatcherdispatcher.on('jsonLoad',function(data){//触发afer json被加载(只是如果你想做额外的这里有东西。)console.log(data);}); var callback = function(error,root){dispatcher.jsonLoad(root); //可以触发新数据在此处的事件var node = div.datum(root).selectAll(。node)。data(treemap.nodes).enter()。append(div)。attr( class,node)。call(position).style(background,function(d){return d.children?color(d.name):null;})。text(function(d){return d .children?null:d.name;}); d3.selectAll(input)。on(change,function change(){var value = this.value ===count?function(){return 1;}:function(d){return d。 size;}; node.data(treemap.value(value).nodes).transition()。duration(1500).call(position);});函数position(){this.style(left,function(d){return dx +px;}} .style(top,function(d){return dy +px;}} .style(width,function(d){return Math.max(0,d.dx - 1)+px;}} .style(height,function(d){return Math.max(0 ,d.dy - 1)+px;});}
body {font-family:Helvetica Neue,Helvetica,Arial,sans-serif;保证金:自动;位置:相对; width:960px;} form {position:absolute;右:10px; top:10px;}。node {border:solid 1px white;字体:10px sans-serif; line-height:12px;溢出:隐藏;位置:绝对; text-indent:2px;}
< script src = https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js\"></script><form> < label>< input type =radioname =modevalue =sizechecked =true/>尺寸和LT; /标签> < label>< input type =radioname =modevalue =count/>计算< / label>< / form>< button id =loadData>加载数据< / button>
I am working on this d3JS example for creating a treemap. The example uses flare.json as a file to contain the json data.
I however want this json data to be sent from my python flask application and loaded into javascript.
This is how the JSON is currently loaded from flare.json file:
d3.json("flare.json", function(error, root) {
var node = div.datum(root).selectAll(".node")
.data(treemap.nodes)
.enter().append("div")
.attr("class", "node")
.call(position)
.style("background", function(d) { return d.children ? color(d.name) : null; })
.text(function(d) { return d.children ? null : d.name; });
d3.selectAll("input").on("change", function change() {
var value = this.value === "count"
? function() { return 1; }
: function(d) { return d.size; };
node
.data(treemap.value(value).nodes)
.transition()
.duration(1500)
.call(position);
});
});
I want to modify this somehow and achieve something like this:
// Load the data.
var callback = function(data, error, root) {
var node = div.datum(root).selectAll(".node")
.data(treemap.nodes)
.enter().append("div")
.attr("class", "node")
.call(position)
.style("background", function(d) { return d.children ? color(d.name) : null; })
.text(function(d) { return d.children ? null : d.name; });
d3.selectAll("input").on("change", function change() {
var value = this.value === "count"
? function() { return 1; }
: function(d) { return d.size; };
node
.data(treemap.value(value).nodes)
.transition()
.duration(1500)
.call(position);
});
};
d3.json("/data", callback);
This currently does not work for me.
On my app.py file, this is some code that I have:
app = flask.Flask(__name__)
@app.route("/")
def index():
"""
When you request the root path, you'll get the index.html template.
"""
return flask.render_template("index.html")
@app.route("/data")
@app.route("/data/<int:ndata>")
def data():
d3js_chart_data = json.dumps(
{ //JSON here }
)
return d3js_chart_data
if __name__ == "__main__":
import os
port = 80
# Open a web browser pointing at the app.
os.system("open http://localhost:{0}".format(port))
# Set up the development server on port 8000.
app.debug = True
app.run(host='0.0.0.0', port=port)
I think you only have to add the url to your server in d3.json(url, function(...)
and it should work for you. There is no need to do a separate callback, but you can do it with a separate callback if you like.
In your callback I think you don't need to add the data
parameter because the data are in root.
(If you're requesting the data from a different site, the server needs to enable CORS to allow cross-origin requests.)
Please find a working demo with data from mocky.io below. It's exactly the code from the treemap demo, just the data are from a different location and loaded after a button click with a callback.
You can find the same also here at jsFiddle.
var margin = {
top: 40,
right: 10,
bottom: 10,
left: 10
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var color = d3.scale.category20c();
var treemap = d3.layout.treemap()
.size([width, height])
.sticky(true)
.value(function (d) {
return d.size;
});
var div = d3.select("body").append("div")
.style("position", "relative")
.style("width", (width + margin.left + margin.right) + "px")
.style("height", (height + margin.top + margin.bottom) + "px")
.style("left", margin.left + "px")
.style("top", margin.top + "px");
var url = "http://www.mocky.io/v2/5491ee0450e288460f8b77a5";
var dispatcher = d3.dispatch('jsonLoad');
d3.select('#loadData').on('click', function() {
d3.json(url, callback);
});
// optional dispatcher
dispatcher.on('jsonLoad', function(data) {
// triggered afer json is loaded (just if you want to do additional stuff here.)
console.log(data);
});
var callback = function (error, root) {
dispatcher.jsonLoad(root); // can trigger an event that new data are here
var node = div.datum(root).selectAll(".node")
.data(treemap.nodes)
.enter().append("div")
.attr("class", "node")
.call(position)
.style("background", function (d) {
return d.children ? color(d.name) : null;
})
.text(function (d) {
return d.children ? null : d.name;
});
d3.selectAll("input").on("change", function change() {
var value = this.value === "count" ? function () {
return 1;
} : function (d) {
return d.size;
};
node.data(treemap.value(value).nodes)
.transition()
.duration(1500)
.call(position);
});
};
function position() {
this.style("left", function (d) {
return d.x + "px";
})
.style("top", function (d) {
return d.y + "px";
})
.style("width", function (d) {
return Math.max(0, d.dx - 1) + "px";
})
.style("height", function (d) {
return Math.max(0, d.dy - 1) + "px";
});
}
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: auto;
position: relative;
width: 960px;
}
form {
position: absolute;
right: 10px;
top: 10px;
}
.node {
border: solid 1px white;
font: 10px sans-serif;
line-height: 12px;
overflow: hidden;
position: absolute;
text-indent: 2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<form>
<label><input type="radio" name="mode" value="size" checked="true" /> Size</label>
<label><input type="radio" name="mode" value="count"/> Count</label>
</form>
<button id="loadData">Load data</button>
这篇关于如何使用python flask应用程序在d3js图表中动态加载json数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!