tl;dr: you cannot manipulate the JSON using the progress
event.
First of all, you are probably using d3.request (D3 v3 and v4), not d3.fetch (D3 v5). That's an important difference because in both microlibraries the method has the same name, which is d3.json
. However, d3.json
is a XMLHttpRequest in the former, while it is a Promise in the latter.
Second, which is the most important, this seems to be (unfortunately) an XY problem. You said "I'd like to draw them as they arrive in order to favor interactivity and spare memory", but the problem is that you can't: even if you could manipulate the data while it arrives (and you can't, see below) D3 will only start drawing anything after the XHR (or the Promise) finishes downloading the data. That means that, with 50MB of data, the user will stare at a blank page for several seconds... So, the best advice here is re-thinking the size of the data file and the whole datavis.
Back to the question:
The progress
event is used just to monitor the progress. According to the W3 Consortium:
This specification defines an event interface — ProgressEvent — that can be used for measuring progress. (emphasis mine)
We can check this in the following demo (I'm using an array with the objects you shared in your question, I just copy/pasted the same objects several times). We can use srcElement.response
to see the loaded JSON, but we cannot change it:
d3.json("https://api.myjson.com/bins/1d7yoi")
.on("progress", function(d) {
console.log(d.srcElement.response)
})
.on("load", function() {
console.log("done")
})
.get()
<script src="https://d3js.org/d3.v4.min.js"></script>
For instance, you can see that in this silly attempt to change anything in the string, nothing is changed:
d3.json("https://api.myjson.com/bins/1d7yoi")
.on("progress", function(d) {
d.srcElement.response[0] = "foo";
console.log("First character is: " + d.srcElement.response[0])
})
.on("load", function(data) {
console.log("JSON:" + JSON.stringify(data))
})
.get()
<script src="https://d3js.org/d3.v4.min.js"></script>