多个雷达图 MDB 未显示

Multiple Radar Charts MDB not showing

我正在使用 MDB 图表,特别是雷达图表:https://mdbootstrap.com/docs/jquery/javascript/charts/

HTML

<!-- MDB core JavaScript -->
<script type="text/javascript" src="../static/js/mdb.min.js"></script>

<div id='canvas_div'></div>

JavaScript

const ids_list = [0,1,2,3,4,5];
var canvas_div = document.getElementById('canvas_div');
for (var i=0; i<ids_list.length; i++){
    canvas_div.innerHTML += "<canvas id='"+ids_list[i]+"'></canvas>";
    generate_chart(ids_list[i], foo_list1, foo_list2);
}

function generate_chart(chartID,foo_list1,foo_list2){
    var ctxR = document.getElementById(chartID).getContext('2d');
        var myRadarChart = new Chart(ctxR, {
          type: 'radar',
          data: {
            labels: Object.keys(foo_list1),
            datasets: [
              {
                label: "Your FOO LIST1",
                data: Object.values(foo_list1),
                backgroundColor: ['rgba(105, 0, 132, .2)',],
                borderColor: ['rgba(200, 99, 132, .7)',],
                borderWidth: 2
              },{
                label: "Your FOO LIST2",
                data: Object.values(foo_list2),
                backgroundColor: ['rgba(0, 250, 220, .2)',],
                borderColor: ['rgba(0, 213, 132, .7)',],
                borderWidth: 1
              }
            ]
          },
          options: {responsive: false}
        });
}

现在,我希望得到我的 ids_list 的每个值的图表。相反,我只得到最后一张图表。是否有可能我不能使用 MDB 图表每页显示超过 1 个图表?还是我遗漏了什么?

如果我只想显示一个图表,我的代码可以正常工作。

可重现的例子:

link to GitHub Repo

Download My example from Google drive

赏金更新:这实际上是我想要做的:

正如您在检查器中看到的那样,生成的第二个 canvas 附有图表,而第一个没有。以下是我的应用程序中的 generate_chart 函数:

//radar
      function generate_chart(chartID,last_scores,best_scores){
        var ctxR = document.getElementById(chartID).getContext('2d');
        console.log(ctxR);
        var myRadarChart = new Chart(ctxR, {
          type: 'radar',
          data: {
            labels: Object.keys(last_scores),
            datasets: [
              {
                label: "Your Last Score",
                data: Object.values(last_scores),
                backgroundColor: ['rgba(105, 0, 132, .2)',],
                borderColor: ['rgba(200, 99, 132, .7)',],
                borderWidth: 2
              },{
                label: "Your Best Score",
                data: Object.values(best_scores),
                backgroundColor: ['rgba(0, 250, 220, .2)',],
                borderColor: ['rgba(0, 213, 132, .7)',],
                borderWidth: 1
              }
            ]
          },
          options: {responsive: false}
        });
        console.log(myRadarChart);
      }

哪个控制台日志 returns 以下内容:

--------------------------------------
CanvasRenderingContext2D

canvas: <canvas id="viRE6FIudKYBbuREGRU14GXLepI3" style="display: block;" height="150">
fillStyle: "rgba(0, 0, 0, 0.1)"
​filter: "none"
​font: "10px \"Helvetica Neue\", \"Helvetica\", \"Arial\", sans-serif"
​globalAlpha: 1
​globalCompositeOperation: "source-over"
​imageSmoothingEnabled: true
​lineCap: "butt"
​lineDashOffset: 0
​lineJoin: "miter"
​lineWidth: 1
​miterLimit: 10
​mozCurrentTransform: Array(6) [ 1, 0, 0, … ]
​mozCurrentTransformInverse: Array(6) [ 1, -0, -0, … ]
​mozImageSmoothingEnabled: true
​mozTextStyle: "10px \"Helvetica Neue\", \"Helvetica\", \"Arial\", sans-serif"
​shadowBlur: 0
​shadowColor: "rgba(0, 0, 0, 0)"
​shadowOffsetX: 0
​shadowOffsetY: 0
​strokeStyle: "rgba(0, 0, 0, 0.1)"
​textAlign: "center"
​textBaseline: "top"
​<prototype>: CanvasRenderingContext2DPrototype { drawImage: drawImage(), beginPath: beginPath(), fill: fill(), … }
read_article.html:625:17
{…}

--------------------------------------
​
"$plugins": Object { descriptors: (3) […], id: 4 }
​
_bufferedRender: false
​_listeners: Object { mousemove: n(), mouseout: n(), click: n()
, … }
​animating: false
​aspectRatio: 2
​boxes: Array(3) [ {…}, {…}, {…} ]
​canvas: <canvas id="viRE6FIudKYBbuREGRU14GXLepI3" style="display: block;" height="150">
​chart: Object { id: 0, width: 300, height: 150, … }
​chartArea: Object { left: 0, top: 32, right: 300, … }
​config: Object { type: "radar", data: {…}, options: {…} }
​controller: Object { id: 0, width: 300, height: 150, … }
​ctx: CanvasRenderingContext2D { mozTextStyle: "10px \"Helvetica Neue\", \"Helvetica\", \"Arial\", sans-serif", mozImageSmoothingEnabled: true, globalAlpha: 1, … }
​currentDevicePixelRatio: 1
​data: 
​height: 150
​id: 0
​lastActive: Array []
​legend: Object { doughnutMode: false, fullWidth: true, position: "top", … }
​options: Object { responsive: false, responsiveAnimationDuration: 0, maintainAspectRatio: true, … }
​scale: Object { id: "scale", type: "radialLinear", hidden: false, … }
​scales: Object { scale: {…} }
​titleBlock: Object { fullWidth: true, position: "top", weight: 2000, … }
​tooltip: Object { _chart: {…}, _chartInstance: {…}, _data: {…}, … }
​width: 300
​<get data()>: function get()​
<set data()>: function set(t)​
<prototype>: Object { construct: construct(e, n), initialize: initialize(), clear: clear()
, … }
read_article.html:648:17

--------------------------------------

CanvasRenderingContext2D
​canvas: <canvas id="Eb31hrWcNgZh1FdGiBxVaz3FOnt1" style="display: block;" height="150">
​fillStyle: "rgba(0, 0, 0, 0.1)"
​filter: "none"
​font: "10px \"Helvetica Neue\", \"Helvetica\", \"Arial\", sans-serif"
​globalAlpha: 1
​globalCompositeOperation: "source-over"
​imageSmoothingEnabled: true
​lineCap: "butt"
​lineDashOffset: 0
​lineJoin: "miter"
​lineWidth: 1
​miterLimit: 10
​mozCurrentTransform: Array(6) [ 1, 0, 0, … ]
​mozCurrentTransformInverse: Array(6) [ 1, -0, -0, … ]
​mozImageSmoothingEnabled: true
​mozTextStyle: "10px \"Helvetica Neue\", \"Helvetica\", \"Arial\", sans-serif"
​shadowBlur: 0
​shadowColor: "rgba(0, 0, 0, 0)"
​shadowOffsetX: 0
​shadowOffsetY: 0
​strokeStyle: "rgba(0, 0, 0, 0.1)"
​textAlign: "center"
​textBaseline: "top"
​<prototype>: CanvasRenderingContext2DPrototype { drawImage: drawImage(), beginPath: beginPath(), fill: fill(), … }
read_article.html:625:17
{…}

--------------------------------------
​
"$plugins": Object { descriptors: (3) […], id: 4 }
​
_bufferedRender: false
​_listeners: Object { mousemove: n(), mouseout: n(), click: n()
, … }
​animating: false
​aspectRatio: 2
​boxes: Array(3) [ {…}, {…}, {…} ]
​canvas: <canvas id="Eb31hrWcNgZh1FdGiBxVaz3FOnt1" style="display: block;" height="150">​
chart: Object { id: 1, width: 300, height: 150, … }
​chartArea: Object { left: 0, top: 32, right: 300, … }
​config: Object { type: "radar", data: {…}, options: {…} }
​controller: Object { id: 1, width: 300, height: 150, … }
​ctx: CanvasRenderingContext2D { mozTextStyle: "10px \"Helvetica Neue\", \"Helvetica\", \"Arial\", sans-serif", mozImageSmoothingEnabled: true, globalAlpha: 1, … }
​currentDevicePixelRatio: 1
​data: 
​height: 150
​id: 1
​lastActive: Array []
​legend: Object { doughnutMode: false, fullWidth: true, position: "top", … }
​options: Object { responsive: false, responsiveAnimationDuration: 0, maintainAspectRatio: true, … }
​scale: Object { id: "scale", type: "radialLinear", hidden: false, … }
​scales: Object { scale: {…} }
​titleBlock: Object { fullWidth: true, position: "top", weight: 2000, … }
​tooltip: Object { _chart: {…}, _chartInstance: {…}, _data: {…}, … }
​width: 300
​<get data()>: function get()​
<set data()>: function set(t)​
<prototype>: Object { construct: construct(e, n), initialize: initialize(), clear: clear(), … }

我还在此处添加调用 generate_chart 函数的 for 循环:

function populate_leaderboard(authorID,submissions,profiles){
        var leaderboard_div = document.getElementById('leaderboard_feed');
        leaderboard_div.innerHTML = '';
        scores_dict = {};
        last_submissions = {};
        best_submissions = {};
        for (var i=0; i<submissions.length; i++){
          sub_user = submissions[i];
          for (var k=0; k<Object.keys(sub_user).length; k++){
            sub = sub_user[Object.keys(sub_user)[k]];
            if (scores_dict[sub['author']]){
              if (scores_dict[sub['author']] < sub['weighted_score']){
                scores_dict[sub['author']] = sub['weighted_score'];
                best_submissions[sub['author']] = sub['scores'];
              }
            } else {
              scores_dict[sub['author']] = sub['weighted_score'];
              best_submissions[sub['author']] = sub['scores'];
            }
            last_submissions[sub['author']] = sub['scores'];
          }
        }

        const lead_array = Object.entries(scores_dict).sort(([,a], [,b]) => b-a).map(([p]) => p);

        let medals = {
          1 : 'Gold Medal',
          2 : 'Silver Medal',
          3 : 'Bronze Medal'
        }

        for (var i=0; i<lead_array.length; i++){
          var medal = '';
          var u = lead_array[i];
          var position = i+1;
          if (i>0 && scores_dict[u] == scores_dict[lead_array[i-1]]) {
            position = position-1;
          }
          medal = medals[position]
          var temp_feed = '';
          temp_feed += "<div class='horiz_line'></div><div class='row centered'>"
          temp_feed += "<div class='col'><img class='profile_picture_leaderboard nomargin' src='"+profiles[u]['profile']['img']+"' alt='profile_picture'>";
          temp_feed += "<p class='nomargin'>"+profiles[u]['profile']['name']+" "+profiles[u]['profile']['surname']+"</p></div><div class='col' align='center'>";
          temp_feed += "<canvas id='"+u+"'></canvas></div><div class='col'>";
          temp_feed += "<p>"+position+" of "+lead_array.length+" on the <strong>Public</strong> Leaderboard</p>";
          temp_feed += "<h3>"+medal+"</h3><div class='progress'>";

          var delta = lead_array.length - (position-1);
          if (delta == 0){
            delta += 0.1;
          }
          var progress = Math.round((delta / lead_array.length) * 100);
          temp_feed += "<div class='progress-bar' role='progressbar' style='width:"+progress+"%' aria-valuenow='"+progress+"' aria-valuemin='0' aria-valuemax='100'></div></div>";
          if (UID == authorID || UID == u){
            temp_feed += "<button style='font-size:70%; margin-top:10px;'>Download Submission <i class='fas fa-cloud-download-alt'></i></button>";
          }
          temp_feed += "</div></div>";
          leaderboard_div.innerHTML += temp_feed;
          generate_chart(u,last_submissions[u],best_submissions[u]);
        }

      }

这里,每次循环,你都在覆盖 canvas_div
的内容 这样在循环结束时,只有一个 canvas 存在。

canvas_div.innerHTML = "<canvas id='"+ids_list[i]+"'></canvas>";

你应该在每个循环中附加一个新的 canvas。

canvas_div.innerHTML += "<canvas id='"+ids_list[i]+"'></canvas>";

编辑

而不是将 html 添加为字符串,在这里...

canvas_div.innerHTML += "<canvas id='"+ids_list[i]+"'></canvas>";

使用 --> document.createElement

创建 canvas 元素
var canvas = canvas_div.appendChild(document.createElement('canvas'));
canvas.id = chartID;

请参阅以下工作片段...

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <link href="https://fonts.googleapis.com/css?family=Lato:300,300i,400,400i,700,700i,900&display=swap" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Noto+Serif:400,400i,700,700i&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">


    <script src="https://kit.fontawesome.com/c346c28ff4.js" crossorigin="anonymous"></script>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <!-- AJAX -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
    <!-- MDB core JavaScript -->
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.14.1/js/mdb.min.js"></script>

  </head>

  <body>


    <div id='canvas_div'></div>

    <script>

      const foo_list1 = [1,2,3,4,5];
      const foo_list2 = [5,4,3,2,1];

      const ids_list = [0,1,2,3,4,5];
      var canvas_div = document.getElementById('canvas_div');
      for (var i=0; i<ids_list.length; i++){
          generate_chart(ids_list[i], foo_list1, foo_list2);
      }

      function generate_chart(chartID,foo_list1,foo_list2){
          var canvas = canvas_div.appendChild(document.createElement('canvas'));
          canvas.id = chartID;
          var ctxR = canvas.getContext('2d');
          var myRadarChart = new Chart(ctxR, {
            type: 'radar',
            data: {
              labels: Object.keys(foo_list1),
              datasets: [
                {
                  label: "Your FOO LIST1",
                  data: Object.values(foo_list1),
                  backgroundColor: ['rgba(105, 0, 132, .2)',],
                  borderColor: ['rgba(200, 99, 132, .7)',],
                  borderWidth: 2
                },{
                  label: "Your FOO LIST2",
                  data: Object.values(foo_list2),
                  backgroundColor: ['rgba(0, 250, 220, .2)',],
                  borderColor: ['rgba(0, 213, 132, .7)',],
                  borderWidth: 1
                }
              ]
            },
            options: {responsive: false}
          });
      }

    </script>

  </body>
</html>


编辑 2

按照第一个解决方案的方法,尝试以下...

populate_leaderboard函数中,
temp_feed 中删除 canvas 元素并将 id 添加到父元素 <div>.
请参阅以下代码段..

    for (var i=0; i<lead_array.length; i++){
      var medal = '';
      var u = lead_array[i];
      var position = i+1;
      if (i>0 && scores_dict[u] == scores_dict[lead_array[i-1]]) {
        position = position-1;
      }
      medal = medals[position]
      var temp_feed = '';
      temp_feed += "<div class='horiz_line'></div><div class='row centered'>"
      temp_feed += "<div class='col'><img class='profile_picture_leaderboard nomargin' src='"+profiles[u]['profile']['img']+"' alt='profile_picture'>";

      // remove canvas, add id
      temp_feed += "<p class='nomargin'>"+profiles[u]['profile']['name']+" "+profiles[u]['profile']['surname']+"</p></div><div class='col' align='center' id='"+u+"'>";
      temp_feed += "</div><div class='col'>";
      temp_feed += "<p>"+position+" of "+lead_array.length+" on the <strong>Public</strong> Leaderboard</p>";
      temp_feed += "<h3>"+medal+"</h3><div class='progress'>";

      var delta = lead_array.length - (position-1);
      if (delta == 0){
        delta += 0.1;
      }
      var progress = Math.round((delta / lead_array.length) * 100);
      temp_feed += "<div class='progress-bar' role='progressbar' style='width:"+progress+"%' aria-valuenow='"+progress+"' aria-valuemin='0' aria-valuemax='100'></div></div>";
      if (UID == authorID || UID == u){
        temp_feed += "<button style='font-size:70%; margin-top:10px;'>Download Submission <i class='fas fa-cloud-download-alt'></i></button>";
      }
      temp_feed += "</div></div>";
      leaderboard_div.innerHTML += temp_feed;
      generate_chart(u,last_submissions[u],best_submissions[u]);
    }

  }

然后在generate_chart函数中,
使用与先前解决方案类似的方法。
请参阅以下片段...

  function generate_chart(chartID,last_scores,best_scores){
    var canvas_div = document.getElementById(chartID);
    var canvas = canvas_div.appendChild(document.createElement('canvas'));
    var ctxR = canvas.getContext('2d');
    var myRadarChart = new Chart(ctxR, {
      type: 'radar',
      data: {
        labels: Object.keys(last_scores),
        datasets: [
          {
            label: "Your Last Score",
            data: Object.values(last_scores),
            backgroundColor: ['rgba(105, 0, 132, .2)',],
            borderColor: ['rgba(200, 99, 132, .7)',],
            borderWidth: 2
          },{
            label: "Your Best Score",
            data: Object.values(best_scores),
            backgroundColor: ['rgba(0, 250, 220, .2)',],
            borderColor: ['rgba(0, 213, 132, .7)',],
            borderWidth: 1
          }
        ]
      },
      options: {responsive: false}
    });
  }

编辑 3

另一种方法是先加载所有内容,
然后,返回并添加图表。

请参阅以下工作片段,
在尝试绘制图表之前添加所有内容。
class 名称用于查找 canvas 元素...

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <link href="https://fonts.googleapis.com/css?family=Lato:300,300i,400,400i,700,700i,900&display=swap" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Noto+Serif:400,400i,700,700i&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">


    <script src="https://kit.fontawesome.com/c346c28ff4.js" crossorigin="anonymous"></script>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <!-- AJAX -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
    <!-- MDB core JavaScript -->
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.14.1/js/mdb.min.js"></script>

  </head>

  <body>


    <div id='canvas_div'></div>

    <script>

      const foo_list1 = [1,2,3,4,5];
      const foo_list2 = [5,4,3,2,1];
      const ids_list = [0,1,2,3,4,5];
      var canvas_div = document.getElementById('canvas_div');

      for (var i=0; i<ids_list.length; i++){
        canvas_div.innerHTML += "<canvas class='chart' id='"+ids_list[i]+"'></canvas>";
      }

      var charts = document.getElementsByClassName('chart');
      Array.prototype.forEach.call(charts, function(canvas) {
        var ctxR = canvas.getContext('2d');
        var myRadarChart = new Chart(ctxR, {
          type: 'radar',
          data: {
            labels: Object.keys(foo_list1),
            datasets: [
              {
                label: "Your FOO LIST1",
                data: Object.values(foo_list1),
                backgroundColor: ['rgba(105, 0, 132, .2)',],
                borderColor: ['rgba(200, 99, 132, .7)',],
                borderWidth: 2
              },{
                label: "Your FOO LIST2",
                data: Object.values(foo_list2),
                backgroundColor: ['rgba(0, 250, 220, .2)',],
                borderColor: ['rgba(0, 213, 132, .7)',],
                borderWidth: 1
              }
            ]
          },
          options: {responsive: false}
        });
      });

    </script>

  </body>
</html>