在 d3 JavaScript 中读取外部数据 - 一个 R r2d3 用例

Reading in external data in d3 JavaScript - an R r2d3 Use Case

编辑:link 用于示例中使用的所有 data/code:https://drive.google.com/open?id=16MpDptwV7m4nOkoT3ImlKffl4rYqc5ms

各位朋友和烘焙师大家好,

我是 D3 可视化方面的新手。我的背景全是 Plotly 和集成的 R 平台绘图。我为 Shiny 应用程序编写了非常 非常 轻 js/css,但我正在尝试扩展到更多自定义和免费的视觉方法。

因此,我一直在深入研究 R 中用于 d3 集成的 r2d3 包。我搜索了所有示例,并仔细阅读了我可以在此处的主存储库和概述页面中找到的任何文档:https://rstudio.github.io/r2d3/articles/gallery/calendar/

但是,对于我来说,我根本无法理解 js 实际上是如何提取数据的

这里有一个示例:视觉效果,后面是生成它的脚本,最后是作为数据源提供的 csv 以进行可视化

视觉:

calendar.js 脚本:

// !preview r2d3 data = read.csv("dji-latest.csv"), d3_version = 4, 

container = "div", options = list(start = 2006, end = 2011)

// Based on https://bl.ocks.org/mbostock/4063318

var height = height / (options.end - options.start),
    cellSize = height / 8;

var formatPercent = d3.format(".1%");

var color = d3.scaleQuantize()
    .domain([-0.05, 0.05])
    .range(["#a50026", "#d73027", "#f46d43", "#fdae61", "#fee08b", "#ffffbf", "#d9ef8b", "#a6d96a", "#66bd63", "#1a9850", "#006837"]);

var svg = div
  .style("line-height", "0")
  .selectAll("svg")
  .data(d3.range(options.start, options.end))
  .enter().append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + cellSize * 3.5 + "," + (height - cellSize * 7 - 1) + ")");

svg.append("text")
    .attr("transform", "translate(-" + (6 * height / 60) + "," + cellSize * 3.5 + ")rotate(-90)")
    .attr("font-family", "sans-serif")
    .attr("font-size", 2 + 8 * height / 60)
    .attr("text-anchor", "middle")
    .text(function(d) { return d; });

var rect = svg.append("g")
    .attr("fill", "none")
    .attr("stroke", "#ccc")
    .attr("stroke-width", "0.25")
  .selectAll("rect")
  .data(function(d) { return d3.timeDays(new Date(d, 0, 1), new Date(d + 1, 0, 1)); })
  .enter().append("rect")
    .attr("width", cellSize)
    .attr("height", cellSize)
    .attr("x", function(d) { return d3.timeWeek.count(d3.timeYear(d), d) * cellSize; })
    .attr("y", function(d) { return d.getDay() * cellSize; })
    .datum(d3.timeFormat("%Y-%m-%d"));

svg.append("g")
    .attr("fill", "none")
    .attr("stroke", "#000")
    .attr("stroke-width", "0.25")
  .selectAll("path")
  .data(function(d) { return d3.timeMonths(new Date(d, 0, 1), new Date(d + 1, 0, 1)); })
  .enter().append("path")
    .attr("d", pathMonth);

r2d3.onRender(function(csv, div, width, height, options) {
  var data = d3.nest()
      .key(function(d) { return d.Date; })
      .rollup(function(d) { return (d[0].Close - d[0].Open) / d[0].Open; })
    .object(csv);

  rect.filter(function(d) { return d in data; })
      .attr("fill", function(d) { return color(data[d]); })
    .append("title")
      .text(function(d) { return d + ": " + formatPercent(data[d]); });
});

function pathMonth(t0) {
  var t1 = new Date(t0.getFullYear(), t0.getMonth() + 1, 0),
      d0 = t0.getDay(), w0 = d3.timeWeek.count(d3.timeYear(t0), t0),
      d1 = t1.getDay(), w1 = d3.timeWeek.count(d3.timeYear(t1), t1);
  return "M" + (w0 + 1) * cellSize + "," + d0 * cellSize
      + "H" + w0 * cellSize + "V" + 7 * cellSize
      + "H" + w1 * cellSize + "V" + (d1 + 1) * cellSize
      + "H" + (w1 + 1) * cellSize + "V" + 0
      + "H" + (w0 + 1) * cellSize + "Z";
}

这是输入的 .csv

而且我知道这完全是我自己对js函数调用和数据处理理解的来源,但这简直让我无所适从。我可以在其中看到一些 .data inits 和函数调用,但我在哪里找不到任何关于此可视化应该捕获什么的指示。它如何知道哪一列表示日期?指定实际 visualize 的变量在哪里?

如有任何帮助,我们将不胜感激。我已经获得了一些 d3 教程,但任何指示至少可以让我玩那些比我构建的更智能的沙箱:)

谢谢!

我知道它是旧的 post...但我最终来到这里,我认为写一些东西以供进一步参考可能是个好主意。

How does it know which of the columns denotes the dates? Where is the variable specified to actually visualize?

这个例子对初学者来说有点棘手(或者至少是误导),但是指定 variables/dates 的代码片段是这个:

var data = d3.nest()
      .key(function(d) { return d.Date; })
      .rollup(function(d) { return (d[0].Close - d[0].Open) / d[0].Open; })
    .object(csv);

您可以看到 d3.nest 的具体作用 here。简而言之,R 通过将 dji-latest.csv 中的 table 转换为 js 友好对象,将 data 变量(在 js 端命名为 csv)传递给 js,例如(在 R 语法中):

data <- list(
  list(Date = "2010-10-01", Open = 10789.72, High = ...),
  list(Date = "2010-09-30", Open = 10789.72, High = ...),
) 

然后通过 d.Datesd.Closed.Openkeyrollup 函数定义中选择特定变量。

注意上面函数中的csv指的是R传过来的data,因为它默认是r2d3.onRender里面函数的第一个参数,可能就是混乱的来源。在 js 端 csv 被馈送到 nest 以生成此特定可视化所需的嵌套数据对象。

正如其他人所说,没有比阅读文档更好的解释了,这个例子非常简单。