Is there a base function/object in D3 which would allow "in-line" logging?
I'm reading Scott Murry's nifty D3 book and want to do this:
d3.select("body").selectAll("div")
.log("body")
.data(dataset)
.log("data")
.enter()
.log("enter")
.append("div")
.log("div")
.attr("class", "bar")
.log("class");
I currently do this Horrible Thing:
const log = function (msg, val) {
const data = val ? val : this
const label = msg ? msg : "data:"
console.log(label, data)
return data
}
Object.prototype.log = log
This works fine, producing this clickable console output: But .. What is the D3 way to do this?
data() returns the values from the array it's been passed, we can use these values to change attributes and styles for SVG elements with a method chain. NOTE: It's possible to use . data() for changing other elements, but we'll focus on SVG. D3 can change the radius by using values from from an array radiusData.
We can load a csv file or csv data using d3. csv() method.
console. log specifically is a method for developers to write code to inconspicuously inform the developers what the code is doing. It can be used to alert you that there's an issue, but shouldn't take the place of an interactive debugger when it comes time to debug the code.
select() function in D3. js is used to select the first element that matches the specified selector string. If any element is not matched then it returns the empty selection. If multiple elements are matched with the selector then only the first matching element will be selected.
For logging datas in your chain, you can just use a fake attribute :
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("fake", d=> console.log(d));
For the other things, I don't think there is a "d3" way which allows to log and sadly, I think you have to do it with a normal way :
console.log(d3.select("body").selectAll("div").data(dataset).enter());
You could use your solution by modifying the d3 selection prototype (as opposed to the object prototype, I don't think that could be considered "horrible" - though I'm a little partial to messing with d3 internally), but I feel you are looking for selection.call()
.
If you want to access the current selection, but not interrupt method chaining, selection.call
is probably your best bet:
Invokes the specified function exactly once, passing in this selection along with any optional arguments. Returns this selection. (docs)
The called function's first parameter will be the selection, further optional parameters can be passed in the call method itself. The general form is:
selection.call(func, arg, arg, ...)
function func(selection, arg, arg, ...) {}
Using selection.call
for logging shouldn't be too hard to rig up with this method. Here's a quick mock up (v4/5):
var dataset = d3.range(10);
d3.select("body").selectAll("div")
.call(log,"body")
.data(dataset)
.call(log,"dataset")
.enter()
.call(log,"enter")
.append("div")
.call(log,"div")
.attr("class", "bar")
.call(log,"bar");
function log(sel,msg) {
console.log(msg,sel);
}
And the results:
Here's the mock up in action.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With