Shakedk
Shakedk

Reputation: 440

Need to select the range of points in react google scatter chart by dragging the mouse

Following this question, I have been trying to make the accepted answer by @whitehat work with react-google-charts scatterplot.

I managed to create the rectangle, but the dragging works very slow, which I believe is due to re-rendering on each change. i tried both having the div_select as imported component and having it inside the scatterPlot container component.

Any idea what would be the right approach for this?

Here is a code example:

import React, { useState } from "react";
import classes from "./ScatterPlot.module.css";
import Chart from "react-google-charts";

const ScatterPlot = props => {
  const [x1, setX1] = useState(0);
  const [x2, setX2] = useState(0);
  const [y1, setY1] = useState(0);
  const [y2, setY2] = useState(0);
  const [x3, setX3] = useState(0);
  const [x4, setX4] = useState(0);
  const [y3, setY3] = useState(0);
  const [y4, setY4] = useState(0);
  const [selectDivStyle, setSelectDivStyle] = useState({
    left: "0px",
    top: "0px",
    width: "0px",
    height: "0px"
  });
  const { data } = props;

  const reCalcSelectBox = () => {
    setX3(Math.min(x1, x2));
    setX4(Math.max(x1, x2));
    setY3(Math.min(y1, y2));
    setY4(Math.max(y1, y2));
    const styleLeft = x3 + "px";
    const styleTop = y3 + "px";
    const styleWidth = x4 - x3 + "px";
    const styleHeight = y4 - y3 + "px";
    setSelectDivStyle({
      left: styleLeft,
      top: styleTop,
      width: styleWidth,
      height: styleHeight
    });
  };

  let hideSelect = true;
  const mouseDownOnChart = e => {
    hideSelect = false;
    setX1(e.pageX);
    setY1(e.pageY);
    reCalcSelectBox();
  };

  const mouseMoveOnChart = e => {
    setX2(e.pageX);
    setY2(e.pageY);
    reCalcSelectBox();
  };

  const mouseUpOnChart = e => {
    hideSelect = true;
    // selectPoints();
  };

  const selectPoints = () => {
    // Not yet implemented
  };

  const selectBoxClasses = [classes.selectDivContainer];

  if (hideSelect) {
    selectBoxClasses.push(classes.hidden);
  }

  return (
    <div
      onMouseDown={mouseDownOnChart}
      onMouseUp={mouseUpOnChart}
      onMouseMove={mouseMoveOnChart}
      className={selectBoxClasses}
    >
      <div className={classes.selectDiv} style={selectDivStyle} />
      <div className={classes.scatterPlotContainer}>
        <Chart
          width={"100%"}
          height={"100%"}
          chartType="ComboChart"
          data={data}
          rootProps={{ "data-testid": "1" }}
        />
      </div>
    </div>
  );
};

export default ScatterPlot;

Upvotes: 0

Views: 500

Answers (1)

D. Richard
D. Richard

Reputation: 472

Use React.memo which help preventing an unnecessary re-render.

Upvotes: 1

Related Questions