我想重寫使用Chart.js vizwit,我很難找出如何獲得日期/時間圖交互工作。如果您嘗試在this demo上選擇日期範圍,則會看到它過濾了其他圖表。我如何讓Chart.js讓我在時間尺度圖上選擇一個範圍?它似乎默認情況下只能讓我點擊某個特定的日期點。我如何選擇日期範圍(如onClick,但拖動/選擇)
謝謝你的時間。
我想重寫使用Chart.js vizwit,我很難找出如何獲得日期/時間圖交互工作。如果您嘗試在this demo上選擇日期範圍,則會看到它過濾了其他圖表。我如何讓Chart.js讓我在時間尺度圖上選擇一個範圍?它似乎默認情況下只能讓我點擊某個特定的日期點。我如何選擇日期範圍(如onClick,但拖動/選擇)
謝謝你的時間。
以@ jordanwillis's和你的答案爲基礎,通過在圖表上放置另一個畫布,可以輕鬆實現任何你想要的。
只需將pointer-events:none
添加到它的樣式中,以確保它不會干擾圖表的事件。
無需使用註釋插件。
例如(在這個例子中canvas
是原始圖表畫布,overlay
是您的新畫布放置在頂部):
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>
注意到,我們立足我們的活動,並在原來的座標畫布,但我們繪製覆蓋。這樣我們就不會弄亂圖表的功能。
不幸的是,沒有像這樣的東西被內置到chart.js中。您必須實現您自己的事件掛鉤和處理程序,這些掛鉤和處理程序會在圖表上呈現突出顯示的部分,然後使用原型方法來確定哪些數據已突出顯示。即使這些內置的鉤子可能不足以實現你想要的東西。
事件鉤選項是:
添加的事件處理程序的畫布元件本身上(見下面的例子)
canvas.onclick = function(evt){
var activePoints = myLineChart.getElementsAtEvent(evt);
// => activePoints is an array of points on the canvas that are at the same position as the click event.
};
使用onClick
添加事件處理程序的chart.js之圖表對象上配置選項(explained here)。
擴展一些核心圖表事件掛鉤並添加自己的。 (有關指導,請參見here)。
假設這種方法可行,那麼你可以再相應地過濾原始的圖表數據陣列(在基礎chart.js之對象),並調用.update()
原型法繪製新圖。
根據@jordanwillis'幾個月後更新'回答:我已經有了範圍選擇的開始。
canvas.onpointerdown = function (evt) {
clearAnnotations()
const points = chart.getElementsAtEventForMode(evt, 'index', { intersect: false })
const label = chart.data.labels[points[0]._index]
addAnnotation(label)
}
canvas.onpointerup = function (evt) {
const points = chart.getElementsAtEventForMode(evt, 'index', { intersect: false })
const label = chart.data.labels[points[0]._index]
addAnnotation(label)
}
function clearAnnotations() {
if (chart.options.annotation) {
chart.options.annotation.annotations = []
}
}
function addAnnotation (label) {
const annotation = {
scaleID: 'x-axis-0',
type: 'line',
mode: 'vertical',
value: label,
borderColor: 'red'
}
chart.options.annotation = chart.options.annotation || {}
chart.options.annotation.annotations = chart.options.annotation.annotations || []
chart.options.annotation.annotations.push(annotation)
chart.update()
}
仍需要弄清楚如何顯示視覺懸停指標,因爲在這個問題聯繫了演示,但它是一個開始。
非常感謝!這個例子看起來不錯。 –
不客氣,很高興幫助 –