如何使用python flask应用程序在d3js图表中动态加载json数据 [英] how to dynamically load json data in d3js chart using python flask application

查看:145
本文介绍了如何使用python flask应用程序在d3js图表中动态加载json数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发这个用于创建树形图的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆