diff --git a/package.json b/package.json index 6e8ce43004..a941162ca6 100644 --- a/package.json +++ b/package.json @@ -152,6 +152,7 @@ "d3-color": "^1.4.0", "d3-scale": "^1.0.7", "d3-shape": "^1.3.4", + "fast-deep-equal": "^3.1.1", "konva": "^4.0.18", "newtype-ts": "^0.2.4", "prop-types": "^15.7.2", diff --git a/src/chart_types/xy_chart/renderer/canvas/area_geometries.tsx b/src/chart_types/xy_chart/renderer/canvas/area_geometries.tsx index e0ba192b0c..3b9ce82761 100644 --- a/src/chart_types/xy_chart/renderer/canvas/area_geometries.tsx +++ b/src/chart_types/xy_chart/renderer/canvas/area_geometries.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { Group as KonvaGroup } from 'konva/types/Group'; import { PathConfig } from 'konva/types/shapes/Path'; import { Circle, Group, Path } from 'react-konva'; +import deepEqual from 'fast-deep-equal/es6/react'; import { buildAreaRenderProps, buildPointStyleProps, @@ -24,10 +25,8 @@ interface AreaGeometriesDataProps { highlightedLegendItem: LegendItem | null; clippings: Clippings; } -interface AreaGeometriesDataState { - overPoint?: PointGeometry; -} -export class AreaGeometries extends React.PureComponent { + +export class AreaGeometries extends React.Component { static defaultProps: Partial = { animated: false, }; @@ -35,10 +34,12 @@ export class AreaGeometries extends React.PureComponent diff --git a/src/chart_types/xy_chart/renderer/canvas/axis.tsx b/src/chart_types/xy_chart/renderer/canvas/axis.tsx index 004ee6391c..a28d5960ef 100644 --- a/src/chart_types/xy_chart/renderer/canvas/axis.tsx +++ b/src/chart_types/xy_chart/renderer/canvas/axis.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { Group, Line, Rect, Text } from 'react-konva'; +import deepEqual from 'fast-deep-equal/es6/react'; import { AxisTick, AxisTicksDimensions, @@ -36,7 +37,11 @@ interface AxisProps { chartDimensions: Dimensions; } -export class Axis extends React.PureComponent { +export class Axis extends React.Component { + shouldComponentUpdate(nextProps: AxisProps) { + return !deepEqual(this.props, nextProps); + } + private renderTickLabel = (tick: AxisTick, i: number) => { /** * padding is already computed through width @@ -249,7 +254,11 @@ interface AxesProps { debug: boolean; chartDimensions: Dimensions; } -class AxesComponent extends React.PureComponent { +class AxesComponent extends React.Component { + shouldComponentUpdate(nextProps: AxesProps) { + return !deepEqual(this.props, nextProps); + } + render() { const { axesVisibleTicks, diff --git a/src/chart_types/xy_chart/renderer/canvas/bar_geometries.tsx b/src/chart_types/xy_chart/renderer/canvas/bar_geometries.tsx index 3d78f7265b..3dc0b0abb9 100644 --- a/src/chart_types/xy_chart/renderer/canvas/bar_geometries.tsx +++ b/src/chart_types/xy_chart/renderer/canvas/bar_geometries.tsx @@ -2,6 +2,7 @@ import { Group as KonvaGroup } from 'konva/types/Group'; import React from 'react'; import { Group, Rect } from 'react-konva'; import { animated, Spring } from 'react-spring/renderprops-konva.cjs'; +import deepEqual from 'fast-deep-equal/es6/react'; import { buildBarRenderProps, buildBarBorderRenderProps } from './utils/rendering_props_utils'; import { BarGeometry } from '../../../../utils/geometry'; import { LegendItem } from '../../../../chart_types/xy_chart/legend/legend'; @@ -19,7 +20,7 @@ interface BarGeometriesDataProps { interface BarGeometriesDataState { overBar?: BarGeometry; } -export class BarGeometries extends React.PureComponent { +export class BarGeometries extends React.Component { static defaultProps: Partial = { animated: false, }; @@ -31,6 +32,11 @@ export class BarGeometries extends React.PureComponent { +export class BarValuesComponent extends React.Component { + shouldComponentUpdate(nextProps: BarValuesProps) { + return !deepEqual(this.props, nextProps); + } + render() { const { chartDimensions, bars } = this.props; if (!bars) { diff --git a/src/chart_types/xy_chart/renderer/canvas/grid.tsx b/src/chart_types/xy_chart/renderer/canvas/grid.tsx index abfc85bf52..5cb6a93698 100644 --- a/src/chart_types/xy_chart/renderer/canvas/grid.tsx +++ b/src/chart_types/xy_chart/renderer/canvas/grid.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { Group, Line } from 'react-konva'; import { connect } from 'react-redux'; +import deepEqual from 'fast-deep-equal/es6/react'; import { AxisLinePosition, isVerticalGrid } from '../../utils/axis_utils'; import { GridLineConfig, mergeGridLineConfigs, Theme } from '../../../../utils/themes/theme'; import { Dimensions } from '../../../../utils/dimensions'; @@ -22,7 +23,11 @@ interface GridProps { chartDimensions: Dimensions; } -class GridComponent extends React.PureComponent { +class GridComponent extends React.Component { + shouldComponentUpdate(nextProps: GridProps) { + return !deepEqual(this.props, nextProps); + } + render() { const { axesGridLinesPositions, axesSpecs, chartDimensions, chartTheme } = this.props; const gridComponents: JSX.Element[] = []; diff --git a/src/chart_types/xy_chart/renderer/canvas/line_annotation.tsx b/src/chart_types/xy_chart/renderer/canvas/line_annotation.tsx index 1853e197bf..edfe979e87 100644 --- a/src/chart_types/xy_chart/renderer/canvas/line_annotation.tsx +++ b/src/chart_types/xy_chart/renderer/canvas/line_annotation.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { Group, Line } from 'react-konva'; +import deepEqual from 'fast-deep-equal/es6/react'; import { LineAnnotationStyle } from '../../../../utils/themes/theme'; import { AnnotationLineProps } from '../../annotations/line_annotation_tooltip'; @@ -8,7 +9,11 @@ interface LineAnnotationProps { lineStyle: LineAnnotationStyle; } -export class LineAnnotation extends React.PureComponent { +export class LineAnnotation extends React.Component { + shouldComponentUpdate(nextProps: LineAnnotationProps) { + return !deepEqual(this.props, nextProps); + } + render() { const { lines } = this.props; diff --git a/src/chart_types/xy_chart/renderer/canvas/line_geometries.tsx b/src/chart_types/xy_chart/renderer/canvas/line_geometries.tsx index 1fd92ae85c..0ee2e87284 100644 --- a/src/chart_types/xy_chart/renderer/canvas/line_geometries.tsx +++ b/src/chart_types/xy_chart/renderer/canvas/line_geometries.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { Group as KonvaGroup } from 'konva/types/Group'; import { Circle, Group, Path } from 'react-konva'; +import deepEqual from 'fast-deep-equal/es6/react'; import { buildLineRenderProps, buildPointStyleProps, @@ -21,10 +22,8 @@ interface LineGeometriesDataProps { highlightedLegendItem: LegendItem | null; clippings: Clippings; } -interface LineGeometriesDataState { - overPoint?: PointGeometry; -} -export class LineGeometries extends React.PureComponent { + +export class LineGeometries extends React.Component { static defaultProps: Partial = { animated: false, }; @@ -37,6 +36,10 @@ export class LineGeometries extends React.PureComponent diff --git a/src/chart_types/xy_chart/renderer/canvas/rect_annotation.tsx b/src/chart_types/xy_chart/renderer/canvas/rect_annotation.tsx index ff7753afa8..216505eb65 100644 --- a/src/chart_types/xy_chart/renderer/canvas/rect_annotation.tsx +++ b/src/chart_types/xy_chart/renderer/canvas/rect_annotation.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { Group, Rect } from 'react-konva'; +import deepEqual from 'fast-deep-equal/es6'; import { RectAnnotationStyle } from '../../../../utils/themes/theme'; import { AnnotationRectProps } from '../../annotations/rect_annotation_tooltip'; @@ -8,7 +9,11 @@ interface Props { rectStyle: RectAnnotationStyle; } -export class RectAnnotation extends React.PureComponent { +export class RectAnnotation extends React.Component { + shouldComponentUpdate(nextProps: Props) { + return !deepEqual(this.props, nextProps); + } + render() { const { rects } = this.props; return {rects.map(this.renderAnnotationRect)}; diff --git a/src/chart_types/xy_chart/specs/line_annotation.tsx b/src/chart_types/xy_chart/specs/line_annotation.tsx index 1487777ce3..161993a060 100644 --- a/src/chart_types/xy_chart/specs/line_annotation.tsx +++ b/src/chart_types/xy_chart/specs/line_annotation.tsx @@ -1,4 +1,5 @@ -import React, { createRef, CSSProperties, PureComponent } from 'react'; +import React, { createRef, CSSProperties, Component } from 'react'; +import deepEqual from 'fast-deep-equal/es6/react'; import { LineAnnotationSpec, DEFAULT_GLOBAL_ID, AnnotationTypes } from '../utils/specs'; import { DEFAULT_ANNOTATION_LINE_STYLE } from '../../../utils/themes/theme'; import { bindActionCreators, Dispatch } from 'redux'; @@ -12,7 +13,7 @@ type InjectedProps = LineAnnotationSpec & Readonly<{ children?: React.ReactNode; }>; -export class LineAnnotationSpecComponent extends PureComponent { +export class LineAnnotationSpecComponent extends Component { static defaultProps: Partial = { chartType: ChartTypes.XYAxis, specType: SpecTypes.Annotation, @@ -38,6 +39,11 @@ export class LineAnnotationSpecComponent extends PureComponent { static displayName = 'ChartContainer'; - shouldComponentUpdate(props: ReactiveChartProps) { - return props.initialized; + shouldComponentUpdate(nextProps: ReactiveChartProps) { + return !deepEqual(this.props, nextProps); } + handleMouseMove = ({ nativeEvent: { offsetX, offsetY, timeStamp }, }: React.MouseEvent) => { diff --git a/src/components/icons/assets/dot.tsx b/src/components/icons/assets/dot.tsx index c50af6dcce..5cbab3eddd 100644 --- a/src/components/icons/assets/dot.tsx +++ b/src/components/icons/assets/dot.tsx @@ -1,7 +1,12 @@ import React from 'react'; +import deepEqual from 'fast-deep-equal/es6/react'; import { Props } from '../icon'; -export class DotIcon extends React.PureComponent { +export class DotIcon extends React.Component { + shouldComponentUpdate(nextProps: Props) { + return !deepEqual(this.props, nextProps); + } + render() { return ( diff --git a/src/components/icons/icon.tsx b/src/components/icons/icon.tsx index 3d7de41eea..7dd5c31dc5 100644 --- a/src/components/icons/icon.tsx +++ b/src/components/icons/icon.tsx @@ -1,5 +1,6 @@ import classNames from 'classnames'; import React, { SVGAttributes } from 'react'; +import deepEqual from 'fast-deep-equal/es6/react'; import { AlertIcon } from './assets/alert'; import { DotIcon } from './assets/dot'; import { EmptyIcon } from './assets/empty'; @@ -31,7 +32,11 @@ export interface IconProps { export type Props = Omit, 'color' | 'type'> & IconProps; -export class Icon extends React.PureComponent { +export class Icon extends React.Component { + shouldComponentUpdate(nextProps: Props) { + return !deepEqual(this.props, nextProps); + } + render() { const { type, color, className, tabIndex, ...rest } = this.props; let optionalCustomStyles = null; diff --git a/src/components/legend/legend_item.tsx b/src/components/legend/legend_item.tsx index 1ffae3f42d..c5a3f305fd 100644 --- a/src/components/legend/legend_item.tsx +++ b/src/components/legend/legend_item.tsx @@ -1,5 +1,6 @@ import classNames from 'classnames'; import React from 'react'; +import deepEqual from 'fast-deep-equal/es6/react'; import { Icon } from '../icons/icon'; import { LegendItemListener, BasicListener } from '../../specs/settings'; import { LegendItem } from '../../chart_types/xy_chart/legend/legend'; @@ -22,10 +23,6 @@ interface LegendItemProps { toggleDeselectSeriesAction: (legendItemId: SeriesIdentifier) => void; } -interface LegendItemState { - isColorPickerOpen: boolean; -} - /** * Create a div for the the displayed value * @param displayValue @@ -92,9 +89,13 @@ function renderColor(color: string, isSeriesVisible = true) { ); } -export class LegendListItem extends React.PureComponent { +export class LegendListItem extends React.Component { static displayName = 'LegendItem'; + shouldComponentUpdate(nextProps: LegendItemProps) { + return !deepEqual(this.props, nextProps); + } + render() { const { displayValue, legendItem, legendPosition, label } = this.props; const { color, isSeriesVisible, seriesIdentifier, isLegendItemVisible } = legendItem; diff --git a/src/components/react_canvas/grid.tsx b/src/components/react_canvas/grid.tsx index 0bffd50ad6..87b4e48f8a 100644 --- a/src/components/react_canvas/grid.tsx +++ b/src/components/react_canvas/grid.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { Group, Line } from 'react-konva'; +import deepEqual from 'fast-deep-equal/es6/react'; import { AxisLinePosition } from '../../chart_types/xy_chart/utils/axis_utils'; import { GridLineConfig } from '../../utils/themes/theme'; import { Dimensions } from '../../utils/dimensions'; @@ -11,7 +12,11 @@ interface GridProps { linesPositions: AxisLinePosition[]; } -export class Grid extends React.PureComponent { +export class Grid extends React.Component { + shouldComponentUpdate(nextProps: GridProps) { + return !deepEqual(this.props, nextProps); + } + render() { return this.renderGrid(); } diff --git a/yarn.lock b/yarn.lock index a90904eea7..938af2d6d8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7535,6 +7535,11 @@ fast-deep-equal@^2.0.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + fast-diff@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03"