![](/img/trans.png)
[英]Once I put a function into defer() in D3, the data structure inside console.log changed in other function
[英]D3 console.log in a function chain
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
要記錄鏈中的數據,可以使用偽屬性:
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("fake", d=> console.log(d));
對於其他事情,我不認為有一種“d3”方式允許記錄和遺憾,我認為你必須以正常的方式做到:
console.log(d3.select("body").selectAll("div").data(dataset).enter());
您可以通過修改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);
}
結果如下:
這是模擬的行動。
我想到的第一件事是Andrew Reid在回答中使用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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.