简体   繁体   中英

Problems accessing d3.json object through queue on a flask server

At work I got an assigment to do a very simple report. In fact, so ridiculously simple that I decided to up the difficulty rating and make it a interactive chart report using dc.js, on a flask server. The kicker here is that I have never touched Flask, dc.js, d3, crossfilter, or javascript for that matter... (Yes; stupid is, stupid does)

What made me go for it was a tutorial , that laid everything out so understandably, and tempting.

So now I am here, sweating due to the time pressure, trying to get data generated at the back with pandas, over to the front-end. The code from the tutorial is as follows;

queue()
.defer(d3.json, "/donorschoose/projects")
.defer(d3.json, "static/geojson/us-states.json")
.await(makeGraphs);

function makeGraphs(error, projectsJson, statesJson) {

//Clean projectsJson data
var donorschooseProjects = projectsJson;
var dateFormat = d3.time.format("%Y-%m-%d");
donorschooseProjects.forEach(function(d) {
    d["date_posted"] = dateFormat.parse(d["date_posted"]);
    d["date_posted"].setDate(1);
    d["total_donations"] = +d["total_donations"];
});

Following the monkey see monkey do principle (the monkey has been using the last couple of hours googling, trying to get an understanding of what is happening, but to no avail), my code is as follows;

queue()
.defer(d3.json, "/salgshisto")
.await(makeGraphs);

function makeGraphs(error, salgsData) {

var salgsTransaksjonene = salgsData;
var dateFormat = d3.time.format("%Y-%m-%d %H:%M:%S");
salgsTransaksjonene.forEach(function(d) {
    d["InvoiceDate"] = dateFormat.parse(d["InvoiceDate"]);
    d["InvoiceDate"].setDate(1);
    d["TotalAmount"] = +d["TotalAmount"];
});

This leads to the following error in the safari console;

TypeError: undefined is not a function (evaluating 'salgsTransaksjonene.forEach')

And the last piece of info; The flask app.py file, has a

@app.route("/salgshisto")
def betHisto():
    ....
    creating FO = pandas.DataFrame object 
    ....

   return FO.to_json(orient='index', date_format='iso', date_unit='s', force_ascii=False)

Also, the console shows an object, which is the .json data, I can see that since I can span out the object's object elements, and see the info from the pandas Dataframe. So; The info makes it across, but it does not look like it gets to the makeGraphs function and the salgsTransaksjonene selector.

I just cannot understand what the typeError is, so if anyone has any idea, I would be very grateful!

Edit 2:

@Mark thank you for replying!! I implemented the d3.json() you supplied like so;

var salgsData = d3.json("/salgshisto", function(error, json) { if (error) return console.warn(error);}); 

function makeGraphs(salgsData) {.....

There are now, no error messages either in the Flask server, or the chrome / safari console. So the code seems to be executing now. But it is not behaving as expected. The rest of the code does not return what I expect - a rowChart:

var salgsData = d3.json("/salgshisto", function(error, json) { if (error) return console.warn(error);}); 

function makeGraphs(salgsData) {

//  var salgsData = d3.json.loads("/salgshisto");

//klargjoer salgsData
var salgsTransaksjonene = salgsData;
var dateFormat = d3.time.format("%Y-%m-%dT%H:%M:%SZ");
salgsTransaksjonene.forEach(function(d) {
    d["InvoiceDate"] = dateFormat.parse(d["InvoiceDate"]);
    d["InvoiceDate"].setDate(1);
    d["TotalAmount"] = +d["TotalAmount"];
});

//Create a Crossfilter instance
var ndx = crossfilter(salgsTransaksjonene);

//Define Dimensions
var kundeDim = ndx.dimension(function(d) { return d["CustomerName"]; });
//var betingelseDim = ndx.dimension(function(d) { return d["Name"]; }); 

//Calculate metrics
var OmsetningKunder = kundeDim.group().reduceSum(function(fact) { return fact.TotalAmount;});

//Charts
var resourceTypeChart = dc.rowChart("#topp-20-row-chart");

resourceTypeChart
    .width(300)
    .height(600)
    .dimension(kundeDim)
    .group(OmsetningKunder)
    .xAxis().ticks(4);

dc.renderAll();

};

I can see from the server log that "/salgshisto" is being called.

The corresponding bootstrap keen.io template has the correct <div id="topp-20-row-chart"></div> added.

Concerning the .json data. I am wondering how to transmit it to you. I cannot get the same info, laying out the object, in the javascript console anymore. Best I can do I guess is copying the response from running ".../salgshisto" url in the browser. That returns the entire list. The only problem then is that the text is uff-8 which I cannot get it printed as. So here is the first two entries, as unicode; {"0":{"InvoiceDate":"2011-04-04T00:00:00Z","CustomerName":"M\e\c\h\a\n\i\c\a\ \A\S\","Name":"Netto per 30 dager","TotalAmount":14689.74},"1":{"InvoiceDate":"2011-04-07T00:00:00Z","CustomerName":"H\e\l\l\a\n\d\ \M\e\k\.\ \V\e\r\k\s\t\e\d\","Name":"Netto per 30 dager","TotalAmount":3705.0},...}

@Mark Thank you so much for all your help. It turned out that you were right; It was the .json that was mal-formed. For all that come after me using pandas, please note that the correct orient for .json, at least as far as d3 and cross filter is concerned; orient='records' is correct. not orient='index'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM