问题描述
我想使用Chart.js重写,我很难搞清楚如何使用让日期/时间图表交互工作。如果您尝试在中选择日期范围,您会看到它会过滤其他图表。如何让Chart.js让我在其时间尺度图表上选择这样的范围?它似乎默认只允许我点击特定的日期点。
I'd like to rewrite vizwit using Chart.js, and I'm having a hard time figuring out how to get the date/time chart interaction to work. If you try selecting a date range on this demo, you'll see that it filters the other charts. How do I get Chart.js to let me select a range like that on its time scale chart? It seems like by default it only lets me click on a specific date point.
感谢您的时间。
推荐答案
在@ jordanwillis和你的答案的基础上,你可以通过在你的图表上放置另一个画布来轻松实现你想要的任何东西。
只需添加 pointer-events:none
以确保它不与图表的事件相关的样式。
无需使用注释插件。
例如(在此示例中 canvas
是原始图表画布, overlay
是您的新画布放在顶部) :
Building on @jordanwillis's and your answers, you can easily achieve anything you want, by placing another canvas on top on your chart.
Just add pointer-events:none
to it's style to make sure it doesn't intefere with the chart's events.
No need to use the annotations plugin.
For example (in this example canvas
is the original chart canvas and overlay
is your new canvas placed on top):
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1
}
]
},
options: {
scales: {
yAxes: [{
ticks: {
reverse: false
}
}]
}
}
}
var canvas = document.getElementById('chartJSContainer');
var ctx = canvas.getContext('2d');
var chart = new Chart(ctx, options);
var overlay = document.getElementById('overlay');
var startIndex = 0;
overlay.width = canvas.width;
overlay.height = canvas.height;
var selectionContext = overlay.getContext('2d');
var selectionRect = {
w: 0,
startX: 0,
startY: 0
};
var drag = false;
canvas.addEventListener('pointerdown', evt => {
const points = chart.getElementsAtEventForMode(evt, 'index', {
intersect: false
});
startIndex = points[0]._index;
const rect = canvas.getBoundingClientRect();
selectionRect.startX = evt.clientX - rect.left;
selectionRect.startY = chart.chartArea.top;
drag = true;
// save points[0]._index for filtering
});
canvas.addEventListener('pointermove', evt => {
const rect = canvas.getBoundingClientRect();
if (drag) {
const rect = canvas.getBoundingClientRect();
selectionRect.w = (evt.clientX - rect.left) - selectionRect.startX;
selectionContext.globalAlpha = 0.5;
selectionContext.clearRect(0, 0, canvas.width, canvas.height);
selectionContext.fillRect(selectionRect.startX,
selectionRect.startY,
selectionRect.w,
chart.chartArea.bottom - chart.chartArea.top);
} else {
selectionContext.clearRect(0, 0, canvas.width, canvas.height);
var x = evt.clientX - rect.left;
if (x > chart.chartArea.left) {
selectionContext.fillRect(x,
chart.chartArea.top,
1,
chart.chartArea.bottom - chart.chartArea.top);
}
}
});
canvas.addEventListener('pointerup', evt => {
const points = chart.getElementsAtEventForMode(evt, 'index', {
intersect: false
});
drag = false;
console.log('implement filter between ' + options.data.labels[startIndex] + ' and ' + options.data.labels[points[0]._index]);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.js"></script>
<body>
<canvas id="overlay" width="600" height="400" style="position:absolute;pointer-events:none;"></canvas>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
</body>
请注意,我们将事件和坐标基于原始画布,但我们在叠加层上绘制。这样我们就不会弄乱图表的功能。
Notice we're basing our events and coordinates on the original canvas, but we draw on the overlay. This way we don't mess the chart's functionality.
这篇关于如何选择日期范围(如onClick但拖动/选择)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!