我想使用谷歌图表。此处给出的快速入门示例: https://developers.google.com/chart/interactive/docs/quick_start 显式定义 HTML 文件中的数据。我想使用 EJS 模板动态地执行此操作。我的问题是如何将数据传递到drawChart()
我的 chart.js 和 chart.ejs 文件如下
chart.js
import { dirname } from "path";
import express from "express"
import { fileURLToPath } from "url";
// A note on where this project left off on 8/14/2023
// The goal is to use Google Chart as a dashboard
// showing database data as a collection of charts and graphs
// The chart.ejs file is used as the template to render the page
// One key hurdle is how to get the data into the .ejs file so it
// can be used by the file's javascript code and not just the html
// code.
//
// For example,
// <body>
// <% console.log(graphs.name) %>
// <% console.log(graphs.myData) %>
// </body>
// renders just fine on the page
const __dirname = dirname(fileURLToPath(import.meta.url));
let myData = [
['Mushrooms', 3],
['Onions', 1],
['Olives', 1],
['Zucchini', 1],
['Pepperoni', 2],
['Pineapple',12],
['Green Peppers',22]
]
let myGraph ={}
myGraph.name="First Chart"
myGraph.myData=myData
const app = express();
app.get('/', (req, res) => {
const templatePath = __dirname+"/views/chart.ejs";
res.render(templatePath,{ graphs: myGraph })
});
app.listen(3000, () => {
console.log("Server running on localhost:3000")
});
这是我的 chart.ejs 文件:
<!DOCTYPE html>
<html lang="en">
</html>
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', { 'packages': ['corechart'] });
google.charts.setOnLoadCallback(drawGraphs);
function drawGraphs() {
console.log("Entered drawGraphs()")
console.log(graphs)
appendDivToBody(graphs.name, 'width: 1200px; height: 500px');
graphs.forEach(g => {
appendDivToBody(g.name, 'width: 1200px; height: 500px');
drawGraph(g.name, g.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>
</head>
<body>
<% console.log(graphs.name) %>
<% console.log(graphs.myData) %>
<p>
<!-- HTML content goes here -->
Hello
</p>
<ul>
<%graphs.myData.forEach((item)=> { %>
<li>
I had <%=item[1] %> slices of <%=item[0]%> pizza </br>
</li>
<%})%>
</ul>
</body>
</body>
</html>
它仅在没有图表的情况下产生此输出。
Hello
I had 3 slices of Mushrooms pizza
I had 1 slices of Onions pizza
I had 1 slices of Olives pizza
I had 1 slices of Zucchini pizza
I had 2 slices of Pepperoni pizza
I had 12 slices of Pineapple pizza
I had 22 slices of Green Peppers pizza
使用 Chrome-Inspect 查看 consol.log() 输出 ==> 我看到错误:
Uncaught (in promise) ReferenceError: graphs is not defined
这表明 drawGraphics() 没有看到 graphs JSON 对象。我怎样才能做到这一点?
基于这个答案:ejs 渲染 JSON
您应该能够将 json 写入页面的变量中,如下所示...
var graphs = <%- JSON.stringify(graphs) %>;
这里...
function drawGraphs() {
var graphs = <%- JSON.stringify(graphs) %>; // write json here
appendDivToBody(graphs.name, 'width: 1200px; height: 500px');
graphs.forEach(g => {
appendDivToBody(g.name, 'width: 1200px; height: 500px');
drawGraph(g.name, g.myData);
});
}
那么其余代码应该可以正常工作了
google.charts.load('current', { 'packages': ['corechart'] });
google.charts.setOnLoadCallback(drawGraphs);
function drawGraphs() {
var graphs = <%- JSON.stringify(graphs) %>;
appendDivToBody(graphs.name, 'width: 1200px; height: 500px');
graphs.forEach(g => {
appendDivToBody(g.name, 'width: 1200px; height: 500px');
drawGraph(g.name, g.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);
}