无法在图表中的水平图中心中制作条形。

问题描述 投票:0回答:1
我尝试了所有选项,但是端杆靠近边界,其他条形也不是中心。我尝试使用Chart.js文档中的水平图表的所有选项,但条没有与中心保持一致。新的使用图书馆,无法找到问题的原因。 toby默认条形与边界对齐

使用:

console.log('script.js loaded'); // Fetch test execution data from the JSON file fetch('test-execution-data.json') .then((response) => { if (!response.ok) { throw new Error('Failed to fetch test execution data'); } return response.json(); }) .then((testExecutionData) => { // Debug: Log the fetched data console.log('Fetched test execution data:', testExecutionData); // Group tests by worker const workers = {}; testExecutionData.forEach((test) => { const parallelIndex = test.parallelIndex.toString(); if (!workers[parallelIndex]) { workers[parallelIndex] = []; } workers[parallelIndex].push({ label: test.title, startTime: new Date(test.startTime), endTime: new Date(test.endTime), status: test.status[0], // Get the first status attempt: test.attempt, totalAttempts: test.totalAttempts }); }); // Calculate relative timestamps (in minutes from the earliest test) const allTimes = testExecutionData.flatMap((test) => [ new Date(test.startTime).getTime(), new Date(test.endTime).getTime() ]); const minTimestamp = Math.min(...allTimes); const maxTimestamp = Math.max(...allTimes); const timeRangeInMinutes = (maxTimestamp - minTimestamp) / (1000 * 60); // Create datasets const datasets = Object.keys(workers).map((worker) => ({ label: `Worker ${worker}`, data: workers[worker].map((test) => ({ x: [ (test.startTime.getTime() - minTimestamp) / (1000 * 60), (test.endTime.getTime() - minTimestamp) / (1000 * 60) ], y: worker, label: test.label, start: test.startTime.toLocaleTimeString(), end: test.endTime.toLocaleTimeString(), status: test.status, attempt: test.attempt, totalAttempts: test.totalAttempts })), backgroundColor: (context) => { const status = context.raw.status; const attempt = context.raw.attempt; const totalAttempts = context.raw.totalAttempts; if (status === 'passed') { return 'rgba(75, 192, 192, 0.5)'; } else if (attempt < totalAttempts) { return 'rgba(255, 159, 64, 0.5)'; // Orange for retried failures } else { return 'rgba(255, 99, 132, 0.5)'; // Red for final failure } }, borderColor: (context) => { const status = context.raw.status; const attempt = context.raw.attempt; const totalAttempts = context.raw.totalAttempts; if (status === 'passed') { return 'rgba(75, 192, 192, 1)'; } else if (attempt < totalAttempts) { return 'rgba(255, 159, 64, 1)'; // Orange for retried failures } else { return 'rgba(255, 99, 132, 1)'; // Red for final failure } }, borderWidth: 1, // Increased from 1 to 3 borderSkipped: false, // This ensures borders are drawn on all sides borderRadius: 2, // Optional: slightly rounded corners barThickness: 5 })); // Render chart const ctx = document.getElementById('timelineChart').getContext('2d'); new Chart(ctx, { type: 'bar', data: { datasets }, options: { responsive: true, maintainAspectRatio: false, indexAxis: 'y', scales: { x: { type: 'linear', position: 'bottom', min: 0, max: Math.ceil(timeRangeInMinutes), title: { display: true, text: 'Time (minutes from start)' }, ticks: { stepSize: Math.max(1, Math.ceil(timeRangeInMinutes / 15)), // At most 15 ticks callback: (value) => { const date = new Date(value * 60 * 1000 + minTimestamp); return date.toLocaleTimeString(); } } }, y: { // type: 'category', // Use category scale for discrete worker indices // labels: Object.keys(workers), // Use worker indices as labels title: { display: true, text: 'Worker' } // offset: true // Add some padding to center the bars } }, plugins: { tooltip: { callbacks: { title: (context) => context[0].raw.label, label: (context) => { const { start, end, status } = context.raw; return [`Status: ${status}`, `Start: ${start}`, `End: ${end}`]; } } }, legend: { display: false } } } }); }) .catch((error) => { // Debug: Log any errors console.error('Error loading test execution data:', error); });

样本输入数据:

[
  {
    "title": "@workflow @tagAdded @AUTOMATIONS_WORKFLOW_SMOKE_TRIGGER DND enabled for all<> All Filter - Verify that when DND enabled trigger should fire",
    "parallelIndex": 3,
    "startTime": "2025-02-04T10:10:21.503Z",
    "endTime": "2025-02-04T10:10:33.748Z",
    "status": ["passed"],
    "retries": 0,
    "attempt": 1,
    "totalAttempts": 1,
    "isRetry": false
  },
  {
    "title": "@workflow @tagAdded @whatsapp DND enabled specific for Whatsapp - Verify that when DND enabled for Whatsapp trigger should fire",
    "parallelIndex": 5,
    "startTime": "2025-02-04T10:10:21.546Z",
    "endTime": "2025-02-04T10:10:27.457Z",
    "status": ["passed"],
    "retries": 0,
    "attempt": 1,
    "totalAttempts": 1,
    "isRetry": false
  }
]

绘制图像

可以帮忙

我不知道这是为什么会发生的,但是我的理论是因为设置

grouped

默认是为了解决此问题,您需要将其设置为false。我认为这种设置的作用是将输入组合在一起,因此如果为该房间准备好divs div中心,则它们可以互相可用
javascript typescript chart.js bar-chart visualization
1个回答
0
投票
轴。我在以下示例中使用了您的代码:


y

let testExecutionData = [ { "title": "@workflow @tagAdded @AUTOMATIONS_WORKFLOW_SMOKE_TRIGGER DND enabled for all<> All Filter - Verify that when DND enabled trigger should fire", "parallelIndex": 3, "startTime": "2025-02-04T10:10:21.503Z", "endTime": "2025-02-04T10:10:33.748Z", "status": ["passed"], "retries": 0, "attempt": 1, "totalAttempts": 1, "isRetry": false }, { "title": "@workflow @tagAdded @whatsapp DND enabled specific for Whatsapp - Verify that when DND enabled for Whatsapp trigger should fire", "parallelIndex": 5, "startTime": "2025-02-04T10:10:21.546Z", "endTime": "2025-02-04T10:10:27.457Z", "status": ["passed"], "retries": 0, "attempt": 1, "totalAttempts": 1, "isRetry": false } ]; // Group tests by worker const workers = {}; testExecutionData.forEach((test) => { const parallelIndex = test.parallelIndex.toString(); if (!workers[parallelIndex]) { workers[parallelIndex] = []; } workers[parallelIndex].push({ label: test.title, startTime: new Date(test.startTime), endTime: new Date(test.endTime), status: test.status[0], // Get the first status attempt: test.attempt, totalAttempts: test.totalAttempts }); }); // Calculate relative timestamps (in minutes from the earliest test) const allTimes = testExecutionData.flatMap((test) => [ new Date(test.startTime).getTime(), new Date(test.endTime).getTime() ]); const minTimestamp = Math.min(...allTimes); const maxTimestamp = Math.max(...allTimes); const timeRangeInMinutes = (maxTimestamp - minTimestamp) / (1000 * 60); // Create datasets const datasets = Object.keys(workers).map((worker) => ({ label: `Worker ${worker}`, data: workers[worker].map((test) => ({ x: [ (test.startTime.getTime() - minTimestamp) / (1000 * 60), (test.endTime.getTime() - minTimestamp) / (1000 * 60) ], y: worker, label: test.label, start: test.startTime.toLocaleTimeString(), end: test.endTime.toLocaleTimeString(), status: test.status, attempt: test.attempt, totalAttempts: test.totalAttempts })), backgroundColor: (context) => { const status = context.raw.status; const attempt = context.raw.attempt; const totalAttempts = context.raw.totalAttempts; if (status === 'passed') { return 'rgba(75, 192, 192, 0.5)'; } else if (attempt < totalAttempts) { return 'rgba(255, 159, 64, 0.5)'; // Orange for retried failures } else { return 'rgba(255, 99, 132, 0.5)'; // Red for final failure } }, borderColor: (context) => { const status = context.raw.status; const attempt = context.raw.attempt; const totalAttempts = context.raw.totalAttempts; if (status === 'passed') { return 'rgba(75, 192, 192, 1)'; } else if (attempt < totalAttempts) { return 'rgba(255, 159, 64, 1)'; // Orange for retried failures } else { return 'rgba(255, 99, 132, 1)'; // Red for final failure } }, borderWidth: 3, borderSkipped: false, borderRadius: 2, barThickness: 50 })); // Render chart const ctx = document.getElementById('timelineChart').getContext('2d'); new Chart(ctx, { type: 'bar', data: {datasets} , options: { responsive: true, maintainAspectRatio: false, indexAxis: 'y', scales: { x: { type: 'linear', position: 'bottom', min: 0, max: Math.ceil(timeRangeInMinutes), title: { display: true, text: 'Time (minutes from start)' }, ticks: { stepSize: Math.max(1, Math.ceil(timeRangeInMinutes / 15)), // At most 15 ticks callback: (value) => { const date = new Date(value * 60 * 1000 + minTimestamp); return date.toLocaleTimeString(); } } }, y: { // type: 'category', // Use category scale for discrete worker indices // labels: Object.keys(workers), // Use worker indices as labels title: { display: true, text: 'Worker' }, // offset: true // Add some padding to center the bars } }, plugins: { tooltip: { callbacks: { title: (context) => context[0].raw.label, label: (context) => { const { start, end, status } = context.raw; return [`Status: ${status}`, `Start: ${start}`, `End: ${end}`]; } } }, legend: { display: false } }, grouped: false } });

您可以看到一个设置为
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<canvas style="display: block; box-sizing: border-box;" height="200" width="500" id="timelineChart"></canvas>
,现在是数据中心的添加
option

grouped

如果这不是您要搜索的答案,并且必须有可能它们俩都存在于彼此的行,但如果不存在的中心或所提供答案的其他问题,请发表评论或更改问题。

	
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.