当ng2-nvd3图表不在视图范围内时,大小的浏览器错误会发生变化

时间:2016-05-02 07:29:06

标签: angular nvd3.js angular2-routing ng2-nvd3

虽然使用ng2-nvd3结合角度2路由功能,但我注意到控制台充满了以下错误:

d3.min.js:1 Error: <g> attribute transform: Expected number, "translate(NaN,5)"

我设法将问题指向一个用例:

  • 将路线出口更改为指向具有ng2-nvd3图表的路线
  • 将其更改回指向没有ng2-nvd3图表的路线
  • 更改窗口大小(或开发者控制台的大小)
  • 在控制台中查看错误

使用此plunker

可轻松复制此内容
  • 打开开发者控制台
  • 点击&#34; Chart&#34;链路
  • 点击&#34; No Chart&#34;链路
  • 更改开发者控制台(或浏览器窗口的大小 - 相同的效果) - 确保释放鼠标按钮而不仅仅是更改大小。
  • 控制台中出现错误

如何避免此错误?

1 个答案:

答案 0 :(得分:5)

在ng2-nvd3 source code第118行,我们可以看到有一个正在注册的调整大小处理程序

self.chart.resizeHandler = nv.utils.windowResize(function() {...})

当图表不在视图范围内时(例如上面的情况),需要清除此调整大小处理程序 - 但它不会自动发生。

要解决此问题,需要通过添加

来获取对图表本身的引用
@ViewChild('chart') chart;

到组件(并通过将#chart属性添加到nvd3元素来命名模板中的图表) 这将允许我们调用

this.chart.chart.resizeHandler.clear();

清除resize事件中的处理程序。 但是我们仍然需要知道图表何时不在视图中 - 有很多方法可以实现这一点,每个方法都有自己的细微之处(ngOnDestroy / ngOnChanges等)。 对我有用的那个虽然有点咄咄逼人,却彻底解决了这个问题:

我已将根路由器注入主组件并订阅了对其的更改,并通过具有EventEmitter的服务委派它们 然后我将该服务注入图表组件并注册到该事件(据我检查,您不能将路由器注入图表组件,因为它不是根路由器而是一些子路由器和因此不会得到所有的路线变化) 在事件处理程序中,我创建了一次性的

调用
this.chart.chart.resizeHandler.clear();

RoutingService

import { Injectable, EventEmitter } from 'angular2/core';

@Injectable()
export class RoutingService {
    public onRouteChange$: EventEmitter<string>;

    constructor() {
        this.onRouteChange$ = new EventEmitter();
    }

    routeChange(route: string) {
        this.onRouteChange$.emit(route);
    }
}

MainComponent构造函数:

  constructor(private router:Router, private routingService:RoutingService){
    router.subscribe( val => routingService.routeChange(val));
  }

ChartComponent构造函数:

  constructor(private routingService:RoutingService) {
    let sub:any = routingService.onRouteChange$.subscribe(route => {
        if (route != 'chart') {
            this.chart.chart.resizeHandler.clear();
            if (sub) {
              sub.unsubscribe();
            }
        }
    });
  }

您可以在此plunker

中看到它