Search code examples
reactjschartsreact-chartjs

options changes not seen in react chartjs 2


I have a problem to update the options of a chart in react-chartjs-2, precisely in the dragData plugin of chartjs

I have the dragData activated for the graph, that part works, the graph allows you to drag the data. The problem occurs when I click the button to disable the drag option, the graph does not work, it still allows dragging the values.

apparently in the console the options of the graph change but it is not reflected in the interaction of the graph, I leave the code in the following link.

useEffect(() => {
  if(props.state === true){
    let ref = chartReference.current.chartInstance;
      ref.options.dragData = false;
      ref.update();
  }else {
    let ref = chartReference.current.chartInstance;
    ref.options.dragData = true;
    ref.update();
  }
}, [props.state])

working code


Solution

  • According to this thread the problem can still exist in this library.

    Beside obvious option to shorten code ...

    useEffect(() => {
      let ref = chartReference.current.chartInstance;
      ref.options.dragData = !props.state;
      ref.update();
    }, [props.state])
    

    ... it looks like you have to somehow force redraw/rerendering.

    One of option is to change entire options prop passed to <Line />. You can use useState to keep this config object - of course with moving initial state:

    const [chartOptions, setChartOptions] = useState(
        {
          onDragEnd: handleDrag,
          dragData: true,
          dragDataRound: 0,
          ...
    

    useEffect to react on prop.state changes:

    useEffect(() => {
      setChartOptions(Chart.helpers.configMerge(chartOptions, {
        dragData: !props.state
        })
      );
    }, [props.state])
    

    <Line /> chart required changes:

      <Line
        ref={chartReference}
        data={data}
        height={30}
    
        options={chartOptions}
    
        redraw={true}
      />
    

    working example

    Of course you can use props.state value in initial state... also think about renaming state prop, it can be at least missleading ... especially when you'll convert this component to class.