You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过EJS模板将数据传入Google Charts的drawGraphs()函数

如何通过EJS模板将数据传入Google Charts的drawGraphs()函数

嘿,我看你遇到的问题是EJS模板里的前端JavaScript拿不到后端传的graphs变量对吧?其实原因很简单:后端传给EJS的graphs是模板渲染变量,它只在EJS的模板标签(比如<% %>、<%= %>)里有效,直接在前端<script>里写graphs的话,浏览器根本不知道这个变量是什么——因为它不在全局作用域里。

下面给你一步步解决的方法:

第一步:把后端数据转成前端可访问的JS变量

在你的chart.ejs的<script>标签最开头,先添加一行代码,用EJS把后端的graphs对象转换成JSON字符串,再赋值给一个前端全局变量:

// 把后端传的graphs变量转成前端能直接用的JS对象
const graphsData = <%= JSON.stringify(graphs) %>;

这里JSON.stringify(graphs)会把后端的JavaScript对象转成合法的JSON字符串,EJS的<%= %>会直接把这个字符串输出到页面里,所以前端JS会把它当成一个原生的JavaScript对象来解析,这样你就能在前端代码里用graphsData访问到后端的数据了。

第二步:修正前端的图表绘制逻辑

看你后端传的myGraph是单个对象(不是数组),但你原来的drawGraphs()里写了graphs.forEach(g => {})——单个对象是没有forEach方法的,这也是潜在的问题。所以我们要调整drawGraphs()的逻辑,直接处理单个图表:

修改后的drawGraphs()函数应该是这样:

function drawGraphs() {
  console.log("Entered drawGraphs()")
  console.log(graphsData) // 现在用我们定义的前端变量

  // 先添加承载图表的div
  appendDivToBody(graphsData.name, 'width: 1200px; height: 500px');
  // 直接调用drawGraph绘制这个图表
  drawGraph(graphsData.name, graphsData.myData);
}

第三步:完整的修改后chart.ejs代码

把这些修改整合到你的chart.ejs里,完整的<script>部分应该是这样:

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
// 新增:把后端数据转成前端变量
const graphsData = <%= JSON.stringify(graphs) %>;

google.charts.load('current', { 'packages': ['corechart'] });
google.charts.setOnLoadCallback(drawGraphs);

function drawGraphs() {
  console.log("Entered drawGraphs()")
  console.log(graphsData)
  appendDivToBody(graphsData.name, 'width: 1200px; height: 500px');
  // 因为是单个图表,不用forEach,直接调用drawGraph
  drawGraph(graphsData.name, graphsData.myData);
}

function drawGraph(graphName, graphData) {
  var data = new google.visualization.DataTable();
  data.addColumn('string', 'Toppings');
  data.addColumn('number', 'Slices');
  data.addRows(graphData);

  var options = {
    title: `${graphName}`,
    'width': 500,
    'height': 300
  };

  var chart = new google.visualization.PieChart(document.getElementById(graphName));
  chart.draw(data, options);
}

function appendDivToBody(id, style) {
  var div = document.createElement('div');
  div.id = id;
  div.style = style;
  document.getElementsByTagName('body')[0].appendChild(div);
}
</script>

为什么这样能行?

  • JSON.stringify(graphs)保证了后端的JavaScript对象能安全地转换成字符串,然后被前端JS解析成原生对象,不会有语法错误。
  • 把数据赋值给前端的graphsData变量后,drawGraphs()就能在浏览器的全局作用域里访问到它了,不会再出现ReferenceError: graphs is not defined的错误。
  • 修正了forEach的问题,因为你现在传的是单个图表对象,不是数组,直接调用绘制函数就可以了。如果以后你需要传多个图表,只需要把后端的myGraph改成数组(比如let myGraphs = [graph1, graph2]),然后前端用graphsData.forEach(g => {})就可以了。

现在重启你的服务器,访问localhost:3000,应该就能看到饼图正常显示了!

备注:内容来源于stack exchange,提问作者Adrian Hood Sr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 15:24:40