github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ui/src/views/shared/util/d3-react.tsx (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  import d3 from "d3";
    12  import React from "react";
    13  
    14  type Chart<T> = (sel: d3.Selection<T>) => void;
    15  
    16  /**
    17   * createChartComponent wraps a D3 reusable chart in a React component.
    18   * See https://bost.ocks.org/mike/chart/
    19   */
    20  export default function createChartComponent<T>(containerTy: string, chart: Chart<T>) {
    21    return class WrappedChart extends React.Component<T> {
    22      containerEl: React.RefObject<Element> = React.createRef();
    23  
    24      componentDidMount() {
    25        this.redraw();
    26        this.addResizeHandler();
    27      }
    28  
    29      componentWillUnmount() {
    30        this.removeResizeHandler();
    31      }
    32  
    33      shouldComponentUpdate(props: T) {
    34        this.redraw(props);
    35  
    36        return false;
    37      }
    38  
    39      redraw(props: T = this.props) {
    40        d3.select(this.containerEl.current)
    41          .datum(props)
    42          .call(chart);
    43      }
    44  
    45      handleResize = () => {
    46        this.redraw();
    47      }
    48  
    49      addResizeHandler() {
    50        window.addEventListener("resize", this.handleResize);
    51      }
    52  
    53      removeResizeHandler() {
    54        window.removeEventListener("resize", this.handleResize);
    55      }
    56  
    57      render() {
    58        return React.createElement(
    59          containerTy,
    60          { ref: this.containerEl },
    61        );
    62      }
    63    };
    64  }