我正在使用node.js,Express,Chart.js和EJS用于模板。我想要一个通过一个带有对象列表的变量的模板。每个对象都定义了图表的图表。
Chart.js要求您从DOM中存储帆布,将其作为参数传递给new Chart()
的变量,但在下面的代码中,我的EJS引用document
会出现一个错误,说明它在参考时未定义。我该如何解决这个问题?
<div class='report-content'>
<!-- 'reportSheet' is a variable passed in from the Express route definition. -->
<!-- for each chart object in the list of charts... -->
<% reportSheet.forEach(function(chart){ %>
<!-- create area for that chart -->
<div class="chart-region">
<div class="chart-item">
<h3>Chart Title</h3>
<canvas id="myChart" width="400" height="200"></canvas>
<% var ctx = document.getElementById("myChart"); %>
<% var myChart = new Chart(ctx, chart); %>
</div>
</div>
<% }); %>
</div>
这是根据图表构建图表的示例。
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>
<canvas id="myChart" width="400" height="400"></canvas>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var chart = new Chart(ctx, {
// The type of chart we want to create
type: 'line',
// The data for our dataset
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: [0, 10, 5, 2, 20, 30, 45],
}]
},
// Configuration options go here
options: {}
});
</script>
对于某些上下文:关键是用户能够查看网页并添加仪表板(例如仪表板),因此数据库需要存储它们为仪表板的每个图表的列表。
感谢您的任何帮助。
好吧!终于在头痛后弄清楚了。我的新手技能水平即将显而易见。
因此,事件的顺序如下:
- 访问浏览器中的地址
- nodejs/express服务器使用我的EJS模板响应,没有图表
- EJS模板运行AJAX脚本
- AJAX脚本联系服务器以查询MongoDB以了解我的图表数据
- 服务器从MongoDB检索图表数据,并以JSON格式将其发送回AJAX脚本
- AJAX脚本接收图表数据,并使用$ String格式化以将必要的HTML和新脚本代码注入步骤1 的页面
这是相关代码
页面加载没有图表。我的页面的页脚调用ajax脚本:
</div>
<script src="../../public/ajax.js"></script>
</body>
</html>
ajax脚本从服务器获取图表数据,并将其注入页面:
$.get("/charts", function(data){ // contacts the server route shown in code block below
data = data[1]; // only using first chart in array of charts for now
var chartData = JSON.stringify(data.chart); // 'data.chart' contains nested objects that describe the chart, so it must be stringified (this caused me days of headache)
// Now inject HTML back into original page with multi-line string literal formatting. Could also use regular string concatenation.
$(".report-content").html(
`
<div class="chart-region">
<div class="chart-item">
<h3>${data.chartName}</h3>
<canvas id="${data._id}" width='400' height='200'></canvas>
// script to create a chart
<script>
var ctx = $("#${data._id}");
var chartVar = new Chart(ctx, ${chartData});
</script>
</div>
</div>
`
);
});
服务器的/图表路由看起来像这样:
app.get("/charts", function(req, res){
Charts.find({}, function(err, chart){
if(err){
console.log(err);
} else {
res.json(chart);
}
});
});
就是这样!
现在,我只注入一个图表,但是要加载整个图表,您必须摆脱data = data[1]
并运行一个类似以下内容的循环(请注意,我尚未测试此代码):
$.get("/charts", function(data){ // data contains the entire array of chartContainers
data.forEach(function(chartContainer){ // chartContainer contains a chart's data and metadata about it like a name
var chartData = JSON.stringify(chartContainer.chart); // chartContainer.chart contains the actual chart data that Chart.js needs
$(".report-content").append(
`
<div class="chart-region">
<div class="chart-item">
<h3>${chartContainer.chartName}</h3>
<canvas id="${chartContainer._id}" width='400' height='200'></canvas>
<script>
var ctx = $("#${chartContainer._id}");
var chartVar = new Chart(ctx, ${chartData});
</script>
</div>
</div>
`
);
});
});