我想在 nextjs 中将 canvas 标签与 chartjs 结合起来,问题不是错误而是图表没有显示在图像画布上。我提供以下代码React.useEffect(() => { const
我想在 nextjs 中将 canvas 标签与 chartjs 结合起来,问题不是错误,而是图表没有显示在图像画布上。我提供了以下代码
React.useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
const bgImage = new Image();
bgImage.src = `/v2/donggi/detail.png`;
const resizeCanvas = () => {
const canvasWidth = window.innerWidth;
const canvasHeight = window.innerHeight;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
drawCanvas(canvasWidth, canvasHeight);
};
const drawCanvas = (canvasWidth, canvasHeight) => {
// Get device pixel ratio (for handling high-DPI screens)
const dpr = window.devicePixelRatio || 1;
// Set canvas dimensions based on the device pixel ratio
canvas.width = canvasWidth * dpr;
canvas.height = canvasHeight * dpr;
// Scale the context to handle high-DPI
ctx.scale(dpr, dpr);
ctx.clearRect(0, 0, canvas.width, canvas.height);
const imgAspectRatio = bgImage.width / bgImage.height;
const canvasAspectRatio = canvasWidth / canvasHeight;
let imgWidth, imgHeight;
if (canvasAspectRatio > imgAspectRatio) {
imgHeight = canvasHeight;
imgWidth = imgHeight * imgAspectRatio;
} else {
imgWidth = canvasWidth;
imgHeight = imgWidth / imgAspectRatio;
}
const xOffset = (canvasWidth - imgWidth) / 2;
const yOffset = (canvasHeight - imgHeight) / 2;
// Draw the background image
ctx.drawImage(bgImage, xOffset, yOffset, imgWidth, imgHeight);
// Draw buttons
menuButton.forEach(button => {
const btnX = xOffset + button.x * imgWidth;
const btnY = yOffset + button.y * imgHeight;
const btnWidth = button.width * imgWidth;
const btnHeight = button.height * imgHeight;
// Draw button background
ctx.fillStyle = 'transparent';
ctx.fillRect(btnX, btnY, btnWidth, btnHeight);
// Draw button label
// ctx.fillStyle = 'white';
// ctx.font = `${btnHeight * 0.5}px Arial`;
// ctx.textAlign = 'center';
// ctx.textBaseline = 'middle';
ctx.fillText(button.label, btnX + btnWidth / 2, btnY + btnHeight / 2);
button.bounds = { x: btnX, y: btnY, width: btnWidth, height: btnHeight };
});
// Draw each label on the canvas
detailValue.forEach(label => {
const labelX = xOffset + label.x * imgWidth;
const labelY = yOffset + label.y * imgHeight;
const labelWidth = label.width * imgWidth;
const labelHeight = label.height * imgHeight;
// Set font and style for text
ctx.fillStyle = 'black'; // Text color
ctx.font = `${labelHeight * 0.2}px Arial`;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(label.value, labelX + labelWidth / 2, labelY + labelHeight / 2);
label.bounds = { x: labelX, y: labelY, width: labelWidth, height: labelHeight };
});
lineChart(xOffset, yOffset, imgWidth, imgHeight);
}
问题出在 lineChart 函数上,详细代码如下
const lineChart = (xOffset, yOffset, imgWidth, imgHeight) => {
// Define chart position and size like a button
const chartX = xOffset + 0.65 * imgWidth; // Example x-coordinate for the chart
const chartY = yOffset + 0.25 * imgHeight; // Example y-coordinate for the chart
const chartWidth = 0.3 * imgWidth; // Width of the chart
const chartHeight = 0.5 * imgHeight; // Height of the chart
// Create a new chart instance (within the chart's specific area)
if (chartInstanceRef.current) {
chartInstanceRef.current.destroy(); // Destroy the old chart instance
}
const chartCanvas = document.createElement('canvas');
const chartCtx = chartCanvas.getContext('2d');
// Set chart canvas dimensions and position
chartCanvas.width = chartWidth;
chartCanvas.height = chartHeight;
// document.body.appendChild(chartCanvas); // Debug: Check if chart canvas appears
// Chart.js configuration
chartInstanceRef.current = new Chart(chartCtx, {
type: 'line',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June'],
datasets: [{
label: 'Dataset',
data: [65, 59, 80, 81, 56, 55],
borderColor: 'rgba(75, 192, 192, 1)',
tension: 0.1,
}],
},
options: {
responsive: false, // Disable responsiveness to control chart size manually
plugins: {
legend: { display: true },
title: { display: true, text: 'Line Chart Example' },
},
},
});
// Draw the chart onto the main canvas at the specific position
ctx.drawImage(chartCanvas, chartX, chartY, chartWidth, chartHeight);
}
lineChart 函数中的图表显示/出现在背景图像画布上