问题
I am trying to load a CSV data and plot graphs based on the returned data.I could see the data when logged to the console, but it does not get plotted in the graph. When I replaced the data copied from the console with the function written to return the data, the graph get plotted. I dont know what I am missing.
my code looks like this
// Options and Data definitions
declare let d3, nv: any;
export const ChartTypes = [
'lineChart',
'discreteBarChart'
];
const color = d3.scale.category20()
export const AllOptions = {
discreteBarChart: {
chart: {
type: 'discreteBarChart',
height: 450,
margin : {
top: 20,
right: 20,
bottom: 50,
left: 55
},
x: function(d){return d.label;},
y: function(d){return d.value;},
showValues: true,
valueFormat: function(d){
return d3.format(',.4f')(d);
},
duration: 500,
xAxis: {
axisLabel: 'X Axis'
},
yAxis: {
axisLabel: 'Y Axis',
axisLabelDistance: -10
}
}
}
}
Getting data into the object
export const AllData = {
// populate the empty object with your data
discreteBarChart: getCsvData()
}
The getCsvData() function that gets the data from the csv looks like this:
function getCsvData(){
d3.csv("app/test.csv", function(error, data){
var dynamicData = data;
console.log(data)
// create an empty object that nv is expecting
var discreteBarChart = [
{
key: "Cumulative Return",
values: []
}
];
data.forEach(function (d){
d.value = +d.value
discreteBarChart[0].values.push(d)
})
console.log('The data is'+JSON.stringify(discreteBarChart))
})
return discreteBarChart
}
I got undefined when I attempted to do an alert of the function like this
alert(JSON.stringify(getCsvData()))
I suspect the problem is, I put the returned statement in the wrong place.
回答1:
The problem is that you are trying to use the asynchronous d3.csv()
function in a synchronous way. When you call return discreteBarChart
it immediately returns undefined
without waiting for you data request to finish. By the time your data comes back, you aren't passing it anywhere.
You either need to make your getCsvData()
function accept a callback for it to call when the data loads, or use JavaScript Promises, which I think would be a better solution.
Using promises, your code could look something like this:
function getCsvData() {
return new Promise(function(resolve, reject) {
d3.csv("app/test.csv", function(error, data) {
var discreteBarChart = [{
key: "Cumulative Return",
values: []
}];
data.forEach(function(d) {
d.value = +d.value
discreteBarChart[0].values.push(d)
});
resolve(discreteBarChart);
});
});
}
getCsvData().then(function(data) {
// Use the data here to render your chart
});
来源:https://stackoverflow.com/questions/40709470/how-to-use-dynamic-csv-data-for-visualisation-with-nvd3-and-angular2