Open
Description
I was doing some benchmarking and noticed a memory leak stemming from having uirevision=1. i comment out the field and no more leak.
I can't say if this is isolated to scatter3d, but thats what I was benchmarking.
i hit the issue only in storybook. porting the same code over to codesandbox does not encounter the leak. likewise if i comment out my <Scatter3D/>
component from the Render, i do not encounter the leak.
apologies in advance if this is a storybook bug and not a plotly bug.
this is all pretty throwaway code half written with claude so forgive me for messiness!
// story
import type { Meta, StoryObj } from "@storybook/react";
import {
useEffect,
useState,
useRef,
useCallback,
useDeferredValue,
} from "react";
import { Scatter3D } from "./Scatter3D";
const meta: Meta<typeof Scatter3D> = {
title: "Charts/Scatter3D",
component: Scatter3D,
parameters: {
layout: "centered",
},
};
export default meta;
// Helper function to generate random data
function generateRandomData(traceCount: number, pointsPerTrace: number) {
return Array.from({ length: traceCount }, (_, traceIndex) => ({
x: Array.from({ length: pointsPerTrace }, () => Math.random() * 100),
y: Array.from({ length: pointsPerTrace }, () => Math.random() * 100),
z: Array.from({ length: pointsPerTrace }, () => Math.random() * 100),
name: `Trace ${traceIndex + 1}`,
}));
}
export const Benchmarking: StoryObj<{
traceCount: number;
updateFrequencyMs: number;
dataPointsPerTrace: number;
}> = {
args: {
traceCount: 1,
dataPointsPerTrace: 10000,
updateFrequencyMs: 100,
},
render:
};
// Scatter3D.tsx
import React, { memo } from "react";
import Plot from "react-plotly.js";
export interface Scatter3DProps {
data: Array<{
x: number[];
y: number[];
z: number[];
name?: string;
}>;
title?: string;
xAxisLabel?: string;
yAxisLabel?: string;
onAfterPlot?: any;
}
const spikeConfig = {
spikethickness: 1,
spikesides: true,
spikecolor: "black",
};
export const Scatter3D = memo(function Scatter3D({
data,
title = "3D Scatter Plot",
xAxisLabel = "X Axis",
yAxisLabel = "Y Axis",
onAfterPlot,
}: Scatter3DProps) {
return (
<Plot
data={data.map((trace, i) => ({
...trace,
type: "scatter3d" as const,
mode: "markers",
marker: {
color: `hsl(${(i * 360) / data.length}, 70%, 50%)`,
size: 2,
opacity: 0.8,
symbol: "circle",
line: { width: 0 },
},
name: trace.name ?? `Trace ${i + 1}`,
}))}
layout={{
width: 500,
height: 500,
scene: {
aspectmode: "cube",
xaxis: { ...spikeConfig, title: xAxisLabel },
yaxis: { ...spikeConfig, title: yAxisLabel },
zaxis: { ...spikeConfig, title: "Z Axis" },
camera: {
up: { z: 1 },
eye: { x: 2, y: 2, z: 1.5 },
},
},
uirevision: 1,
}}
config={{
displaylogo: false,
responsive: true,
plotGlPixelRatio: 1,
showAxisDragHandles: false,
showAxisRangeEntryBoxes: false,
queueLength: 0,
}}
useResizeHandler={false}
onAfterPlot={onAfterPlot}
/>
);
});
Metadata
Metadata
Assignees
Labels
No labels