Chart.js在一张画布上并排放置两个图表

时间:2019-04-16 18:12:47

标签: javascript charts chart.js

就像标题一样,我想使用一个画布通过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;

图变得混乱,堆积confused plot chart.js

很明显我可以设置

 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>

结果如下所示:
desired result 诸如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忽略了填充或边距。

two charts, buggy

0 个答案:

没有答案