Вчера закончился очередной сезон английской премьер-лиги, и это отличный повод поговорить о визуализации спортивных сезонов.
Полгода назад я написал о том, как превратить статичную таблицу с результатами спортивного сезона в интерактивную. Напомню, что она выглядела так:
С тех пор
Архитектура
Библиотека состоит из пяти независимых модулей:
configure
извлекает data- атрибуты из HTML и готовит конфигурацию для остальных модулейextract
добывает данные из файла или APItransform
преобразует данные в стандартный форматcalculate
считает победы, поражения, голы и другие штуки, а также добавляет метаинформациюvisualize
рисует интерактивную таблицу и возвращает объект с методами вродеplay()
иdrillDown(item)
Но модулей мало не бывает, поэтому
extract
, transform
и visualize
сами состоят из подмодулей.Каждый модуль знает, что к нему придёт на вход и что ему нужно отдать на выходе.
Такая архитектура позволяет добавлять функции быстро и безболезненно. Так, для поддержки JSON-файлов в
extract
, достаточно было добавить 13 строк кода. Визуализаторы
Но это ещё не самое крутое. В какой-то момент стало понятно, что пытаться идеально адаптировать одну и ту же таблицу к разными видам спорта через data- атрибуты — это путь в никуда. Поэтому в
visualize
появились визуализаторы. Визуализатор определяет, как строить таблицу, как перемещаться между раундами и как углубляться в результаты команды.Благодаря визуализаторам из одних и тех же данных можно получить две очень разные таблицы:
Теперь, если вы захотите поэкспериментировать с визуализацией, например, сезона Формулы-1, вам не придётся готовить данные и программировать анимацию таблицы — всё это библиотека сделает за вас. Просто напишите свой визуализатор.
Или поступите, как Виталик. Виталик сделал красивый прототип, а мы его оживили и добавили в библиотеку:
Результат
Поиграйте с живыми таблицами:
Библиотека умеет работать с csv и json файлами, управляется со списком матчей и таблицей очков и предлагает два визуализатора: классическую таблицу и таблицу со спарклайнами.
Использование
Как и прежде, исходный код лежит на Гитхабе, а рядом с ним — документация.
Предполагается два варианта использования: подключить скрипты в head и наслаждаться тем, как дивы превращаются в интерактивные таблицы, или установить библиотеку через npm и запрограммировать чудеса.
Милосердная лицензия позволяет пользоваться библиотекой без ограничений на любых сайтах.
Мы будем рады замечаниям, предложениям и пулл-реквестам.
Комментарии (20)
Horoshiy78
23.05.2017 11:39Многие футбольные чемпионаты при сортировке в таблице применяют фактор «очных встреч» у команд, набравших одинаковое количество очков. Причем и тут порядок разных бывает — кто-то допустим голы в гостях учитывает, а кому просто достаточно разницы мячей.
Есть ли вариант в будущих версиях учитывать этот показатель?antoniokov
23.05.2017 11:47Да, есть такие планы. Сейчас параметр orderBy принимает список вычислений, например, «points, wins, draws' и сортирует по порядку: сначала по очкам, потом по победам, потом по ничьям. Для большинства чемпионатов этого достаточно: в той же премьер-лиге дополнительные показатели — разница забитых и пропущенных и количество забитых мячей.
В будущем есть два пути: принимать что-то вроде 'matchesBetween, matchesBetween.goalsDifference' или давать возможность переопределять саму функцию сравнения.
Crusader_12
23.05.2017 20:00Если смотреть на примере АПЛ то там как раз не личные встречи считают а кто забил больше и у кого лучше разница голов.
BigTenis
23.05.2017 11:39все это, даже больше, есть на сайтах для капперов, а вот чего там нет, так это корреляции между позициями в рейтингах и коэффициентов на событие (в открытом доступе).
Если хотите сделать что-то востребованное — советую двигаться в этом направлении.antoniokov
23.05.2017 11:49А дайте ссылку, пожалуйста, на визуализации от капперов: я не смог найти.
Рынок ставок мне неинтересен, поэтому двигаться в этом направлении желания нет.
KreetKreet
23.05.2017 11:39Добрый день!
Идея неплохая, но есть серьезное замечание:
Согласно Вашего примера в АПЛ после первого тура было такое положение:
1. Халл 2-1
2. Свонси 1-0
…
5. МЮ 3-1
6 Ливерпуль 4-3
Это неверно. В АПЛ при равенстве очков считают сначала разницу забитых, пропущенных, а затем количество забитых.
Так что визуализация это здорово, но порядок быть должон!antoniokov
23.05.2017 11:50Справедливо, спасибо! Достаточно добавить в orderBy=«points,goalsDifference,goalsFor» — поправлю :)
antoniokov
23.05.2017 12:00Решил не откладывать в долгий ящик:
KreetKreet
23.05.2017 12:22Да, теперь порядок верный.
Еще рекомендация, у Вас пишнтся изменение количества очков +3 +1 0. Мне кажется + тут лишнее, по-моему нет спортивных соревнований, где количество очков уменьшается :)antoniokov
23.05.2017 12:26Действительно, таких видов спорта и я придумать не могу. Но плюс помогает понять, что это именно изменение. Если люди будут понимать это и без значка, то мы его уберём, спасибо.
KreetKreet
23.05.2017 12:34Возможно имеет смысл рассмотреть варианты представления, например, в большом теннисе точно количество очков за матч может меняться (для общего рейтинга), а вот футбол / хоккей может имеет смысл рассмотреть типовые «в», «н», «п» (выигрыш, ничья, поражение), а может и вовсе обойтись без этой метки. Так как, большинство болельщиков и так знают сколько очков дается в их виде спорта (футбол/хоккей) за результат — возможно достаточно будет уже существующей у Вас раскраски результата матча.
feik_brutus
23.05.2017 18:57Есть случаи когда Федерация лишает очков команду за нарушения (тот же Милан и Ювентус в 2006). Этот случай как отобразится?
antoniokov
24.05.2017 00:14Ух ты, вот это интересно. Об этом мы не думали, спасибо.
Лучшим решением выглядит параметр fines в модуле calculate, в который будет приходить массив вида «команда-тур-количество штрафных очков», а визуализаторы уже будут сами решать, как лучше показывать штрафы.
В спарклайнах я бы добавлял чёрные кирпичики в начало или конец сезона.
Случай хоть и интересный, но достаточно редкий, поэтому мы пока займём выжидательную позицию до очередного коррупционного скандала :)
Another09
23.05.2017 12:00Есть общий вопрос. Откуда еще можно автоматом брать статистику? Маловато чемпионатов на football-data.org
Видел еще football-data.co.uk, но там тоже только основные страны.antoniokov
23.05.2017 12:05К сожалению, у меня нет ответа. Для прошлого года я брал csv с football-data.co.uk, в этом году — выгружал json из API football-data.org, потому что там здорово проставлены matchdays.
Могу разве что посоветовать список спортивных баз и API. Но большинство ресурсов там уступают по удобству и полноте двум сайтам выше.
Есть ещё платные API вроде Opta, но я их не пробовал.
Будет здорово, если кто-то подскажет удобный API — можно будет сделать real-time таблицы.
KreetKreet
23.05.2017 12:38Отдельным вопросом. А как быть с отложенными матчами? Например, когда переносят 3 матча 4 тура. Остальные команды играют по расписанию, а вот отложенные играются позже.
Как вариант могу предложить рассмотреть возможность двигаться не по турам, а по датам (чтобы отложенный матч влиял на таблицу в правильный момент времени), тогда конечно нужно сразу отображать текущее количество матчей, проведенных командойantoniokov
23.05.2017 12:53В этом случае будет дырка в спарклайне, и она будет хорошо заметна. Как-то так:
В классической таблице для незаконченных сезонов мы советуем выводить колонку с количеством сыгранных матчей — она называется «rounds».
Если строить по датам, то получается уж очень большое число раундов. У нас есть ещё одно решение: подавать на вход список матчей с датами и ставитьcollapseToRounds="true"
: таблица сама посчитает 1-й, 2-й, 3-й и n-й матч для каждой команды и схлопнет 180 дат в 38 раундов.maxzuber
23.05.2017 17:04Если тур разбивается на несколько игровых дней, группировка более чем желательна. Отложенный же матч вырывается из своего тура, и возвращать его на родное место некорректно. Лучше сделать дырку и сохранить игровую последовательность. Возможно, в один условный тур потребуется сгруппировать отложенные матчи из разных туров, в чемпионатах предусмотрены резервные даты. Например, в Испании недавно был отложенный матч Сельта — Реал. Зато все срезы будут соответствовать ходу чемпионата.
Пропуск игры в любом случае лучше предусмотреть, ведь в группе с нечётным количеством участников в каждом туре есть отдыхающий.antoniokov
24.05.2017 00:08Визуализация и сейчас умеет работать со случаем, когда команда сыграла 1-й и 3-й тур, но пропустила 2-й: на месте второго будет пустой «спарк».
Дело исключительно в подготовке данных: как вы устроите matchweeks/matchdays, так результаты и отобразятся.
BOOTor
Отличная работа!
Только поправьте в примерах ссылочку данных футбола на json вместо csv.