我有一个条形图(使用 chart.js),标签作为图像,当我尝试将 Canvas 导出为图像时,它只导出图表部分而不是图像(标签),但当我右键单击并导出相同的 Canvas 时另存为图像能够正确导出(图表和标签图像)。
谁能帮我解决这个问题。
我的js文件:
var config = {
type: 'horizontalBar',
data: {
labels:['a', 'b', 'c', 'd', 'e', 'f'],
datasets: [
{
data: [ "20", "10", "2", "5", "1", "22" ],
backgroundColor: [ '#f1f33a', '#99d695', "#cc8e50", '#ec9089', '#8e7bd4', '#eef5ce' ]
}]
},
options: {
animation: {
duration: 1,
onComplete: function(charttt) {
var chartInstance = charttt.chart,
ctx = chartInstance.ctx;
ctx.textAlign = 'right';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function (bar, index) {
var img = new Image();
img.src = 'https://i.imgur.com/yDYW1I7.png';
var data = dataset.data[index];
ctx.fillStyle = 'red';
ctx.fillText(data, bar._model.x - 20, bar._model.y - 10);
img.onload = function() {
ctx.drawImage(img, bar._model.x, bar._model.y, 10, 10);
}
});
});
var url = document.getElementById('barChart').toDataURL('image/png');
document.getElementById("testimg").src = url;
}
},
legend: {
"display": false
},
responsive:false,
chartArea: {
backgroundColor: 'blue'
}
}
};
var ctx = document.getElementById("barChart").getContext("2d");
var chartt = new Chart(ctx, config);
最佳答案
我想你的问题就在这里......
this.data.datasets.forEach(function (dataset) {
var meta = chartInstance.controller.getDatasetMeta(i);
您正在尝试获取数据集 i
的元数据
但是 i
没有定义
需要给forEach
函数添加参数
this.data.datasets.forEach(function (dataset, i) { // <-- here
var meta = chartInstance.controller.getDatasetMeta(i);
请参阅以下工作片段...
$(document).ready(function() {
var config = {
type: 'horizontalBar',
data: {
labels:['a', 'b', 'c', 'd', 'e', 'f'],
datasets: [
{
data: [ "20", "10", "2", "5", "1", "22" ],
backgroundColor: [ '#f1f33a', '#99d695', "#cc8e50", '#ec9089', '#8e7bd4', '#eef5ce' ]
}]
},
options: {
animation: {
duration: 1,
onComplete: function(charttt) {
var chartInstance = charttt.chart,
ctx = chartInstance.ctx;
ctx.textAlign = 'right';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function (bar, index) {
var img = new Image();
img.src = 'https://i.imgur.com/yDYW1I7.png';
var data = dataset.data[index];
ctx.fillStyle = 'red';
ctx.fillText(data, bar._model.x - 20, bar._model.y - 10);
img.onload = function() {
ctx.drawImage(img, bar._model.x, bar._model.y, 10, 10);
}
});
});
var url = document.getElementById('barChart').toDataURL('image/png');
document.getElementById("testimg").src = url;
}
},
legend: {
"display": false
},
responsive:false,
chartArea: {
backgroundColor: 'blue'
}
}
};
var ctx = document.getElementById("barChart").getContext("2d");
var chartt = new Chart(ctx, config);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<canvas id="barChart"></canvas>
<img id="testimg"/>
编辑
有两个问题导致图像未出现在导出中。
首先,添加来自另一个域的图像会污染 Canvas 。
之后,安全错误将阻止 Canvas 导出。
解决方法是将 crossorigin
属性添加到要添加到图表的图像。
img.setAttribute('crossorigin', 'anonymous');
接下来,在导出图表之前,
我们必须等待所有图像加载完毕,
在 img.onload
事件中。
请参阅以下工作片段...
$(document).ready(function() {
var config = {
type: 'horizontalBar',
data: {
labels:['a', 'b', 'c', 'd', 'e', 'f'],
datasets: [
{
data: [ "20", "10", "2", "5", "1", "22" ],
backgroundColor: [ '#f1f33a', '#99d695', "#cc8e50", '#ec9089', '#8e7bd4', '#eef5ce' ]
}]
},
options: {
animation: {
duration: 1,
onComplete: function(charttt) {
var chartInstance = charttt.chart,
ctx = chartInstance.ctx;
ctx.textAlign = 'right';
ctx.textBaseline = 'bottom';
var countDatasets = this.data.datasets.length;
this.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
var countMeta = meta.data.length;
meta.data.forEach(function (bar, index) {
var img = new Image();
img.setAttribute('crossorigin', 'anonymous');
img.src = 'https://i.imgur.com/yDYW1I7.png';
var data = dataset.data[index];
ctx.fillStyle = 'red';
ctx.fillText(data, bar._model.x - 20, bar._model.y - 10);
img.onload = function() {
ctx.drawImage(img, bar._model.x, bar._model.y, 10, 10);
countMeta--;
if (countMeta === 0) {
countDatasets--;
}
if ((countDatasets === 0) && (countMeta === 0)) {
var url = document.getElementById('barChart').toDataURL('image/png');
document.getElementById("testimg").src = url;
}
}
});
});
}
},
legend: {
"display": false
},
responsive:false,
chartArea: {
backgroundColor: 'blue'
}
}
};
var ctx = document.getElementById("barChart").getContext("2d");
var chartt = new Chart(ctx, config);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<canvas id="barChart"></canvas>
<img id="testimg"/>
关于javascript - 无法使用 toDataURL() 转换带有图表和图像的 Canvas,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56745980/