如何使用jsdom,D3和IJavascript

时间:2017-04-19 06:51:36

标签: javascript node.js dom d3.js jupyter-notebook

我在前端开发方面不强,但最近我玩弄了很多Javascript和D3。习惯于使用Jupyter Notebooks在Python中进行科学分析,我认为应该可以使用类似的工作流来使用带有JS内核的Jupiter笔记本中的JS代码来使用D3开发科学可视化。我查看过n-riesco IJavascript project这似乎很有希望,但在尝试导入D3时,笔记本会出错:

// npm install d3
var d3 = require('d3');

引发

ReferenceError: document is not defined

我猜这是因为Jupyter环境中没有DOM(because Mike Bostock says so)。事实上,如果我导入jsdom,D3也会成功导入。真棒!但是,现在,我无法选择任何东西,因为,我猜是因为在Jupyter环境中没有什么可以选择的。

我想做的事情是:

$$svg$$ = "<svg><rect width=1000 height=1000/></svg>";
var svg = d3.select("svg")
// Beautiful D3 code

或者(不太酷但也有利),获得对某些本地服务器的DOM的引用,然后我可以通过在笔记本中执行代码来操作。


更新

随着Observable的引入,不再需要在Jupyter笔记本中使用JavaScript。 Observable是一个非常棒的JavaScript笔记本环境,几乎可以做任何事情。例如,当我提出这个问题时我想做的事情可以简单地完成:

enter image description here

2 个答案:

答案 0 :(得分:5)

让我先给出一个工作示例(在ijavascript@5.0.19jsdom@9.12.0d3@4.8.0上测试),然后进行一些澄清:

var jsdom = require("jsdom");
global.document = jsdom.jsdom();

var d3 = require("d3");

var svg = d3.select(document.body).append("svg");

svg.append("rect")
    .attr("width", 80)
    .attr("height", 80)
    .style("fill", "orange");

$$.svg(svg.node().outerHTML);

screenshot from 2017-04-20 09-32-53

此解决方案:

  • 使用jsdom提供的DOM。

  • 使用d3创建<svg>节点并附加<rect>

  • 使用outerHTML获取前面步骤中创建的<svg>节点的字符串表示

  • 最后指示IJavascript将此字符串作为SVG结果返回到Jupyter笔记本。

理论上,IJavascript可以将javascript代码注入Jupyter笔记本(以操纵其DOM),但此代码可能无法运行(取决于Jupyter前端的安全策略)。

由于您的兴趣是科学分析,您可能对我最近发布的模块感兴趣:ijavascript-plotly

我知道这个答案可以浏览很多概念。如果您需要我更新答案并进一步解释,请使用下面的评论。

答案 1 :(得分:1)

在Jupyter中渲染D3的类似方法:

var d3 = require("d3");
var jsdom = require("jsdom");

var dom = new jsdom.JSDOM("<svg></svg>",{QuerySelector:true});

var svg = dom.window.document.querySelector("svg");

d3.select(svg)
    .append("rect")
    .attr("width", 80)
    .attr("height", 80)
    .style("fill", "orange");

$$.html(dom.serialize());