File size: 1,305 Bytes
1db9b28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import { lazy, Suspense } from "react";
import type { Data, Layout } from "plotly.js";

const LazyPlot = lazy(async () => {
  const [{ default: Plotly }, { default: createPlotlyComponent }] = await Promise.all([
    // @ts-expect-error plotly.js-dist-min ships no type declarations; runtime shape matches plotly.js
    import("plotly.js-dist-min"),
    import("react-plotly.js/factory"),
  ]);
  return { default: createPlotlyComponent(Plotly) };
});

export interface PlotlyChartSpec {
  schema?: string;
  chart_type?: string;
  title?: string;
  plotly: {
    data: Data[];
    layout?: Partial<Layout>;
  };
}

export function PlotlyChartBlock({ spec }: { spec: PlotlyChartSpec }) {
  if (!spec?.plotly?.data) return null;

  return (
    <div className="my-3 max-w-full overflow-x-auto rounded-lg border border-slate-200 bg-white p-2">
      <Suspense
        fallback={
          <div className="flex h-64 items-center justify-center text-xs text-slate-400">Loading chart…</div>
        }
      >
        <LazyPlot
          data={spec.plotly.data}
          layout={{ autosize: true, ...spec.plotly.layout }}
          config={{ displaylogo: false, responsive: true }}
          style={{ width: "100%", height: "360px" }}
          useResizeHandler
        />
      </Suspense>
    </div>
  );
}