NVD3图表无法在隐藏选项卡中正确呈现

met*_*lin 18 hidden-field d3.js nvd3.js bootstrap-tabs twitter-bootstrap-3

我正在构建一个包含许多图表的页面,这些图表根据您正在查看的选项卡一次显示一个.

最初激活的选项卡中的图表正确呈现.但是,当我单击另一个选项卡时,图表无法正确呈现.

据推测,这是因为隐藏字段在可见之前没有尺寸.事实上,如果我调整窗口大小,图表将更正它的比例,并进行渲染以使其填充可用宽度.

我可以通过css显式定义图表大小来解决这个问题,但这会破坏图表的响应方面.

任何人都可以告诉我如何触发相同的NVD3事件,当窗口调整大小时,该事件会被激活吗?这样我就可以将它绑定到新选项卡的选择,并希望能够解决渲染问题.

Nic*_*ton 16

我遇到了同样的问题(多个标签上的图表),这是我唯一可以开始工作的东西.

$(function () {
    $(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
        window.dispatchEvent(new Event('resize'));
    });
});
Run Code Online (Sandbox Code Playgroud)

但是,我感觉所有图表都在重新渲染,无论它们是在活动标签上(可见)还是在非选定标签(隐藏)中.

有谁知道如何确保只调整活动图表的大小/重绘?


met*_*lin 12

我想出了如何触发我需要的调整大小事件.在我的情况下,选项卡由引导程序驱动.所以我只是修改了我的bootstrap show tab事件以触发页面调整大小事件.这有点间接,但它完成了工作:

jQuery('#myTab a').click(function (e) {
    e.preventDefault()
    jQuery(this).tab('show')
    jQuery(window).trigger('resize'); // Added this line to force NVD3 to redraw the chart
})
Run Code Online (Sandbox Code Playgroud)


nos*_*omo 8

只需添加此JavaScript:

$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
  window.dispatchEvent(new Event('resize'));
})
Run Code Online (Sandbox Code Playgroud)

hidden.bs.tab是根据Bootstrap文档显示新选项卡后触发的事件.每次更改选项卡后,此代码将触发resize事件.


wun*_*uno 5

新答案的原因

2018年,很多人都需要使用Vanilla Javascript 。由于当今存在的许多框架和Javascript库在jQuery中无法很好地发挥作用。曾几何时,使用jQuery解决方案来回答所有Javascript问题是可以接受的,但现在不再可行。

问题

加载C3.js或D3.js图形时,如果在页面加载期间视口不在活动中,则这些图形将无法正确呈现。

  1. 如果键入URL,则打开一个新选项卡,然后在页面加载后返回。

  2. 如果刷新包含图形的页面,请最小化浏览器并在页面加载后将其打开备份。

  3. 如果您刷新或转到带有图形的页面,则滑动到计算机上的新窗口。加载图形后,返回带有图形的页面。

在所有这些情况下,您的C3.js / D3.js图形将无法正确呈现。通常,您会看到一块空白的画布。因此,如果您期望条形图,则会看到没有绘制条形的画布。

背景

尽管我看到这个问题的答案,但我需要一个使用jQuery 的答案。现在我们已经到了用jQuery无法解决所有问题的时代,我认为为这个问题提供一个有效的Javascript答案似乎很合适。

我的团队面临的问题是,如果刷新页面并刷掉或最小化了C3.js / D3.js图形,将无法加载。基本上,如果您没有留在页面上并将其保留在网站上,直到完成加载,您将不会看到图表,直到您再次调整页面大小。我知道这是每个使用C3.js / D3.js的人都会遇到的问题,但是我们在Salesforce中特别使用了Lightning。

回答

我们的解决方法是将其添加到初始化图表的控制器功能中。任何人都可以在编写的任何函数中使用此函数来初始化C3.js / D3.js图,而无需考虑其堆栈。这不依赖于Salesforce,但是如果您在Salesforce中遇到此问题,它确实可以工作。

document.addEventListener('visibilitychange', () => {
   console.log(document.visibilityState);
   window.dispatchEvent(new Event('resize'));
});
Run Code Online (Sandbox Code Playgroud)