我正在开发一个使用 Chart.js 来显示条形图的 React 应用程序。我遇到一个问题,条形图中的工具提示将时间数据显示为点,而不是所需格式的 HH:MM:SS。我已经尝试了多种方法来正确设置工具提示的格式,但到目前为止,没有一种方法有效。
详情:
将鼠标悬停在图表中的条形上时,工具提示会以点为单位显示时间数据(例如,
1.5, 2.3
),而不是所需的格式 HH:MM:SS(例如,01:00:00
、02:00:00
)。
我在 Chart.js 选项中实现了自定义工具提示回调函数,将总秒数转换为 HH:MM:SS 格式。然而,这种方法并没有解决问题。
代码:
import {
BarElement,
CategoryScale,
Chart as ChartJS,
Legend,
LinearScale,
Title,
Tooltip,
} from 'chart.js';
import React from 'react';
import { Bar } from 'react-chartjs-2';
ChartJS.register(
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend
);
export function convertTimeFormat(fractionalHour) {
// Convert fractional part to minutes
var minutes = Math.floor((fractionalHour % 1) * 60);
// Extract whole number part as hours
var hours = Math.floor(fractionalHour);
// Convert remaining decimal part to seconds
var seconds = Math.floor(((fractionalHour % 1) * 60 - minutes) * 60);
// Format the time as HH:MM:SS
var formattedTime = padZero(hours) + ":" + padZero(minutes) + ":" + padZero(seconds);
return formattedTime;
}
const options = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
position: 'top',
},
},
tooltip: {
callbacks: {
label: function (tooltipItem, data) {
return convertTimeFormat(tooltipItem.parsed);
},
}
},
scales: {
x: {
ticks: {
autoSkip: true,
// maxTicksLimit: 12, // Set the maximum number of x-axis ticks
},
grid: {
display: false, // Hide vertical grid lines
},
},
y: {
ticks: {
min: 0, // Set the minimum value for the y-axis
max: 20, // Set the maximum value for the y-axis
maxTicksLimit: 6, // Set the maximum number of x-axis ticks
callback: function (value, index, values) {
return value
},
},
},
},
};
// Initialize the usedColors array outside the component or wherever you are managing state
const usedColors = [];
// Function to generate a random color
function getRandomColor() {
const colors = ["#FFD147", "#BD9AF8", "#B6F09C", "#FF9C9C", "#9ADBF8", "#9CF8E8", "#F8E89A", "#F89A9A", "#F89AD3", "#9AF8B5"];
// Filter out used colors
const availableColors = colors.filter(color => !usedColors.includes(color));
// If there are available colors, use one of them; otherwise, generate a new light color
if (availableColors.length > 0) {
const randomIndex = Math.floor(Math.random() * availableColors.length);
const color = availableColors[randomIndex];
usedColors.push(color);
return color;
} else {
const lightColor = generateLightColor();
usedColors.push(lightColor);
return lightColor;
}
}
function generateLightColor() {
const letters = '89ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 8)];
}
return color;
}
export function DashGroupBarChart({ styles, barData }) {
const dates = barData?.map(entry => entry?.date);
const usernames = Array.from(new Set(barData.flatMap(entry => entry.data.map(item => item.username))));
const datasets = usernames.map(username => ({
label: username,
data: dates.map(date => {
const dateEntry = barData.find(item => item.date === date);
const userData = dateEntry ? dateEntry.data.find(item => item.username === username) : null;
return userData ? userData.totalWorkTimeInSeconds / 3600 : 0;
}),
backgroundColor: getRandomColor(),
borderWidth: 0,
barPercentage: 1,
categoryPercentage: 0.5,
borderRadius: 3,
}));
const data = { labels: dates, datasets };
return <div style={{ width: "100%", height: "100%", ...styles }}>
<Bar options={options} data={data} />
</div>;
}
DashGroupBarChart.defaultProps = {
styles: {},
barData: []
}
以及我传递给 CharComponent 的数据格式
[
{
"date": "2024-03-18",
"data": [
{
"username": "smith",
"totalWorkTimeInSeconds": 12260
},
{
"username": "alena",
"totalWorkTimeInSeconds": 12727
},
{
"username": "nadir",
"totalWorkTimeInSeconds": 2759
},
{
"username": "noman",
"totalWorkTimeInSeconds": 7878
},
{
"username": "adam",
"totalWorkTimeInSeconds": 11758
}
]
},
{
"date": "2024-03-19",
"data": [
{
"username": "alena",
"totalWorkTimeInSeconds": 31609
},
{
"username": "jhon",
"totalWorkTimeInSeconds": 1449
},
{
"username": "noman",
"totalWorkTimeInSeconds": 4745
},
{
"username": "adam",
"totalWorkTimeInSeconds": 14266
},
{
"username": "atif",
"totalWorkTimeInSeconds": 7
},
{
"username": "bob",
"totalWorkTimeInSeconds": 5086
}
]
},
{
"date": "2024-03-20",
"data": [
{
"username": "smith",
"totalWorkTimeInSeconds": 13979
},
{
"username": "alena",
"totalWorkTimeInSeconds": 1492
},
{
"username": "noman",
"totalWorkTimeInSeconds": 8335
},
{
"username": "adam",
"totalWorkTimeInSeconds": 7532
},
{
"username": "bob",
"totalWorkTimeInSeconds": 3839
}
]
},
{
"date": "2024-03-21",
"data": [
{
"username": "smith",
"totalWorkTimeInSeconds": 11300
},
{
"username": "alena",
"totalWorkTimeInSeconds": 26813
},
{
"username": "adam",
"totalWorkTimeInSeconds": 13168
},
{
"username": "bob",
"totalWorkTimeInSeconds": 1386
}
]
},
{
"date": "2024-03-22",
"data": [
{
"username": "smith",
"totalWorkTimeInSeconds": 5281
},
{
"username": "alena",
"totalWorkTimeInSeconds": 21844
},
{
"username": "jhon",
"totalWorkTimeInSeconds": 20251
},
{
"username": "adam",
"totalWorkTimeInSeconds": 1987
},
{
"username": "bob",
"totalWorkTimeInSeconds": 15102
}
]
},
{
"date": "2024-03-23",
"data": [
{
"username": "smith",
"totalWorkTimeInSeconds": 7635
},
{
"username": "bob",
"totalWorkTimeInSeconds": 14660
}
]
},
{
"date": "2024-03-24",
"data": [
{
"username": "smith",
"totalWorkTimeInSeconds": 17819
},
{
"username": "alena",
"totalWorkTimeInSeconds": 17999
},
{
"username": "jhon",
"totalWorkTimeInSeconds": 3235
},
{
"username": "bob",
"totalWorkTimeInSeconds": 10241
}
]
},
{
"date": "2024-03-25",
"data": [
{
"username": "smith",
"totalWorkTimeInSeconds": 11338
},
{
"username": "adam",
"totalWorkTimeInSeconds": 3325
}
]
}
]
您的
ChartConfiguration
不正确,tooltip
应该位于 plugins
对象中,但与 plugins
不在同一级别。
您需要通过
tooltipItem.parsed.y
而不是tooltipItem.parsed
获取y轴值。
const options = {
responsive: true,
maintainAspectRatio: false,
plugins: {
...,
tooltip: {
callbacks: {
label: function (tooltipItem, data) {
return convertTimeFormat(tooltipItem.parsed.y);
},
},
},
}
...
};