D3 console.log在一个功能链中

时间:2018-04-12 16:56:10

标签: javascript debugging d3.js console.log

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

这很好用,产生这个可点击的控制台输出: enter image description here 但是...... D3的方法是什么?

3 个答案:

答案 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);
}

结果:

enter image description here

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());