19

我正在构建一个包含许多图表的页面,这些图表一次显示一个,具体取决于您正在查看的选项卡。

最初活动选项卡中的图表正确呈现。但是,当我单击另一个选项卡时,图表未正确呈现。

大概这是因为隐藏字段在变得可见之前没有维度。事实上,如果我调整窗口大小,图表将更正它的比例,并渲染以填充可用宽度。

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

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

4

7 回答 7

16

我有同样的问题(多个选项卡上的图表),这是我唯一可以开始工作的事情。

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

但是,我有一种感觉,所有图表都在重新渲染,无论它们是在活动选项卡(可见)还是在未选择的选项卡(隐藏)中。

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

于 2015-03-22T04:15:43.960 回答
12

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

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
})
于 2014-02-04T22:19:51.133 回答
8

只需添加此 JavaScript:

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

hidden.bs.tab是根据 Bootstrap 文档显示新选项卡后触发的事件。此代码在每次选项卡更改后触发调整大小事件。

于 2015-04-02T05:11:31.877 回答
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'));
});
于 2018-04-01T15:58:41.577 回答
4

我面临同样的问题。我正在使用ng-show使 div hidden 。一旦我将 ng-show 替换为ng-if我能够看到以预期行为绘制的图形。解释:

  1. 当我们使用 ng-show 或ng-hide使 div 隐藏时,它只会更改它的显示属性,但 div 将在 dom 中。

  2. 当我们使用ng-if从 dom 中删除 div 并再次添加到 dom 时,它在内部也会对 nvd3 图执行重绘操作。因此,我们看到的是正确的图表而不是压扁的图表。

于 2016-07-19T07:21:20.770 回答
0

通常触发重绘的事件是窗口resize事件——NVD3 不为此使用自定义事件。你可以自己控制它;通常的定义是

nv.utils.windowResize(function() { d3.select('#chart svg').call(chart); });

(其中“#chart”是包含图表的元素)。没有什么可以阻止您在另一个事件上触发代码,甚至在您更改选项卡时显式运行重绘代码。

于 2014-02-04T21:31:29.523 回答
0

更有效的方法是使用 chart.update() 方法

var chart_x = nv.models.somechart()
var chart_y = nv.models.somechart()

.....显示图表

jQuery('#myTab a').click(function (e) {
    e.preventDefault()
    jQuery(this).tab('show')
    if(jQuery(this)...something === '..x..')
      chart_x.update(); //CALL THE UPDATE
    else ...  

})

于 2017-11-27T23:52:51.317 回答