d3.js:在 Angular 应用程序和 node.js 上运行相同的代码

Posted

技术标签:

【中文标题】d3.js:在 Angular 应用程序和 node.js 上运行相同的代码【英文标题】:d3.js: run the same code in Angular app and on node.js 【发布时间】:2019-02-15 21:56:30 【问题描述】:

我需要在 Angular 5 应用程序中添加一些信息图表。我为此选择了 d3.js。我还需要能够导出图形,即使用 Node 制作 SVG 并将它们包装在 PDF 中。

幸运的是,让浏览器中的 d3 图形在 node.js 上运行的代码相当简单。以下几行就是这样做的......

const  JSDOM  = jsdom;
const  window  = new JSDOM();
const  document  = (new JSDOM('')).window;
global.document = document;

之后,只需对可在浏览器中运行的代码进行少量更改。

显然我不想拥有几乎相同代码的 2 个副本,因此我需要一种方法来组织在两个角度应用程序端创建 SVG 的函数的使用(如果那是 Typescript 而不是 javascript,我更喜欢)和节点应用程序端。不幸的是,我在 Node 方面没有太多经验,也没有看到一个简单的解决方案。

这是我的问题...

    如何通过 Angular 5 应用和 node.js 应用简单地组织使用 d3 创建 SVG 的函数的使用? 也许用节点渲染 d3.js 不是最好的解决方案,还有另一个更简单的解决方案?

提前谢谢你!

【问题讨论】:

我能给你的最好建议是不要混合使用 Node.js 和 Angular。只需使用 Angular 作为前端框架,使用 node.js 作为后端框架,通过 REST API 向 Angular 提供数据。使用 node.js 来呈现你的角度页面没有任何意义。 Angular 旨在处理所有客户端逻辑,例如从 REST API 呈现和获取数据。 此外,您可以将 d3.js 导入您希望渲染的角度组件中。请注意,在角度景观中不允许直接 dom 操作,因为它会导致奇怪的行为。使用 d3.js 时,您无法完全避免这种情况,但至少可以将影响降到最低。 当你想在 Angular 中使用 d3.js 时,这可能对你有用,像这样导入它:import * as d3 from 'd3'; 然后使用 ngAfterContentInit 生命周期钩子来定位 html 中的元素这个组件的。 @enf0rcer 感谢您的建议,我仍然不需要在 Node.js 上启动整个应用程序。我所需要的只是能够在角度端和节点端启动创建 SVG 的函数。我已经更新了问题以使其更清楚 您可以使用import isPlatformBrowser, isPlatformServer from '@angular/common'; 来检测浏览器,与s-s-r 一起使用。不确定您的确切要求,但有一些示例可能会为您提供正确的模式。 【参考方案1】:

我想建议以下解决方案。

首先,不管你现在实际使用的是哪个前端框架。 如果我的想法正确,您需要有 d3js 图表的图片/屏幕截图,以便将来在 PDF 中使用它。对吗?

您需要编写一个实用程序,以便能够使用您的图表组件打开真实网页并制作屏幕截图(具有您想要的分辨率)它可能是量角器与 chrome-browser 的组合,例如. (有很多解决方案,实际上,我们甚至可以使用 PhantomJS。根据我使用 Protractor 的经验,更简单、更容易实现)。此外,Protractor 有一个内部功能,可以截取页面并保存到特定文件夹。

遵循该解决方案我们有哪些好处:

唯一一个有图表渲染相关源码的地方 100% 确保图表视图与真实网页上的相同(带有 其他角度组件) 我们不需要找到在 Node.JS 端渲染 SVG 的方式等等...

作业可能如下所示:

启动一些 NPM/Gulp/Grunt(随便)任务来打开特定的 使用 Protractor 和 Chrome 浏览器打开您的网络应用页面。 打开只有图表组件+数据层的虚拟页面。 截屏并保存到特定文件夹。使用截图 PDF 中的图表(手动或使用其他工具)

【讨论】:

是的,您已经正确理解了我需要有 d3js 图表的图片/屏幕截图,以便将来在 PDF 中使用它。即使是 svg 也可以!【参考方案2】:

如果你想在服务器端做,你可以有一个 api 来生成图形并返回元素。您可以直接将其插入 UI,也可以使用相同的功能生成 PDF。

【讨论】:

以上是关于d3.js:在 Angular 应用程序和 node.js 上运行相同的代码的主要内容,如果未能解决你的问题,请参考以下文章

将 D3.js 导入 Angular 2 应用程序的正确方法

在 Angular2 中使用 d3.js

升级到 Angular 8 后出现 d3.js 运行时错误

如何在带有 D3 的 Angular 中使用“this”?

Renderer2 在使用 d3 js - Angular 4 时不渲染 SVG 元素

如何将 D3.js 与 Renderer API 与 Angular 2 集成