Простой COVID‑трекер на JavaScript

Ищете быстрый проект, чтобы потренировать навыки веб‑разработки? За время пандемии вы наверняка видели множество трекеров и графиков по COVID — в этом руководстве показано, как сделать свой собственный с минимальными усилиями.
Вы освоите полезные приёмы в JavaScript: как получить удалённые данные через API и как отобразить их с помощью библиотеки для графиков. Поехали.
Что вы будете собирать
Это руководство демонстрирует основы работы с API с помощью JavaScript. Вы научитесь получать данные из удалённого источника и преобразовывать их для отображения на графике с помощью библиотеки billboard.js.
Весь код из статьи доступен в репозитории на GitHub.
Источник данных и что важно знать
Чтобы получать актуальные данные по COVID, мы используем disease.sh — «Open Disease Data API».
Почему это удобно:
- Большое количество источников и форматов данных.
- Хорошая документация с описанием доступных endpoint‑ов.
- Ответы в формате JSON — удобно для JavaScript.
- Полностью открыто и бесплатно, без авторизации.
Важно: отсутствие авторизации означает, что API удобно вызывать прямо из браузера. Однако у открытых API есть свои ограничения по надёжности и SLA — см. раздел о рисках и вариантах резервирования.
Для этого туториала мы используем endpoint disease.sh, который отдаёт данные New York Times по США с 21 января 2020 года — это удобно, потому что формат отмечен в виде списка объектов с полем date, cases и deaths.
Если вы привыкли к JSON, то это легко прочитать. Небольшой отрывок в более удобном виде:
[{
"date":"2020-01-21",
"cases":1,
"deaths":0,
"updated":1643386814538
},{
"date":"2020-01-22",
"cases":1,
"deaths":0,
"updated":1643386814538
}]API возвращает простой массив объектов: каждый объект — точка данных с датой, количеством случаев и т.д.
Подготовка HTML
Для начала создадим простую HTML‑структуру. В конце статьи есть рекомендации по подключению зависимостей и размещению стилей/скриптов в продакшн‑среде.
Covid Tracker
Covid cases, US
Примечание: позже мы добавим внешние библиотеки в head (d3 и billboard.js).
Получение данных через JavaScript (fetch)
Начнём с простого — загрузим данные и выведем их в консоль, чтобы убедиться, что всё работает. Поместите в файл covid.js:
var api = 'https://disease.sh/v3/covid-19/nyt/usa';
fetch(api)
.then(response => response.json())
.then(data => {
console.log(data);
});Короткое объяснение: Fetch API — современная альтернатива XMLHttpRequest. Он возвращает Promise, что упрощает последовательную обработку асинхронных шагов. После получения ответа мы вызываем response.json(), чтобы распарсить тело как JSON.
Вы сможете взаимодействовать с объектом в консоли, просмотрев структуру и поля. Когда проверили, что данные приходят — можно переходить к визуализации.
Визуализация данных с помощью billboard.js
Вместо вывода в консоль, отобразим данные на графике. Сначала обновим код, чтобы передавать данные в функцию plotData:
fetch(api)
.then(response => response.json())
.then(data => {
plotData(data);
});
function plotData(data) {
// реализуем ниже
}Мы используем библиотеку billboard.js — лёгкую обёртку над d3, которая даёт интерактивные графики и базовые типы диаграмм.
Добавьте в head HTML следующие строки, чтобы подключить d3 и billboard.js:
Попробуем самый базовый график. Вставьте в plotData простую генерацию:
bb.generate({
bindto: "#covid-all-us-cases",
data: {
type: "line",
columns: [
[ "data", 10, 40, 20 ]
]
}
});Свойство bindto указывает CSS‑селектор целевого элемента. Данные передаются в виде колонок: первая ячейка массива — название серии, остальные — значения.
Теперь осталось превратить реальные данные API в формат колонок, который понимает billboard.js.
Преобразование данных для графика
Построим две колонки: одну для оси X с датами, вторую — для самих случаев.
var keys = data.map(a => a.date),
cases = data.map(a => a.cases);
keys.unshift("dates");
cases.unshift("cases");После этого используем их в конфигурации графика:
bb.generate({
bindto: "#covid-all-us-cases",
data: {
x: "dates",
type: "line",
columns: [
keys,
cases
]
},
axis: {
x: {
type: "category",
tick: {
count: 10
}
}
}
});Описание: мы назначаем колонку “dates” как ось X и просим отобразить только 10 подписей, чтобы даты не налезали друг на друга. Результат интерактивен: при наведении показываются значения.
Исходный код трекера доступен в репозитории на GitHub.
Варианты отображения данных
Ниже — несколько простых приёмов, как изменить входные данные, не переписывая весь plotData.
Ограничение до одного года
Если общий график слишком шумный, можно оставить данные только за один год. Измените второй .then() так:
plotData(data.filter(a => a.date > '2022'));filter() оставляет элементы, для которых функция возвращает true. Строковое сравнение работает, потому что формат даты — год‑месяц‑день.
Уменьшение детализации — один пункт в неделю
Другой подход — сохранить один элемент каждые 7 дней, чтобы сохранить тренд, но убрать шум.
plotData(data.filter((a, index) => index % 7 == 0));Здесь используется второй параметр filter — индекс, и оператор % (modulus).
Отображение случаев и смертей на одном графике
Чтобы показать две серии (cases и deaths), добавим массив deaths и обновим columns:
var deaths = data.map(a => a.deaths);
var columns = [ keys, cases, deaths ];
bb.generate({
bindto: "#covid-all-us-cases",
data: {
x: "dates",
columns: columns,
axes: { "cases": "y", "deaths": "y2" },
types: {
cases: "bar"
}
},
axis: {
x: {
type: "category",
tick: { count: 10 }
},
y2: {
show: true
}
}
});Таким образом мы указали, по каким осям отображать серии и задали для cases тип “bar”.
Практические советы и дополнительные идеи
Важно: при работе с открытыми данными учитывайте, что структура и доступность API могут меняться. Поддерживайте версию кода и проверяйте документацию API.
Ниже собрано несколько рекомендаций, которые пригодятся при развитии проекта.
Альтернативы billboard.js
- Chart.js — простая и популярная библиотека, хорошо документирована.
- ApexCharts — интерактивная и красивая, коммерческие дополнения.
- Plotly.js — мощнее для аналитики, но тяжелее.
Если вам нужна лёгкость и минимум настроек — billboard.js хорош. Если нужны кастомные интерактивные визуализации или большие объёмы данных, рассмотрите d3 напрямую.
Когда такой подход не подойдёт
- Если API ограничивает запросы или требует авторизации — прямой вызов из браузера может быть неприменим.
- Для больших наборов данных (миллионы точек) клиентская визуализация тормозит — требуется агрегация на сервере или серверный рендеринг.
- Для критичных систем с SLA и требованиями к правкам данных лучше использовать стабильные платные сервисы и кэш.
Как масштабировать и сделать менее хрупким
- Добавьте кеширование (localStorage, IndexedDB или серверный кэш).
- Выполняйте фоновые обновления данных на сервере и отдавайте агрегаты на фронтенд.
- Оборачивайте вызов API в слой с повторными попытками и обработкой ошибок.
Мини‑методология: шаги разработки
- Изучите структуру API и сделайте пробный fetch с выводом в консоль.
- Спроектируйте, какие серии и оси нужны.
- Преобразуйте JSON в формат колонок (dates + серии).
- Нарисуйте минимальный график и протестируйте интерактивность.
- Добавьте фильтры/агрегацию для улучшения читаемости.
- Добавьте обработку ошибок и механизм кеширования.
- Напишите тесты на преобразование данных и тесты UI (smoke tests).
Контрольный список ролей при внедрении
- Разработчик фронтенда:
- Реализует fetch и трансформацию данных.
- Интегрирует billboard.js и стили.
- Добавляет обработку ошибок.
- Разработчик бэкенда (если есть):
- Настраивает кэш/агрегацию данных.
- Обеспечивает ограничение частоты запросов.
- Тестировщик:
- Проверяет корректность осей и отображения.
- Проводит тесты на выборках (фильтрация, агрегация).
- DevOps:
- Наблюдает за доступностью внешнего API.
- Настраивает резервные endpoint’ы при необходимости.
Критерии приёмки
- Данные загружаются и отображаются без ошибок в консоли.
- Ось X показывает корректные даты и не налезает на подписи.
- График корректно реагирует на hover и показывает значения.
- Фильтры (год/неделя) работают и изменяют отображение.
- Обработка ошибок присутствует: показ уведомления при недоступности API.
Тестовые случаи и критерии приёма
- Успешный fetch: при корректном ответе график отрисовывается.
- Неверный формат данных: приложение показывает сообщение “Неверный формат данных”.
- Оффлайн/404/500: пользователь видит дружелюбное уведомление и кнопку «Попробовать снова».
- Фильтрация по году: только точки с датой > выбранного года отображаются.
- Агрегация по неделям: при выборе weekly количество точек уменьшается ~в 7 раз.
Безопасность и приватность
- Не храните в публичном репозитории секреты (API‑ключи и т. п.). В нашем случае API открытое, поэтому секретов нет.
- Проверяйте CORS‑политику при вызове API из браузера.
- Если вы сохраняете данные пользователей или логи с геоданными — учитывайте требования локального законодательства о защите данных.
Примечание: для публикации трекера внутри организации рекомендуется использовать сервер‑прокси, который добавляет кэш и фильтрует трафик.
Мультистраничные и локализационные советы
- Формат дат от API — yyyy-mm-dd; для отображения локализуйте даты на клиенте (Intl.DateTimeFormat).
- Для других стран disease.sh поддерживает множество endpoint’ов — замените путь на нужную страну.
Сопутствующие шаблоны и сниппеты
Пример простой обработки ошибок и отображения сообщения пользователю:
fetch(api)
.then(response => {
if (!response.ok) throw new Error('Network response was not ok');
return response.json();
})
.then(data => plotData(data))
.catch(err => {
document.getElementById('covid-all-us-cases').innerText = 'Не удалось загрузить данные: ' + err.message;
});Пример кеширования в localStorage с тайм‑ауотом 1 час:
const CACHE_KEY = 'covid_usa_cache';
const CACHE_TTL = 1000 * 60 * 60; // 1 час
function fetchWithCache(url) {
const cached = localStorage.getItem(CACHE_KEY);
if (cached) {
const obj = JSON.parse(cached);
if (Date.now() - obj.t < CACHE_TTL) return Promise.resolve(obj.data);
}
return fetch(url)
.then(r => r.json())
.then(data => {
localStorage.setItem(CACHE_KEY, JSON.stringify({ t: Date.now(), data }));
return data;
});
}Короткое руководство по миграции на другой график
- Сохраните логику преобразования данных (columns = [dates, series…]).
- В новой библиотеке найдите API для передачи «labels» (даты) и «datasets» (серии).
- Подключите новую зависимость и замените вызов bb.generate на createChart или аналог.
- Проверьте стили и поведение hover/tooltip.
Небольшой словарь (в одном предложении)
- API: интерфейс для получения данных по HTTP.
- JSON: формат обмена данными.
- fetch: браузерный API для HTTP‑запросов.
- billboard.js: библиотека для графиков поверх d3.
- aggregation: свёртка/сжатие данных (по неделям, месяцам).
Социальный превью и короткое объявление
Социальный заголовок (OG): COVID‑трекер на JavaScript — быстрый туториал
Социальное описание (OG): Соберите простой трекер COVID с fetch и billboard.js. Код и варианты очистки данных — готовы к использованию.
Краткое объявление (100–200 слов):
Соберите собственный COVID‑трекер на JavaScript за один присест. В этом руководстве показано, как получить исторические данные через публичный API disease.sh, преобразовать JSON и визуализировать его с помощью billboard.js. Вы получите рабочий пример, варианты агрегации данных (по годам или по неделям), способ добавить столбцы смертей и kasus, и советы по кешированию и обработке ошибок. Подойдёт как мини‑проект для портфолио или как стартовая точка для более сложной аналитики.
Краткое резюме
- disease.sh — бесплатный и удобный источник исторических данных по COVID.
- fetch + JSON + billboard.js дают быстрый путь от данных к графику.
- Фильтрация и агрегация помогают сделать графики читаемыми.
- Для продакшна используйте кеш, обработку ошибок и, при необходимости, сервер‑прокси.
Если хотите, могу помочь адаптировать код под другую страну, добавить суммарную статистику или подготовить версию для мобильного просмотра.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента