就像标题一样,我想使用一个画布通过chart.js共享。我见过side by side with DOM,但这是另一回事,我需要保留一张画布并保留动画。
我使用Chart.js版本:2.8.0(最新),通过注册插件重新发布图。第一部分在beforeLayout
chart.width = chart.canvas.width * 0.6;
这可以缩放第一幅图,完美地工作,即使工具提示也仅显示在第一幅图区域内。如果我设置了第二个图:
chart.width = chart.canvas.width * 0.4;
chart.options.layout.padding.left = chart.canvas.width * 0.6;
很明显我可以设置
chart.width = chart.canvas.width * 1;
然后重新绘制第一个图,但是也许有一些简单的方法可以使两个(或多个)图共享画布?
从chart.js samples提取并由我修改的代码,以产生最少的工作示例。
<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Line Chart</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
</head>
<body>
<canvas id="canvas" width="1013" height="506" class="chartjs-render-monitor"></canvas>
<br>
<button id="randomizeData">Randomize Data</button>
<script>
var config = {
type: 'bar',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
label: 'My First dataset',
backgroundColor: 'green',
borderColor: 'blue',
data: [
Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random()
],
fill: false,
}, {
label: 'My Second dataset',
fill: false,
backgroundColor: 'blue',
borderColor: 'blue',
data: [
Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random()
],
}]
},
plugins: [{
beforeLayout: function (chart) {
chart.width = chart.canvas.width * 0.6;
chart.options.layout.padding.left = 0;
},
}],
options: {
responsive: true,
title: {
display: true,
text: 'Chart.js Line Chart'
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}]
}
}
};
var config2 = {
type: 'bar',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
label: 'My First dataset',
backgroundColor: 'green',
borderColor: 'blue',
data: [
Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random()
],
fill: false,
}, {
label: 'My Second dataset',
fill: false,
backgroundColor: 'blue',
borderColor: 'blue',
data: [
Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random()
],
}]
},
plugins: [{
beforeLayout: function (chart) {
chart.width = chart.canvas.width * 0.4;
chart.options.layout.padding.left = chart.canvas.width * 0.6;
},
}],
options: {
responsive: true,
title: {
display: true,
text: 'Chart.js Line Chart'
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
window.myLine = new Chart(ctx, config);
window.myLine2 = new Chart(ctx, config2);
};
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return Math.random();
});
});
config2.data.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return Math.random();
});
});
window.myLine.update();
window.myLine2.update();
});
</script>
</body></html>
结果如下所示:
诸如Y轴丢失,图例和标题之类的内容被隐藏
简单的display: false
,然后将第二个的绘图填充顶部设置为第一个的plot chartArea.top,这里的问题是闪烁,经常重绘第一个绘图,它还会接收到悬停事件,因此单独设置填充是行不通的,因此应该会以某种方式偏移第二个绘图集。
现在,我同时努力进行修改并决定自行清除,剩下的越野车是工具提示,在两个图中均触发,并且在两个图中的条之间垂直移动。还需要在调整大小时手动重绘。
<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Line Chart</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
</head>
<body>
<div>
<canvas id="canvas" width="1013" height="506" class="chartjs-render-monitor"></canvas>
</div>
<br>
<button id="randomizeData">Randomize Data</button>
<script>
var config = {
type: 'horizontalBar',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'],
datasets: [{
label: 'My First dataset',
backgroundColor: 'green',
borderColor: 'blue',
data: [
Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random()
]
}, {
backgroundColor: 'blue',
borderColor: 'blue',
data: [
Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random()
],
}]
},
plugins: [{
beforeLayout: function (chart) {
chart.width = chart.canvas.width * 0.55;
chart.options.layout.padding.left = 0;
},
}],
onResize: function() {
console.log(3)
},
options: {
responsive: true,
legend: {
display: false
},
title: {
display: true,
text: 'Chart.js Test double plot'
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'label',
intersect: true
},
scales: {
xAxes: [{
display: false,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
gridLines: {
display:false
}
}]
}
}
};
var config2 = {
type: 'horizontalBar',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
backgroundColor: 'green',
borderColor: 'blue',
data: [
Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random()
],
fill: false,
}, {
backgroundColor: 'blue',
borderColor: 'blue',
data: [
Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random(), Math.random()
],
}]
},
plugins: [{
beforeLayout: function (chart) {
chart.options.layout.padding.left = chart.canvas.width * 0.55;
chart.options.layout.padding.top = myLine.chartArea.top;
},
afterDraw: function (chart) {
myLine.update();
},
}],
options: {
responsive: true,
title: {
display: false,
},
legend: {
display: false
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'label',
intersect: true
},
scales: {
xAxes: [{
gridLines: {
display:false
},
display: false,
scaleLabel: {
display: true,
}
}],
yAxes: [{
display: false,
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
window.myLine = new Chart(ctx, config);
myLine.clear = function() {
var canvas = this.ctx;
canvas.clearRect(0, 0, this.chartArea.right, this.height); return this.canvas;}
window.myLine2 = new Chart(ctx, config2);
myLine2.clear = function() {
var canvas = this.ctx;
canvas.clearRect(this.chartArea.left, 0, this.chartArea.right - this.chartArea.left + 15, this.height); return this.canvas;}
};
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return Math.random();
});
});
config2.data.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return Math.random();
});
});
window.myLine.update();
window.myLine2.update();
});
</script>
</body></html>
它甚至会保留许多更新,但是在动画过程中,工具提示被删除,同时有两个提示。这个结果看起来几乎像最终版本,所以如果有人想知道为什么,这些是相同数据的四个变量,两个耦合的变量。由于只剩下条和工具提示,所以如果没有动画和用于其他绘图的框架,我会自己绘制一些矩形。用于进一步处理的管道需要一个图像,因此按需破解画布来绘制它们都无济于事。
底层的问题是重绘时Chart.js忽略了填充或边距。