我有一个使用React和ObservablePlot以及react-monaco的笔记本项目
我的应用程序上有一个 IDE:
采用这样的用户代码(可观察代码)
Plot.lineY(props.data, { x: "Date", y: "Close" })
然后我将该代码作为道具传递给我的组件
然后我将该 prop 字符串代码传递给 eval
绘图未定义参考错误:绘图未定义
就是用 eval 编译该代码并将返回值放入可观察图的标记中。
或
以某种方式将用户字符串代码转换为JS可读代码
Plot 是一个 npm 包,所以我从它的包中导入它,如下所示
这是我的代码:
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;
我搜索了很多,但没有找到这个问题的答案。任何指导将不胜感激
大家好,可能遇到同样问题的人。
看起来eval不能使用导入的Package;相反,您可以将其存储在一个变量中,该变量在使用 eval 的同一范围内声明。 然后在要传递给 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;
现在,如果您传递如下所示的字符串,您的评估将正常工作。
plotly.lineY(props.data, {x: 'Date', y: 'Close'})