Гид по технологиям

Как построить COVID‑трекер на JavaScript и billboard.js

7 min read Веб-разработка Обновлено 09 Jan 2026
COVID‑трекер на JavaScript и billboard.js
COVID‑трекер на JavaScript и billboard.js

Что вы построите

Этот материал шаг за шагом объясняет базовый рабочий цикл: запрос данных из внешнего API, преобразование JSON в формат, пригодный для графика, и отрисовку интерактивной диаграммы с помощью billboard.js. Подойдёт как учебный проект для практики Fetch API, работы с массивами и простых конфигураций графиков.

Панель с статистикой COVID‑19

Важно: весь код можно поместить в простой статический сайт — никакой серверной логики для этого примера не требуется.

Источник данных и почему disease.sh

Для получения актуальных данных мы используем disease.sh — открытый API с данными о COVID. Он удобен для учебных проектов, потому что:

  • возвращает JSON (удобный для JavaScript);
  • не требует авторизации и ключей;
  • агрегирует данные из разных источников и предоставляет несколько энтпойнтов;
  • достаточно подробно документирован (см. официальный сайт disease.sh для справки).

Для демонстрации в этом руководстве мы используем исторические данные New York Times по США, которые в disease.sh представлены в виде массива объектов с датами и значениями по дням. Пример исходного вывода API:

Фрагмент JSON-ответа от disease.sh в виде массива объектов

Если вы знакомы с JSON, то такая структура понятна: массив объектов, где каждый объект содержит поля date, cases, deaths и т. п. Маленький фрагмент в читаемом виде:

[{  
  "date":"2020-01-21",  
  "cases":1,  
  "deaths":0,  
  "updated":1643386814538
},{  
  "date":"2020-01-22",  
  "cases":1,  
  "deaths":0,  
  "updated":1643386814538
}]

Минимальный HTML‑каркас

Создадим простой HTML-файл, куда будем подключать JavaScript и место для графика:




  
  Covid Tracker
  


  

Covid cases, US

Примечание: порядок подключений важен — billboard.js требует d3.js, а локальный скрипт должен быть подключён после библиотек.

Шаг 1 — получение данных (Fetch)

В файле covid.js начнём с простого запроса и вывода результата в консоль. Это поможет убедиться, что API доступен из браузера.

const api = 'https://disease.sh/v3/covid-19/nyt/usa';

fetch(api)
  .then(response => {
    if (!response.ok) throw new Error(`HTTP error ${response.status}`);
    return response.json();
  })
  .then(data => {
    console.log('Получены данные:', data);
  })
  .catch(err => console.error('Ошибка запроса:', err));

Ключевые моменты:

  • Проверяйте response.ok, чтобы обработать HTTP‑ошибки.
  • Используйте .catch для вывода сетевых/парсерных ошибок.

JSON-объект в консоли браузера, подготовленный для инспекции

Шаг 2 — подготовка данных для графика

billboard.js ожидает данные в определённом формате: массивы столбцов, где первый элемент массива — название серии (или меток оси X). Для временного ряда удобно подготовить две колонки: даты и значения случаев.

function plotData(data) {
  // data — массив объектов {date, cases, deaths, ...}
  const keys = data.map(a => a.date);
  const cases = data.map(a => a.cases);

  keys.unshift('dates');   // теперь keys = ['dates', '2020-01-21', ...]
  cases.unshift('cases');  // cases = ['cases', 1, 2, ...]

  // конфигурация графика дальше
}

Шаг 3 — базовый график billboard.js

Добавим в plotData генерацию простого линейного графика:

function plotData(data) {
  const keys = data.map(a => a.date);
  const 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 }
      }
    }
  });
}

Эта конфигурация связывает массив дат с осью X (x: ‘dates’), задаёт тип графика line и ограничивает количество отметок на оси X до 10.

Пример простого графика, сгенерированного billboard.js

Полный рабочий поток вместе

Комбинируем fetch и визуализацию:

const api = 'https://disease.sh/v3/covid-19/nyt/usa';

fetch(api)
  .then(r => { if (!r.ok) throw new Error(r.status); return r.json(); })
  .then(data => plotData(data))
  .catch(err => console.error(err));

function plotData(data) {
  const keys = data.map(a => a.date);
  const 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 }
      }
    }
  });
}

Диаграмма с суммарной историей случаев COVID в США

Вариации визуализаций и работы с объёмом данных

В реальных задачах график за несколько лет получается «захламлённым». Ниже — три простых приёма, как упростить видимость данных, не теряя информативности.

1) Ограничение временного интервала (например, один год)

Если нужно показать только 2022 год, примените фильтр перед передачей данных в plotData:

fetch(api)
  .then(r => r.json())
  .then(data => plotData(data.filter(a => a.date > '2022')));

Здесь используется строковое сравнение дат в формате YYYY-MM-DD, что корректно для такой сортировки.

График случаев COVID в США за 2022 год

2) Уменьшение детализации (например, одна точка в неделю)

Чтобы взять каждую 7‑ю запись (выборка по интервалу), используйте индекс в filter:

plotData(data.filter((a, i) => i % 7 === 0));

График с более редкими точками (по неделям)

3) Несколько серий на одном графике (cases и deaths)

Добавим ещё одну серию и отрисуем её вместе с первой, настроив разные оси и типы отображения:

function plotData(data) {
  const dates = data.map(a => a.date);
  const cases = data.map(a => a.cases);
  const deaths = data.map(a => a.deaths);

  dates.unshift('dates');
  cases.unshift('cases');
  deaths.unshift('deaths');

  bb.generate({
    bindto: '#covid-all-us-cases',
    data: {
      x: 'dates',
      columns: [dates, cases, deaths],
      axes: { cases: 'y', deaths: 'y2' },
      types: { cases: 'bar', deaths: 'line' }
    },
    axis: {
      x: { type: 'category', tick: { count: 10 } },
      y2: { show: true }
    }
  });
}

График с двумя сериями: случаи и смерти

Когда это решение не подходит (ограничения и ошибки)

  • CORS: если API не выставляет заголовки CORS, браузер заблокирует запросы. Решение: проксировать запрос через ваш сервер.
  • Ограничения API: публичные API могут иметь rate limit — при большом числе пользователей потребуется кэширование или серверная промежуточная прослойка.
  • Большие объёмы данных: если данных слишком много (тысячи точек), визуализация в браузере может быть медленной. Решения: агрегация на сервере, разбиение данных по страницам, использование WebGL‑решений.
  • Достоверность данных: источники могут иметь задержки и корректировки — для ответственных приложений проверяйте даты обновления и источник.

Альтернативные библиотеки и подходы

  • Chart.js — широко используемая библиотека проще в настройке для большинстве базовых графиков.
  • D3.js — мощный инструмент для кастомных визуализаций, но требует больше кода.
  • Plotly.js — хороший выбор, если нужны экспорт и богатые взаимодействия.
  • Google Charts — быстрый старт с простым подключением для базовых случаев.

Выбор зависит от требований: если нужен быстрый прототип — billboard.js или Chart.js; для кастомных интерактивных виджетов — D3.

Практические подсказки и шаблоны (cheat sheet)

  • Проверка успешного получения данных:
if (!Array.isArray(data)) throw new Error('Ожидался массив объектов');
  • Быстрая агрегация по неделям (пример):
function aggregateWeekly(data) {
  return data.filter((_, i) => i % 7 === 0);
}
  • Переход от категорий к временной оси: billboard.js поддерживает тип x: ‘timeseries’ и парсинг дат, если вам нужны аккуратные метки времени.
// пример для timeseries
bb.generate({
  data: { x: 'x', columns: [['x', '2020-01-21', '2020-01-22'], ['data', 1, 1]] },
  axis: { x: { type: 'timeseries', tick: { format: '%Y-%m-%d' } } }
});
  • Отладка: используйте консоль браузера и выводы console.table для быстрого просмотра структурированных данных.

Критерии приёмки

  • Данные загружаются без ошибок и отображаются в консоли;
  • Диаграмма отрисовывается в контейнере #covid-all-us-cases;
  • При переключении фильтров (год, агрегация) график обновляется корректно;
  • При объединении нескольких серий оси и легенда читаемы.

Роль‑ориентированные чек‑листы

  • Для разработчика фронтенда:

    • проверить CORS и механизмы кэширования;
    • убедиться, что зависимости подключены в корректном порядке;
    • покрыть кейсы с пустыми и частично заполненными данными.
  • Для дизайнера/UX:

    • проверить читаемость осей и легенды;
    • предусмотреть подсказки при наведении;
    • обеспечить доступность (контраст, крупный шрифт).
  • Для DevOps/владельца продукта:

    • настроить мониторинг доступности API и алерты на ошибки;
    • организовать кэширование и балансировку запросов при росте трафика.

Безопасность, приватность и соответствие требованиям

  • Приватность: если вы собираете пользовательские данные или логи запросов, убедитесь в соответствии с местными законами о защите данных (например, GDPR). Для публичного отображения агрегированных данных это обычно неактуально, но при сохранении IP‑адресов пользователей или их действий — нужна политика хранения данных.
  • Безопасность: не храните чувствительные ключи в коде, даже если сейчас API публично открыт. При переходе к защищённым API используйте серверную прослойку для сокрытия секретов.

Производительность и масштабирование

  • Кэширование: кешируйте ответ API на стороне сервера или CDN, чтобы снизить нагрузку и ускорить отклик.
  • Ленивая загрузка: загружайте большие наборы данных по требованию (например, при выборе периода).
  • Агрегация: агрегируйте данные по дням/неделям/месяцам на сервере для долгих временных рядов.

Тесты и приёмка

Набор минимальных тестов:

  • unit: функции map/reduce/aggregate возвращают ожидаемые результаты на фиксированных входных данных;
  • integration: при эмуляции успешного API-ответа график отрисовывается в DOM;
  • e2e: пользователь может выбрать год и увидеть изменённый график.

Отладочный план (runbook)

  1. Если график не отрисовывается — проверить консоль на ошибки (CORS, 404, парсинг JSON).
  2. Если данные пустые — проверить endpoint вручную в браузере или через curl.
  3. Если график тормозит — уменьшить количество точек и проверить время отрисовки; включить профилирование в DevTools.

Методология быстрого прототипа (mini‑method)

  1. Получить и отобразить JSON в консоли — убедиться в структуре.
  2. Написать простую функцию plotData с заглушкой (пара массивов) и убедиться, что billboard.js работает.
  3. Подключить реальные данные и преобразовать в формат columns.
  4. Добавить фильтры/агрегации и тесты принятия.

Сравнение: когда выбирать billboard.js

  • Используйте billboard.js, если вам нужен быстрый прототип с D3‑подложкой и небольшим объёмом кастомизации.
  • Выберите Chart.js для простоты настроек и широкой поддержки типов.
  • Берите D3.js для полного контроля и сложных кастомных визуализаций.

Краткая глоссарий (одна строка на термин)

  • API — интерфейс для получения данных из внешних систем.
  • CORS — политика браузера, ограничивающая междоменные запросы.
  • timeseries — временной ряд, данные упорядоченные по времени.
  • Агрегация — объединение данных (например, по неделю/месяц).

Резюме

Вы использовали Fetch API для получения данных, преобразовали JSON в формат, понятный для billboard.js, и построили интерактивные графики. Вы также узнали простые приёмы фильтрации и агрегации, получили рекомендации по масштабируемости, тестированию и соответствию требованиям приватности. Этот проект можно расширять: добавить выбор страны, данные о вакцинации, сверку источников и экспорт графиков.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Отключить статус «Просмотрено» в Instagram
Социальные сети

Отключить статус «Просмотрено» в Instagram

Как ответить на сообщение в Instagram
Социальные сети

Как ответить на сообщение в Instagram

Добавить музыку в заметки Instagram
Социальные сети

Добавить музыку в заметки Instagram

Как пользоваться Notes в Instagram
Социальные сети

Как пользоваться Notes в Instagram

Видео-заметки в Instagram: как публиковать
соцсети

Видео-заметки в Instagram: как публиковать

Обновление Instagram на iPhone и Android
Мобильные приложения

Обновление Instagram на iPhone и Android