Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chart isn't updated when primitive is detached using plugins-example #1594

Open
Rafael-Ramblas opened this issue May 12, 2024 · 2 comments
Open
Labels
bug Unexpected problem or unintended behavior. plugin This feature request should/could be implemented as a Plugin.
Milestone

Comments

@Rafael-Ramblas
Copy link

Rafael-Ramblas commented May 12, 2024

Lightweight Charts™ Version: 4.1.4

Importing the code from the band-indicator example and using in a React component there's an issue with detaching the primitive using a controlled state, as shown in the code below, the chart isn't updated after executing the function detachPrimitive.

The problem relies on the file plugin-base.ts that implements the method for detaching the primitive. The method doesn't call the requestUpdate function before destroying the instance data. If we add the line this.requestUpdate(); before this._requestUpdate = undefined; the feature works as expected.

const colors = {
  backgroundColor: "black",
  lineColor: "#2962FF",
  textColor: "white",
  areaTopColor: "#2962FF",
  areaBottomColor: "rgba(41, 98, 255, 0.28)",
};

const bandIndicator = new BandsIndicator();

const ChartComponent = ({
  data,
  showBands,
}: {
  data: LineData[];
  showBands: boolean;
}) => {
  const chartContainerRef = useRef<HTMLDivElement>(null);
  const lineSeries = useRef<ReturnType<IChartApi["addLineSeries"]>>(null);

  useEffect(() => {
    const { backgroundColor, textColor } = colors;
    const handleResize = () => {
      chart.applyOptions({ width: chartContainerRef.current.clientWidth });
    };

    const chart = createChart(chartContainerRef.current, {
      layout: {
        background: { type: ColorType.Solid, color: backgroundColor },
        textColor,
      },
      width: chartContainerRef.current.clientWidth,
      height: 300,
    });

    lineSeries.current = chart.addLineSeries();
    lineSeries.current.setData(data);

    chart.timeScale().fitContent();

    window.addEventListener("resize", handleResize);

    return () => {
      window.removeEventListener("resize", handleResize);
      chart.remove();
    };
  }, [data]);

  useEffect(() => {
    if (!lineSeries.current) return;
    if (showBands) {
      lineSeries.current.attachPrimitive(bandIndicator);
    } else {
      lineSeries.current.detachPrimitive(bandIndicator);
    }
  }, [showBands]);

  return <div ref={chartContainerRef} />;
};

const ChartWidget = (props: any) => {
  const [showBands, setShowBands] = React.useState(false);
  const sampleData = React.useMemo(() => generateLineData(), []);
  return (
    <>
      <ChartComponent data={sampleData} showBands={showBands} />
      <button onClick={() => setShowBands(!showBands)}>Toggle Bands</button>
    </>
  );
};

Actual behavior:

The chat isn't updated when the method detachPrimitive is executed.

Expected behavior:

The chart should update and remove the primitive draw.

CodeSandbox/JSFiddle/etc link:

https://codesandbox.io/p/sandbox/jolly-christian-lkmqnh

@SlicedSilver SlicedSilver added bug Unexpected problem or unintended behavior. plugin This feature request should/could be implemented as a Plugin. labels May 12, 2024
@SlicedSilver SlicedSilver added this to the 5.0 milestone May 12, 2024
@SlicedSilver
Copy link
Contributor

Thanks for the bug report with the helpful example.

I think it makes more sense if the library automatically refreshes the chart when a primitive is removed instead of relying on the Plugin code to do this within the detached lifecycle hook. So while it would be possible to fix this within the plugins code (in this case plugin-base), it would make more sense to implement this by adding this._series.model().fullUpdate(); to the end of detachPrimitive method.

public detachPrimitive(primitive: ISeriesPrimitive<HorzScaleItem>): void {
this._series.detachPrimitive(primitive as ISeriesPrimitiveBase<unknown>);
if (primitive.detached) {
primitive.detached();
}
}

@Rafael-Ramblas
Copy link
Author

Rafael-Ramblas commented May 16, 2024

I found one more information about this. This issue only happens for line charts, other types of charts works as expected without having the need to call the requestUpdate method, and adding the line suggested actually causes a runtime error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Unexpected problem or unintended behavior. plugin This feature request should/could be implemented as a Plugin.
Projects
None yet
Development

No branches or pull requests

2 participants