D3中是否有基本功能/对象允许"在线"日志记录?
我正在阅读Scott Murry的精彩D3书并希望这样做:
d3.select("body").selectAll("div")
.log("body")
.data(dataset)
.log("data")
.enter()
.log("enter")
.append("div")
.log("div")
.attr("class", "bar")
.log("class");
我目前正在做这件可怕的事情:
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
答案 0 :(得分:3)
你可以通过修改d3选择原型来使用你的解决方案(而不是对象原型,我不认为这可以被认为是"可怕的" - 虽然我不是很偏在内部搞乱d3),但我觉得你在寻找selection.call()
。
如果您想访问当前选择但不是中断方法链接,selection.call
可能是您最好的选择:
只调用指定的函数一次,传入此选择 以及任何可选参数。返回此选择。 (docs)
被调用函数的第一个参数是选择,其他可选参数可以在调用方法本身中传递。一般形式是:
selection.call(func, arg, arg, ...)
function func(selection, arg, arg, ...) {}
使用selection.call
进行日志记录不应该太难以使用此方法。这是一个快速模拟(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);
}
结果:
Here's模拟行动。
答案 1 :(得分:3)
我想到的第一件事是Andrew Reid在answer使用selection.call()
时提出的方法。虽然这个解决方案很好,但我认为可以通过直接扩展D3的选择来改进。 d3.selection()
明确指出的文档声明此函数可用于扩展选择原型。
您可以按照以下方式创建自己的记录器:
const logger = {
log() {
console.log(...arguments);
return this;
}
}
这可以在d3.selection.prototype
:
Object.assign(d3.selection.prototype, logger);
简单方法logger.log()
只记录传递给控制台的所有参数,并通过返回this
来引导方法链接,const logger = {
log() { // Generic method logging all arguments.
console.log(...arguments);
return this;
},
logMsg(msg) { // Logging just a simple msg.
console.log(msg);
return this;
},
logSel() { // Log the selection.
console.log(this);
return this;
},
logAttr(name) { // Log the attributes with "name" for all selected elements.
this.each(function(d, i) {
let attr = d3.select(this).attr(name);
console.log(`Node ${i}: ${name}=${attr}`);
});
return this;
},
logData() { // Log the data bound to this selection.
console.log(this.data());
return this;
},
logNodeData() { // Log datum per node.
this.each(function(d, i) {
console.log(`Node ${i}: ${d}`);
});
return this;
}
};
Object.assign(d3.selection.prototype, logger);
d3.select("body")
.logMsg("Start")
.append("svg").selectAll(null)
.log(1, {}, "Test")
// .logSel() // this doesn't work well in Stack snippets
.data([1,2])
.enter().append("circle")
.attr("r", "10")
.logAttr("r")
.logData()
.logNodeData()
.logMsg("End");
引用选择本身。
当然,人们可以很容易地想象出更多有用的日志记录方法来打印属性,选择,数据等等。以下演示扩展了基本概念:
<script src="https://d3js.org/d3.v5.js"></script>
myButton
答案 2 :(得分:1)
要记录链中的数据,可以使用假属性:
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("fake", d=> console.log(d));
对于其他事情,我不认为有一个&#34; d3&#34;允许记录和悲伤的方式,我认为你必须以正常的方式做到这一点:
console.log(d3.select("body").selectAll("div").data(dataset).enter());