如何使用jsdom,D3和IJavascript在Jupyter笔记本中输出SVG

Ulf*_*lak 5 javascript dom node.js d3.js jupyter-notebook

我在前端开发方面并不强,但最近我玩弄了很多Javascript和D3.习惯于使用Jupyter笔记本在Python中进行科学分析,我认为应该可以使用类似的工作流程来开发科学可视化,使用带有JS内核的Jupiter笔记本中的JS代码使用D3.我看过n-riescoIJavascript项目,看起来很有希望,但是当试图导入D3时,笔记本会抛出一个错误:

// npm install d3
var d3 = require('d3');
Run Code Online (Sandbox Code Playgroud)

ReferenceError: document is not defined
Run Code Online (Sandbox Code Playgroud)

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

我想做的事情是:

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

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


更新

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

在此输入图像描述

Nic*_*ico 5

让我先给出一个工作实例(测试ijavascript@5.0.19,jsdom@9.12.0然后d3@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);
Run Code Online (Sandbox Code Playgroud)

截图来自2017-04-20 09-32-53

此解决方案:

  • 使用jsdom提供的DOM .

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

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

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

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


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


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