Не могу указать шаг следования по горизонтальной оси
Строю график по данным JSON. Данные поступают через разные промежутки времени (могут каждые 20 сек, а могут раз в два часа). Но график нужно строить за сутки, то есть начиная с 00:00:00 текущей даты и заканчивая 23:59:59 текущей даты. Шаг на оси должен быть равным 1 часу (на оси должно быть 24 засечки). Данные могут располагаться между засечками, например, 6:10. Сейчас все точки равноудалены друг от друга, хотя на самом деле так не должно быть. Как установить равный шаг и начальное и конечное значения?
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<canvas id="temperatureChart" width="800" height="400"></canvas>
<script>
// JSON строка с данными
const dataString = `{"feeds":[{"created_at":"2024-03-10T05:58:39","entry_id":487,"field1":"2.70"}, {"created_at":"2024-03-10T06:10:19","entry_id":488,"field1":"2.50"},
{"created_at":"2024-03-10T06:23:09","entry_id":489,"field1":"2.60"},{"created_at":"2024-03-10T15:34:49","entry_id":490,"field1":"2.60"},{"created_at":"2024-03-10T15:46:29","entry_id":491,"field1":"2.65"}]}`;
// Распарсим JSON данные
const data = JSON.parse(dataString);
// Создаем массивы для времени и температуры
const dateTimeLabels = [];
const temperatureData = [];
// Итерируемся по элементам данных и добавляем соответствующие значения в массивы
data.feeds.forEach(feed => {
// Извлекаем время из созданного элемента данных
const date = new Date(feed.created_at);
const dateTime = date.toLocaleString('ru-RU', { year: 'numeric', month: 'short', day: '2-digit', hour: 'numeric', minute: 'numeric' });
// Добавляем дату и время в соответствующий массив
dateTimeLabels.push(dateTime);
temperatureData.push(parseFloat(feed.field1));
});
// Создаем график с использованием библиотеки Chart.js
const ctx = document.getElementById('temperatureChart').getContext('2d');
const temperatureChart = new Chart(ctx, {
type: 'line',
data: {
labels: dateTimeLabels,
datasets: [{
data: temperatureData,
borderColor: 'black',
backgroundColor: 'lightblue',
fill: false,
}]
},
options: {
scales: {
x: {
title: {
display: true,
text: 'Дата и время'
}
},
y: {
title: {
display: true,
text: 'Температура (°C)'
}
}
}
}
});
</script>
</body>
</html>
Изменено: Я нашёл решение:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Метео</title>
<style>
body {
font-family: Arial, Helvetica, sans-serif;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
</head>
<body>
<canvas id="temperatureChart" width="800" height="400"></canvas>
<script>
const dataString = `{"feeds":[{"created_at":"2024-03-11T05:58:39","entry_id":487,"field1":"2.70"}, {"created_at":"2024-03-11T06:10:19","entry_id":488,"field1":"2.50"},
{"created_at":"2024-03-11T06:23:09","entry_id":489,"field1":"2.60"},{"created_at":"2024-03-11T15:34:49","entry_id":490,"field1":"2.60"},{"created_at":"2024-03-11T15:46:29","entry_id":491,"field1":"2.65"}]}`;
let chart;
let endDate;
let startDate;
let milliseconds;
// Функция для форматирования временных меток
function formatTimeLabel(value, index, values) {
return moment().startOf('day').add(value, 'hours').format('YYYY-MM-DD HH:mm');
}
function fetchDataAndDrawChart() {
const data = JSON.parse(dataString);
const temperatureData = data.feeds.map(feed => parseFloat(feed.field1));
const timeLabels = data.feeds.map(feed => {
const date = new Date(feed.created_at);
return date.getTime(); // Преобразование в миллисекунды
});
const normalizedTimeLabels = timeLabels.map(time => (time - milliseconds) / (1000*60*60));
const ctx = document.getElementById('temperatureChart').getContext('2d');
if (chart) {
chart.destroy(); // Уничтожаем предыдущий график перед отрисовкой нового
}
chart = new Chart(ctx, {
type: 'line',
data: {
labels: normalizedTimeLabels,
datasets: [{
label: 'Температура в городе Бердске',
data: temperatureData,
borderColor: 'black',
backgroundColor: 'lightblue',
fill: false,
}]
},
options: {
plugins: {
legend: {
display: false
},
tooltip: {
mode: 'index',
intersect: false,
callbacks: {
label: function(context) {
var label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += context.parsed.y + '°C';
}
var timeLabel = moment().startOf('day').add(context.parsed.x, 'hours').format('YYYY-MM-DD HH:mm');
label += ' (' + timeLabel + ')';
return label;
}
}
}
},
scales: {
x: {
type: 'linear',
title: {
display: true,
text: 'Время (год-месяц-день час)'
},
ticks: {
stepSize: 1, // Шаг по оси X
callback: formatTimeLabel // Форматирование временных меток
},
min: 0, // Минимальное значение оси X
max: 24 // Максимальное значение оси X
},
y: {
title: {
display: true,
text: 'Температура (°C)'
},
ticks: {
stepSize: 0.1, // Шаг по оси Y
},
min: 2, // Минимальное значение оси X
max: 3 // Максимальное значение оси X
}
}
}
});
}
function initializeChartData() {
endDate = new Date(); // Текущая дата и время
startDate = new Date(endDate); // Копируем текущую дату и время
startDate.setHours(0, 0, 0, 0); // Устанавливаем начало дня (00:00)
milliseconds = startDate.getTime(); // Переводим в миллисекунды
}
initializeChartData(); // Инициализируем начальные данные для графика
fetchDataAndDrawChart(); // Отрисовываем график
</script>
</body>
</html>
Теперь по горизонтальной оси откладывается время за сутки с шагом в 1 час. Единственное, что не очень, так это то, что при наведении курсора на точку, высвечивается время в минутах, оставшееся с перевода времени в минуты. Заменить бы его тоже на реальное время...