Не могу указать шаг следования по горизонтальной оси

Строю график по данным 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 час. Единственное, что не очень, так это то, что при наведении курсора на точку, высвечивается время в минутах, оставшееся с перевода времени в минуты. Заменить бы его тоже на реальное время...


Ответы (0 шт):