使用jint从c#中使用d3调用javascript



我目前正在进行一个项目,需要根据一些输入数据生成一些SVG。目前,所有这些SVG生成都是使用d3库在javascript中实现的。请注意,我的目标是能够重用这个逻辑,而不是全部实现它。

我的问题是,我希望能够从C#调用这个javascript。

我尝试过使用PhantomJS,我能够生成SVG,但我不满意,因为

  • 每次我想调用javascript时,它都会启动一个新的进程注意到它占用了大量内存(在我的情况下,我看到了100 mb这对我来说太过分了)
  • 它看起来有点不稳定。我有在某些情况下,流程会挂起
  • 开发(在javascript方面)非常令人沮丧,因为它很难调试

因为我对PhantomJS不满意,我也尝试过使用jint,这似乎真的很好用。不幸的是,我还没有完全建立并运行一个工作示例。目前,我正在使用AngleSharp来提供DOM,这样D3就有地方写数据了。这给了我以下例子:

static void TestJint()
{
//We require a custom configuration with JavaScript and CSS
var config = Configuration.Default.WithJavaScript().WithCss();
//Let's create a new parser using this configuration
var parser = new HtmlParser(config);
//This is our sample source, we will do some DOM manipulation
var source = "<!doctype html> <html><head></head> <body> </body></html>";
var document = parser.Parse(source);

var jintEngine = new Engine();
jintEngine.SetValue("document", document.Implementation);

jintEngine = jintEngine.Execute(File.ReadAllText("d3.min.js"));

jintEngine = jintEngine.Execute("function testFunc() { d3.select("body").append("span").text("Hello, world!"); return 42;}");
var res = jintEngine.Invoke("testFunc").ToObject();
}

问题是行var res=jintEngine.Invoke("testFunc").ToObject();引发异常。

异常截图

如果我尝试更换线路

jintEngine = jintEngine.Execute("function testFunc() { d3.select("body").append("span").text("Hello, world!"); return 42;}");

带有

jintEngine = jintEngine.Execute("function testFunc() { d3.select("body"); return 42;}");

则该函数能够在没有任何异常的情况下运行。通过对逻辑进行一点处理,我得出结论,是.append(\"span\")导致了异常。

我有点困了,所以我希望有人能给我一个正确的方向。

我已经解决了问题。

1) 解析程序返回的文档。解析(来源);没有实现d3使用的函数createElementNS。我通过使用委托调用的包装器解决了这个问题。

2) d3使用了我尚未设置的变量ownerDocument。所以我还必须添加以下

jintEngine.SetValue("ownerDocument", new MyDocumentWrapper(document));

请注意,这并不能使整个d3库正常工作。我也注意到了d3.geopath()的一些问题,但通过这些修复,我可以执行我的初始示例。

最新更新