Reputation: 3573
I have this messy and ugly nested json parse calls(!!) which I am trying to simplify, I was hoping with d3.queue. The first json is used by function doFirstChart
to do a chart after some basic typesetting. The function makes the chart and also returns some extra data which are used together with the second json file and another user-defined parameter by the function doSecondChart
to do the next chart.
var c = 'someValue'
d3.json(countryJson, function (data) {
data.forEach(function (d) {
d.Country_Num = +d.Country_Num
d.y = +d.Y
d.x = +d.X
});
dataOut = doFirstChart(data);
d3.json(salesJson, function (salesData) {
salesData.forEach(function (d) {
d.Expt = +d.Expt
d.x = +d.x
d.y = +d.y
});
doSecondChart(dataOut, salesData, c)
console.log("Done!!")
});
});
It sounds like d3.queue
is the appropriate tool for these situations, I have failed however to make it work even with a simplified example. For example (ignoring the exta parameter c
) the following I was hoping to do trick but obviously I am not using it correctly.
d3.queue()
.defer(d3.json, 'path\to\country\data')
.await(doFirstChart)
.defer(d3.json, 'path\to\sales\data')
.await(doSecondChart)
I dont even get right the simplest of all:
d3.queue()
.defer(d3.json, 'path\to\country\data')
.await(doFirstChart)
How is this working please?
Upvotes: 1
Views: 2669
Reputation: 2012
Using Defer after await is throwing you an error, change this:
d3.queue()
.defer(d3.json, 'path\to\country\data')
.await(doFirstChart)
.defer(d3.json, 'path\to\sales\data')
.await(doSecondChart)
To this:
d3.queue()
.defer(d3.json, 'path\to\country\data')
.defer(d3.json, 'path\to\sales\data')
.await(splitCharts)
Where the function splitCharts(err, ...args)
is either:
function splitCharts(err, ...charts){
doFirstChart(charts[0]);
doSecondChart(charts[1]);
}
The problem you were having was using defer after and await, and probably your function parameters, where you were not expecting (err, ...args) as parameters.
This example will console.log
the queue process, so you can work your way from there:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="https://d3js.org/d3-queue.v3.min.js"></script>
</head>
<body>
<script>
function doFirstChart(err, ...args) {
console.log('[FUNC]: ', args);
}
d3.queue()
.defer(d3.json, 'https://gist.githubusercontent.com/GbalsaC/db387adae4e84e999960ef79267ceada/raw/0cf2b08280452c7dbb04f81fafcb304bb841bc36/test1.json')
.defer(d3.json, 'https://gist.githubusercontent.com/GbalsaC/db387adae4e84e999960ef79267ceada/raw/0cf2b08280452c7dbb04f81fafcb304bb841bc36/test1.json')
.await(doFirstChart)
</script>
</body>
</html>
Note:
If you want to pass a custom parameter to the .await()
callback, you have to define doFirstChart
function as such:
function doFirstChart(myParam){
// Now you'll return an anonymous function as first step
return (err, ...args) => {
// Here you'll do your thing, like rendering the data
console.log('My Param: ', myParam); // Your Custom param
console.log('[FUNC]: ', args); // As before
}
}
So, now you can change the <script></script>
tag to:
<script>
const paramTest = 'Testa Rossa';
function doFirstChart(myParam) {
return (err, ...args) => {
console.log('My Param: ', myParam);
console.log('[FUNC]: ', args);
}
}
d3.queue()
.defer(d3.json, 'https://gist.githubusercontent.com/GbalsaC/db387adae4e84e999960ef79267ceada/raw/0cf2b08280452c7dbb04f81fafcb304bb841bc36/test1.json')
.defer(d3.json, 'https://gist.githubusercontent.com/GbalsaC/db387adae4e84e999960ef79267ceada/raw/0cf2b08280452c7dbb04f81fafcb304bb841bc36/test1.json')
.await(doFirstChart(paramTest)) // do a first param declaration
</script>
Upvotes: 4