Я полностью новичок в Flask, и я пытаюсь понять, как отображать данные в формате gridx с помощью макетов d3js force. Вот соответствующий код Python:Передача данных JSON от сервера к клиенту с Flask
@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("/thread")
def get_graph_data(thread_id: int=3532967):
"""
returns json of a network graph for the specified thread
:param thread_id:
:return:
"""
pqdict, userdict = graphs.get_post_quote_dict(thread_id)
G = graphs.create_graph(pqdict)
s = graphs.graph_to_node_link(G, remove_singlets=True) # returns dict
return flask.jsonify(s)
А вот файл index.html:
<!DOCTYPE html>
<html>
<head>
<title>Index thing</title>
<script type="text/javascript" src="http://d3js.org/d3.v2.js"></script>
<link type="text/css" rel="stylesheet" href="templates/graph.css"/>
</head>
<body>
<div id="chart"></div>
<script>
var w = 1500,
h = 1500,
fill = d3.scale.category20();
var vis = d3.select("#chart")
.append("svg:svg")
.attr("width", w)
.attr("height", h);
d3.json("/thread", function (json) {
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.nodes(json.nodes)
.links(json.links)
.size([w, h])
.start();
var link = vis.selectAll("line.link")
.data(json.links)
.enter().append("svg:line")
.attr("class", "link")
.style("stroke-width", function (d) {
return Math.sqrt(d.value);
})
.attr("x1", function (d) {
return d.source.x;
})
.attr("y1", function (d) {
return d.source.y;
})
.attr("x2", function (d) {
return d.target.x;
})
.attr("y2", function (d) {
return d.target.y;
});
var node = vis.selectAll("circle.node")
.data(json.nodes)
.enter().append("svg:circle")
.attr("class", "node")
.attr("cx", function (d) {
return d.x;
})
.attr("cy", function (d) {
return d.y;
})
.attr("r", 5)
.style("fill", function (d) {
return fill(d.group);
})
.call(force.drag);
vis.style("opacity", 1e-6)
.transition()
.duration(1000)
.style("opacity", 1);
force.on("tick", function() {
link.attr("x1", function (d) {
return d.source.x;
})
.attr("y1", function (d) {
return d.source.y;
})
.attr("x2", function (d) {
return d.target.x;
})
.attr("y2", function (d) {
return d.target.y;
});
node.attr("cx", function (d) {
return d.x;
})
.attr("cy", function (d) {
return d.y;
});
});
});
</script>
</body>
</html>
Так ясно d3.json() функция хочет расположение статического файла JSON, который в в этом случае я пытаюсь генерировать динамически на основе URL-адреса запроса.
Я пробовал около десятка подходов, которые я нашел здесь. За ниже предложение, я попробовал:
@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("/thread")
def get_graph_data():
"""
returns json of a network graph for the specified thread
:param thread_id:
:return:
"""
thread_id = request.args.get("thread_id", 3532967, type=int)
pqdict, userdict = graphs.get_post_quote_dict(thread_id)
G = graphs.create_graph(pqdict)
s = graphs.graph_to_node_link(G, remove_singlets=True)
return jsonify(s)
с шаблоном index.html без изменений, и переходите к «http://localhost/thread?thread_id=12345», но это не удалось, потому что это была печать JSON для ID 12345 на странице вместо рендеринга JavaScript.
Итак, моя текущая цель - указать параметр в методе Python из URL («.../showgraph? Threadid = whatever ...»), сгенерировать json в коде Python и передайте его обратно в html/js. Как это сделать?
Итак, из того, что вы говорите, я собираю, что d3.json() принимает URL (то есть статический файл или что-то из REST API), но для этого мне нужно будет вызвать отдельный метод как-то на самом деле сделать шаблон, не так ли? Я попробовал версию (чуть измененную - 'request.args.get' вместо' request.get') вашего первого предложения фрагмента, но он просто печатает необработанный JSON на странице вместо рендеринга JS. Это была другая проблема, с которой я столкнулся несколько раз ... – stuart
да, это асинхронный метод, поэтому принимает любой допустимый URL-адрес http. Request.get был ошибкой, хорошим уловом. Можете ли вы более подробно объяснить, что происходит? Возможно, еще больше кода. – abigperson
Я вложил почти весь свой код целиком (пропущенный импорт и бит «if __name__ ==» __main__ »), и я думаю, что я мог бы сделать что-то не так в моем подходе ... когда я иду на url' [ domain]/thread? thread_id = 12345', он делает все необходимое, но буквально печатает {«источник»: 1, «target»: 2} и т. д. на странице вместо рендеринга этого JSON. Может быть, я не должен идти прямо к URL? – stuart