多个雷达图 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 个图表?还是我遗漏了什么?
如果我只想显示一个图表,我的代码可以正常工作。
可重现的例子:
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>
我正在使用 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 个图表?还是我遗漏了什么?
如果我只想显示一个图表,我的代码可以正常工作。
可重现的例子:
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
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>