I have a notebook project that uses React and ObservablePlot and react-monaco
there's an IDE on my App that :
takes the User Code ( Observable Code ) like this Plot.lineY(props.data, { x: "Date", y: "Close" })
then I pass that code as a prop to my Component
then I pass that prop string code to the eval
Plot is not defined ReferenceError: Plot is not defined
is to Compile that code with eval and put the return value to marks of the Observable plot.
OR
somehow convert user string code to JS readable code
Plot is an npm package so i imported it from its package like below
Here is my Code:
import React, { useEffect, useState, useRef } from "react";
import * as Plot from "@observablehq/plot";
import * as d3 from "d3";
const PlotChart = (props) => {
const containerRef = useRef();
const [data, setData] = useState();
useEffect(() => {
d3.csv("/gistemp.csv", d3.autoType).then(setData);
}, []);
useEffect(() => {
if (data === undefined) return;
const plot = Plot.plot({
marks: [eval(props.plot)],
});
containerRef.current.append(plot);
return () => plot?.remove();
}, [data]);
return <div ref={containerRef} />;
};
export default PlotChart;
I searched a lot and I got no answer for this Problem. Any guide will be appreciate
Hey guys for anyone who might face with same problem.
It looks like the eval can't use the imported Package; instead, you can store it in a variable that is declared in the same scope that the eval gets used. then use that variable name in the string code that you want to pass into eval.
const PlotChart = (props) => {
const containerRef = useRef();
const [data, setData] = useState();
const compileCode = () => {
// store package in a variable
const plotly = Plot;
return eval(props.plot);
};
useEffect(() => {
compileCode();
setData(props.data);
}, []);
useEffect(() => {
if (data === undefined) return;
const plot = Plot.plot({
marks: [compileCode()],
});
containerRef.current.append(plot);
return () => plot?.remove();
}, [data]);
return <div ref={containerRef} />;
};
export default PlotChart;
now if you pass a string like below your eval will work fine.
plotly.lineY(props.data, {x: 'Date', y: 'Close'})