Визуализируем данные тренировок с DevExpress Dashboard



    Не секрет, что среди айтишников много тех, кто любит физическую активность. Возможно, это вызвано сидячим характером работы и желанием позаботиться о своем здоровье. Или, может быть, это просто мода на велосипеды, бег и плавание. В любом случае, некоторые из тех, кто любит физическую активность, занимаются любительским спортом или регулярно тренируются.

    Лирическое отступление
    Если ты не занимался в детстве никаким циклическим видом спорта, то увлечение спортом может начаться покупкой велосипеда. Велосипед, конечно же, выбирается после изучения множества отзывов и рекомендаций и чтения веломании, и обязательно не «ашанбайк» (см. недавно пролетавшую по интернету шутку про то, как бесит во всем разбираться). Потом получается, что на купленном крутом горном велосипеде кататься по парку и по городу не очень-то интересно, и ты ищешь единомышленников, начинаешь регулярно участвовать в покатушках местного велоклуба и возможно попадаешь на свою первую в жизни любительскую КК гонку. Там вдруг оказывается, что твоя физическая форма позволяет занять почетное место только где-то в конце списка. После этого, если ты не скажешь «ну их, эти гонки», а начнешь изучать ту же веломанию, но уже на предмет тренировок, читать «Библию велосипедиста», зарегистрируешься на страве (http//strava.com), начнешь регулярно тренироваться и вести дневник тренировок — вот тогда начнется спорт, пусть и любительский.

    Другая вещь, которую любят айтишники, это разнообразная статистика и цифры. Обычные спортивные сервисы не позволяют как-то играться со статистикой, предоставляя лишь стандартные виды отчетов, вроде счетчиков пробега или времени по неделям и дням недели и видам активности. Так уж получилось, что автор этих строк одновременно и тренируется, и участвует в разработке DevExpress Dashboard. И конечно же мне захотелось самому сделать дэшборд (и показать всем, как это легко) по данным из своего дневника тренировок.

    Дневник я веду просто в виде таблицы Google doc. Вести дневник просто: для каждой тренировки надо записать по типу занятия, получившееся время, дистанцию, средней/максимальной скорости, данные по пульсу. Обычно я переношу в дневник данные из стравы или из movescount.com (так как тренировки я записываю при помощи часов suunto ambit 3). Самое сложное при этом — не забыть с утра измерить свой пульс в покое, что является показателем общей усталости и перетренированности, если она вдруг возникнет. Выглядит дневник так:



    Наши дэшборды начиная с версии 15.2 позволяют импортировать данные из экселя, поэтому для использования их достаточно просто сохранить в файл в формате xls.

    Конечно, для построения дэшборда данные пришлось немного «причесать». Я проставил правильные форматы (числовой или временной) для ячеек, удалил некорректные значения, а также добавил колонку «Тип активности», чтобы по ней можно было агрегировать. Она может принимать одно из следующих значений -«Road bike», «MTB», «Велотренажер», «Бассейн», «Бег» и «Тренажерный зал», которые я проставил руками для каждой тренировки.

    Что бы мне хотелось увидеть на моем дэшборде:

    — стандартную статистику по пробегам по типу активности — общие цифры пробега, времени и набора высот по типам активностей, а также их графики по времени,
    — историю тренировок по дням недели, примерно как это выглядит в страве,
    — какие-либо данные по пульсу, например корреляцию между средним пульсом на тренировке и средней скоростью,
    — ну и конечно же, дэшборд должен быть живым, то есть не быть просто статической картинкой. В нем должен быть максимум интерактивности, чтобы можно было выбирать какой-то конкретный срез данных и посмотреть на них «более внимательно».

    Теперь можно запустить дизайнер (а чтобы сделать дизайнер, достаточно создать новое WinForms приложение, добавить на форму DashboardDesigner и сгенерировать для него риббон), создать новый дэшборд (или аналитическую панель, как написано в русской локализации). Начнем с добавления в него источника данных из Excel:



    Далее, добавим на дэшборд карточки, поместим поле «тип активности» в ряды данных (Series), и сделаем несколько карточек (по времени и по пробегу). Однако, тут есть несколько проблем:

    Во-первых, длительность тренировки приходит из экселя в виде DateTime колонки, в которой составляющая даты равна 01.01.0001. Суммировать даты невозможно, и поэтому длительность необходимо перевести в число с плавающей точкой, что можно сделать с помощью вычисляемого поля (calculated field), задав ему выражение GetHour([TM]) + GetMinute([TM]) / 60.0. Тренировок длиннее суток у меня не предвидится, поэтому ограничимся часами и минутами.

    Во-вторых, «голые» карточки смотрятся не очень хорошо, поэтому хорошо было бы добавить туда спарклайн. Но, для того, чтобы график красиво смотрелся, нужно сгруппировать данные по неделям. К сожалению, встроенного интервала группировки (Group interval) по неделям и годам у нас нет, а группировать только по номеру недели в году будет неправильно, придется сделать еще одно вычисляемое поле с датой начала недели, чтобы его можно было использовать как значение для группировки. Выражение будет выглядеть так AddDays([Дата], — GetDayOfWeek([Дата]) + 1). Еще чуть-чуть настроек (формат чисел и названия) и получаем следующее:



    Да, дэшборды это не только числа и функциональность, но и красивая картинка. При разработке конкретного дэшборда приходится учитывать и его визуальную составляющую — все должно хорошо выглядеть.

    После общих цифр мне хотелось бы показать на дэшборде более детальную информацию. Добавим графики объемов тренировок по пробегу, времени, набору высот в разрезе разного типа активностей и дат. Для этого создадим в дэшборде новый элемент — диаграмму (Chart). Чтобы получить группировку по неделям и годам, сначала добавим в аргументы поле «Дата» с группировкой по году, а потом еще раз его же с группировкой «Номер недели в году». Далее добавим несколько панелей (Рane) и добавим на них поля по продолжительности тренировки, времени и набору высоты. Далее, добавим в ряды (Series) тип тренировки, и включим по ним раскраску. Переключим типы графиков на всех панелях в «Stacked bar» (по-русски это звучит как «гистограмма с накоплением») и получим следующую картину:



    Теперь хочется проверить — а правильные ли данные показывает дэшборд? А также удовлетворить любопытство и узнать, что же скрывается под конкретным столбиком на диаграмме. Например, узнать, а что за тренировки были в ту неделю, когда набор высоты перевалил за 3 тыс м? Для этого нужно дать дэшборду его важную способность — интерактивность. Для начала, добавим в дэшборд таблицу (Grid Dashboard Item). Я бы хотел увидеть там детальную информацию по тренировкам — то есть практически все поля из исходных данных. Придется потратить немного времени, добавляя их в таблицу и настраивая опции их отображения. После этого, включим у ранее добавленного графика режим множественного мастер-фильтра и посмотрим, что получилось:



    Таким образом, кликая по графику, можно отфильтровать записи в таблице снизу. А чтобы фильтр не влиял на карточки вверху — им надо выставить режим игнорирования мастер фильтра. Заодно, можно сделать чтобы фильтр срабатывал и при клике по карточке. Только теперь, чтобы он не влиял на графики, им тоже придется запретить реагировать на мастер фильтр.

    Итак, теперь дэшборд позволяет выбрать какой-то один или несколько конкретных типов активностей и увидеть список тренировок по ним в таблице внизу. После этого можно выбрать одну или несколько дат на графиках активности и отфильтровать данные в таблице еще более детально:



    Теперь у нас есть статистика по объемам и датам тренировок, но в исходных данных есть еще данные о пульсе. По идее, средний пульс должен отражать интенсивность тренировки и хотелось бы посмотреть на корреляцию между средним пульсом и средней скоростью, что должно примерно отражать прогресс в тренировках. Конечно, простая зависимость пульс/средняя скорость не будет учитывать то, что по беговой дорожке бежать проще, чем по пересеченной местности, а для велосипеда скорость зависит еще и от качества дороги, ветра и прочих внешних факторов. Но все равно, было бы интересно на неё посмотреть.

    Для этого воспользуемся точечной диаграммой. Поместим средний пульс на ось X, среднюю скорость на ось Y. В аргументы поместим дату поездки, чтобы точки не сливались в одну, и тип активности, чтобы раскрасить разные типы разным цветом (но тем же самым, которым раскрашены элементы диаграммы — спасибо поддержке дэшбордами глобальных палитр). В поле «вес» поместим «набор высот», чтобы отличать поездки по ровному рельефу от поездок с большим набором (но при этом мы теряем тренировки на велостанке, так как, к сожалению, для них нет данных о наборе высот и на диаграмме они показаны не будут).

    Также будет удобно свести к одной шкале темп бега, который задается в минутах/км, и скорость при езде на велосипеде, которая задается в км/ч. Для этого сделаем еще одно вычисляемое поле «Средняя скорость/темп бега» со следующим выражением: Iif([AVS темп] < 1, [AVS темп] * 24, [AVS темп])

    Вообще говоря, есть еще и плавание, где темп часто записывают в мин/100м, но точных данных по скорости в бассейне у меня набралось мало, да и набор высот в бассейне не имеет смысла. Поэтому скорость в бассейне я учитывать в этом выражении не стал. В лыжах скорость также часто записывают в виде темпа, как и при беге — но автор этих строк не очень любит беговые лыжи.

    Включим для получившейся диаграммы режим фильтрации, чтобы по конкретному значению можно было узнать, какие тренировки в него попали. Итоговый дэшборд будет иметь следующий вид:



    Что в результате получилось?

    Дэшборд можно использовать для подробного «копания» в данных. Например, можно выбрать только беговые тренировки за определенную неделю и посмотреть для них распределение скорости/пульса. Или выбрать неделю с максимальным объемом тренировок и посмотреть, что это были за тренировки. Диаграмме пульса при этом покажет корреляцию между интенсивностью тренировки и средним пульсом, а также значения, «выпадающие» из общей тенденции. При этом можно будет легко посмотреть, почему они такие получились. В моем случае это либо большой набор высот, из-за которого при том же среднем пульсе средняя скорость получилась 15 км/ч вместо обычных для такого пульса 22 км/ч, либо специфический тип активности, как например, для мтб, где выделяются последние кросс-кантри гонки прошлого сезона. В которых, несмотря на достаточно экстремальные для меня значения пульса, средняя скорость получилась всего 10 км/ч, что, впрочем, для них нормально.

    Исходный код примера, а также данные и xml файл дэшборда можно скачать с GitHub. Можно как попробовать поменять дэшборд, так и подставить свои данные в xls файл(или добавить свой источник данных).

    Буду рад ответить на все вопросы, как по тренировочному процессу, так и по дэшбордам.
    Developer Soft
    Компания
    Реклама
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее

    Комментарии 15

      –2
      т.е. вы берёте данные из стравы и делаете из них вторую страву?
        +4
        "берете данные из стравы" — не совсем так. При заполнении дневника надо записать средний/максимальный пульс и прочие показатели. Их можно взять из велокомьютера и без стравы, просто иногда из стравы удобнее. Я плачу за премиум аккаунт в страве в основном потому, что она показывает распределение пульса по процентам. Бесплатный мувезкаунт показывает то же самое, но не в процентах, а в абсолютных величинах и я наверно скоро откажусь от премиум аккаунта стравы, так как у неё есть проблемы с получением данных с устройств suunto. Проценты можно посчитать и в экселе.
        Насчет "второй стравы" — все таки страва это соц сеть, с лайкам(кудосами), фотками и гонками на сегментах). Я же пытался визуализировать те данные, которые она не показывает. А так же показать, что у нас это сделать легко. Кроме того, дэшборд, что я сделал можно легко модифицировать и увидеть на нем что-то новое. Страва не дает возможности делать произвольные дэшборды.
          –1
          я наверно скоро откажусь от премиум аккаунта стравы, так как у неё есть проблемы с получением данных с устройств suunto

          Какие у неё могут быть проблемы? ) взял файл и загрузил в страву
          Я же пытался визуализировать те данные, которые она не показывает.

          Да, визуализировать и показывать можно что угодно, но я вот смотрю на график средней скорости к среднему пульсу и у меня даже нет предположения зачем он может быть нужен и чем может быть полезен...
          Но это всё оффтоп получается, если вы хотели показать какая крутая у вас штука.
          P.S. Не обратил внимания, что это очередной рекламный пост очередной компании
            +2
            При загрузке из файла страва не использует показания барометрического альтиметра для моих часов.
            Чем больше пульс — тем больше усилий прилагает человек, чтобы поддерживать скорость.
            При прочих равных, чем более низкий пульс получается у человека при той же средней скорости, тем он выносливее (если грубо объяснять).
            Насчет рекламы — я надеюсь что эта статья чуть интереснее и полезнее, чем просто реклама)
              0
              При загрузке из файла страва не использует показания барометрического альтиметра для моих часов.

              Возможно другой формат файла нужен. Хотя если исходный файл содержит эти данные, то странно что не съедает — об этом можно уже им и в ТП написать.
              Чем больше пульс — тем больше усилий прилагает человек, чтобы поддерживать скорость.

              Охъ, пульс зависит уж Очень от многого, что бы так сильно полагаться на него…
              При прочих равных, чем более низкий пульс получается у человека при той же средней скорости, тем он выносливее (если грубо объяснять).

              Эта мысль просто в дребезги разбивается о рельеф маршрута ), это возможно только если по одному и тому же месту ездить/бегать
              Оффтоп это всё короче
                +2
                Возможно другой формат файла нужен. Хотя если исходный файл содержит эти данные, то странно что не съедает — об этом можно уже им и в ТП написать.

                техподдержка стравы напишет что это у них не поддерживается, уже проходили. Они смотрят на модель устройства который в гпх прописан — если оно попадает в определенный список, то они не обновляют высоту по своей карте.
                Эта мысль просто в дребезги разбивается о рельеф маршрута ), это возможно только если по одному и тому же месту ездить/бегать

                Так набор высот на графике тоже есть. и по одному маршруту тоже можно бегать /ездить. Для себя вполне возможно проводить такие тесты.
              +2
              Какие у неё могут быть проблемы? )

              Здесь, очевидно, пропущен тэг "sarcasm"?
          +2
          Я понимаю, что профиль вашего блога именно C# и собственный платформо-зависимый инструмент, но тем не менее спрошу, а вы не разглядывали уже готовые решения в этой области, для более глубокого и широкого анализа данных (без регистрации, СМС и .net :) ), например http://www.goldencheetah.org ?
            +1
            Ну, было бы странно разрабатывать софт для визуализации данных и не попробовать использовать его на своих данных.
            На http://www.goldencheetah.org посмотрю. Но похоже это еще более продвинутый уровень, с учетом данных с измерителей мощности
              +1
              Большей частью все объективные показатели завязаны на измерение объективных параметров, а к таковым относится пожалуй только измерение мощности. Но и без поверметров можно очень много метрик составить, например советую обратить внимание на понятие тренировочного импульса (TRIMP) потому как это и есть конечная точка накопления данных об объёме работы, а не просто цифра 500 часов за год.
            +1
            Дашборды смотрятся хорошо. Но есть и специальный софт для сбора и анализа статистики со спорт датчиков — goldencheetah, trainingpeaks, stravistix. Всё это применяют обычно вместе с планом тренировок, чтобы достигать нужной формы в нужное время
              0
              Дашборды эти выглядят может и хорошо, а вот работают хреново. Единицы измерения не проставлены, оси не везде подписаны, легенда свёрстана плохо. На графике средней скорости и пульса вообще не ясно что кодируется цветом и размером (радиусом). И это странно, разрабатывать софт для визуализации данных и допускать такие грубые ошибки непосредственно в визуализации.
                0
                Спасибо за замечания. Но позволю себе кое с чем согласиться, кое с чем нет.
                Соглашусь тем, что не подписана ось аргументов на графике активности. Там не получалось сделать хорошую подпись из-за отсутствия week-year интервала
                Легенда на диаграмме скорость пульс убрана, так как она точно такая же, как на соседнем графике, там использованы те же цвета. Нет нужды тратить полезное пространство на повторение одной и той же информации. Единицы измерения можно было бы проставить, но я думаю, что это лишнее, так как и так понятно, что скорость у нас км/ч, а дистанция в километрах.
                Кроме того, при использовании живого дэшборда были бы видны тултипы и некоторых вопросов (а именно, что кодируется размером круга на диаграмме) не возникло бы.
                  –1
                  Там не получалось сделать хорошую подпись из-за отсутствия week-year интервала
                  Оправдание из разряда: «Сделал как мог, потому что как надо не получилось».

                  Легенда на диаграмме скорость пульс убрана, так как она точно такая же, как на соседнем графике, там использованы те же цвета.
                  Это логично для вас, но не для стороннего наблюдателя. На соседнем графике у вас в легенде 6 цветов, а тут всего 3. При этом они искажены из-за прозрачности.

                  Нет нужды тратить полезное пространство на повторение одной и той же информации.
                  Есть, если это позволяет пользователю не строить догадки. И minimal ink Тафти тут не при чём.

                  Единицы измерения, опять заставляете пользователя строить догадки. Тем более не для всех видов активности логичны измерения в километрах, для бассейна вполне можно использовать метры. Я не говорю уже, что не везде метрическая система, кое-где предпочитают мили.

                  Кроме того, при использовании живого дэшборда были бы видны тултипы и некоторых вопросов (а именно, что кодируется размером круга на диаграмме) не возникло бы.
                  Я всегда считал, что смысл визуализации в том, что она упрощает анализ данных. А тут оказывается сначала нужно кликнуть на картинку и проанализировать содержимое тултипа, а потом уже гадать, что же из этих данных коррелирует с размером круга.
                    0
                    Data-ink ratio как раз тут причем. Впрочем, в том и прелесть наших дэшбордов — что можно легко сделать и так и так. Я убрал легенду, так как считаю что она лишняя. Вы хотите оставить — нет проблем, это одна опция. То же самое касается подписей осей, и прочего.
                    По ссылке в конце статьи можно скачать пример дизайнера и попробовать.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое