Skip to content

Chart resize observer example #5995

Description

@dlabrecq

In order to resize charts, PatternFly examples use the window resize event. However, this doesn't work well with PatternFly's vertical navigation. For example, onNavToggle doesn't generate a window resize event when the nav pane is collapsed. This typically results in a chart that does not resize as expected.

To resolve the issue, Cost Management has been using a ResizeObserver. This resizes the chart whenever its parent container is resized. Not only for the window resize event, but it's also triggered by PatternFly's vertical navigation onNavToggle.

We would like to contribute this code back to PatternFly and perhaps update some examples. Our getResizeObserver code provides a workaround for Chrome and uses the window resize event as a fallback. The developer's existing handleResize function would remain unchanged.

React.Component example

  private observer: any = () => {};

  public componentDidMount() {
    this.observer = getResizeObserver(this.containerRef.current, this.handleResize);
  }

  public componentWillUnmount() {
    if (this.observer) {
      this.observer();
    }
  }

getResizeObserver code

export const getResizeObserver = (containerRef: HTMLDivElement, handleResize: () => void) => {
  const containerElement = containerRef;
  const { ResizeObserver } = window as any;
  let _navToggle;
  let _resizeObserver;

  if (containerElement && ResizeObserver) {
    const resizeObserver = new ResizeObserver(entries => {
      // We wrap it in requestAnimationFrame to avoid this error - ResizeObserver loop limit exceeded
      window.requestAnimationFrame(() => {
        if (!Array.isArray(entries) || !entries.length) {
          return;
        }
        handleResize();
      });
    });
    resizeObserver.observe(containerElement);
    _resizeObserver = () => resizeObserver.unobserve(containerElement);
  } else {
    handleResize();
    window.addEventListener('resize', handleResize);
    _resizeObserver = () => window.removeEventListener('resize', handleResize);
    _navToggle = insights.chrome.on('NAVIGATION_TOGGLE', setTimeout(handleResize, 500));
  }

  return () => {
    if (_resizeObserver) {
      _resizeObserver();
    }
    if (_navToggle) {
      _navToggle();
    }
  };
};

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions