2017-09-23 41 views
0

我正在使用Node.js,Express,Chart.js和EJS模板。我想要一个通过变量和对象列表传递的模板。每个对象都定义了Chart.js在网页中呈现的图表。EJS内联DOM选择器未定义

chart.js之要求您从一个变量,你作为参数传递给new Chart(),但在下面的代码,我EJS引用document它得到一个错误说这是在引用时未定义的DOM存储画布它。我怎样才能解决这个问题?

<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>

下面是根据chart.js之文档的示例的方式来建立的图表:

<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>

对于一些上下文:点为用户能够查看网页并像仪表板一样添加新图表,因此数据库ne编辑存储他们为仪表板制作的每张图表的清单。

感谢您的任何帮助。

+0

让我告诉你一件事.... EJS的模板引擎,运行在后端....你不能把关于文件的后台...你可以做的是使用JavaScript的EJS其打印将运行在客户端....或者使ajax调用服务器来获取数据并使用chartjs制作图表 – Tolsee

+0

感谢您的建议Tolsee。它帮助我意识到我需要AJAX。我对web dev很陌生。我已在下面发布我的解决方案。 – Inertia

回答

0

OKAY!终于在头痛之后才发现它。我的新手技能水平即将明显。

所以事件的顺序就为这样的:在浏览器

  1. 访问地址
  2. 的NodeJS/Express服务器与我没有图表EJS模板
  3. 这EJS模板运行的AJAX脚本响应
  4. AJAX脚本联系服务器以查询MongoDB的图表数据
  5. 服务器从MongoDB中检索图表数据并将其发送回JSON格式的AJAX脚本
  6. AJAX脚本接收的图表数据,并使用$字符串文本格式注入必要的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> 
     ` 
     ); 
    }); 
});