С каждым годом мир вычислительной техники всё больше и больше переползает в глобальную паутину. HTML5 шагает по планете, и пока никаких признаков замедления его развития и распространения не заметно. Кажется, даже холодильники скоро начнут понимать HTML5!
Мы в DevExpress как никто чувствуем эту тенденцию. И хорошо поработали в этом году!
читатели уже знает о нашем новом фреймворке PhoneJS, которой позволяет опытным веб-разработчикам чувствовать себя уверенно и в разработке для мобильных устройств.
Однако и классическую сторону веб-разработки мы не забыли.
Люди по-прежнему получают информацию из интернета.
К сожалению, эти же люди по-прежнему не любят читать долгие и нудные отчеты.
Картинка стоит тысячи слов.
Живая картинка, взаимодействующая со смотрящим её человеком, бесценна.
Чтобы веб-разработчики могли показать своим клиентам живые чарты, мы создали библиотеку визуализации данных ChartJS.
Графики? Оно же всё уже есть!
Есть, конечно.
Но всегда есть к чему стремиться и что улучшать.
Что нам хотелось улучшить:
- графики должны рендериться на клиенте. Зачем — для того, чтобы на клиенте же они могли меняться;
- создание графика должно быть простым. Если вам для создания графика нужно 100 строчек кода, то это уже как-то немного перебор;
- однако, если встаёт задача график дополировать до идеала — то и она должна быть решаемой. Только решаться она должна отдельно от первой, и как эволюция кода, а не революция;
- элегантность. Когда мы рисуем график на основе данных — мы хотим видеть данные, а не рюшечки;
- графики должны работать во всех браузерах. И не в последнюю очередь, учитывая, куда катится мир — на мобильных устройствах;
- ну и, собственно, визуализация данных — это не только графики. В нашу библиотеку также входит набор Gauges — “индикаторов” — визуальных элементов, позволяющих визуально оценить значение, и виджет RangeSelector, упрощающий такие манипуляции над данными как фильтрация и масштабирование.
Примеры
К сожалению, я стараюсь не смешивать работу и политику, поэтому классных графиков с “общественных инициатив” у меня не будет.
Чтобы сохранить интерес интернет-аудитории, выход у меня фактически один — нарисовать график с котятками!
Кошки окружают нас. Многие кухонные разговоры рано или поздно сводятся к пушистым любимцам.
Я задался вопросом — какой, в действительности, процент DevExpress’овцев держит питомца? Каков их любимец, насколько похож на идеального котёнка с фотографии, или же больше напоминает кота Саймона из небезызвестных мультиков?
Мысль порождает действие. Был организован небольшой социологический опрос среди наших коллег. Шуточный, конечно — ведь мы же всё-таки говорим о котятках! — но с претензией на некоторую репрезентативность.
Результаты этого опроса представляют собой табличку с цифрами.
Но лишь определенный процент людей действительно получает удовольствие, глядя на таблички с сухими цифрами (ну, если мы не говорим о таблицах, показывающих рост зарплаты!)
Давайте лучше посмотрим на эти данные в картинках.
Какова же доля людей — любителей кошачьих — в компании, преимущественно занимающейся разработкой?
(да, код лежит тут, а рядом можно будет найти код всех нижеследующих примеров)
Не так уж и много, но, с другой стороны, не так уж и мало — почти каждый четвертый или уже делит своё жилище с четвероногим другом, или собирается. А некоторые — и не с одним!
А кто они, эти коты и кошки?
В мире сейчас существует около семи десятков пород кошек. В России можно встретить порядка 40 пород, а широко распространены и того меньше. Какие же кошки живут у наших программистов? Насколько одних больше, чем других?
Для представления такой информации можно взять простейший тип серий — столбики, или Bar chart. Такой график на бумаге не даёт одного важного момента — невозможно, с первого взгляда определив наиболее распространенную породу, представить её себе вживую. К счастью, современный веб полностью построен на интерактивности и взаимодействии с пользователем. И с помощью ChartJS совсем не тяжело добавить возможность показать фотографию кота при взаимодействии пользователя с диаграммой:
Играться можно тут.
И тут при взгляде на картинку не нужно никаких сомнений и раздумий — факты бросаются в глаза: хотя некоторые виды породистых кошек и пользуются определенной популярностью (есть даже довольно экзотические виды) — всё же неуклонную победу над котами-аристократами одерживают обычные серо-бело-рыжие кошки и коты.
Кстати, а кошки или коты?
Это тоже показать несложно — давайте рассматривать данные по кошкам и котам как две отдельные величины, которые можно представить с помощью двух серий данных:
Уже хорошо видно, сколько кого — кошек или котов, и кого больше. Можно сравнить количество британских кошек с количеством сиамских котов.
Но зато стало чуть хуже видно, каких пород больше в сумме.
Продолжим улучшать график — вместо рядом стоящих баров покажем те же данные в виде составных баров (stacked bar):
Кстати, если точное количество животных нам вообще не интересно, а важно только соотношения внутри каждой породы, мы можем вообще избавиться от визуальной составляющей количества, используя серию Full Stacked Bar:
Последние три графика являются прекрасным примером того, какое влияние может оказывать на человеческое восприятие всего одна строчка кода. С помощью минимального кода можно склонить наших пользователей к тем или иным мыслям и выводам, заставить увидеть, что отношение кошек и котов среди самых популярных беспородных и следующих за ними британских пород почти одинаково — на первых графиках этого было не видно. Зато на последнем совершенно потерялось количество…
Единственное хорошее решение — предоставить пользователям самим выбирать, что и как они хотят увидеть:
Именно для динамического изменения типа графиков, которого можно добиться с помощью трех строк кода — считая египетские скобки — мы и создавали ChartJS.
Количество — не единственный показатель, посвященный нашим котам.
Например: мало кто с тем же успехом, как типичный представитель семейства кошачьих, способен убеждать людей в том, что последние сутки он голодал. Нередко результатом становятся коты, помаленьку догоняющие своим весом хозяев.
Каков же вес DX-котов? Какой кот самый легкий, а какой — самый тяжелый? И зависит ли это от породы?
Давайте посмотрим на средний вес для каждой из пород, а также на то, до каких пределов доходят их представители. Для отображения диапазонов прекрасно подходят типы серий RangeBar и RangeArea:
(Да, к сожалению, некоторые кошки присутствуют в единственном экземпляре; для них средний вес естественным образом совпадает с ним самим. Код примера — тут)
Уже становится потихоньку ясно, у какой породы глаза могут стать самыми жалостливыми!..
Ну, или кого стоит бояться в тёмном переулке…
Главное, конечно, помнить, что в кормлении кошки нельзя впадать в крайности; напротив, нужно придерживаться золотой середины!
Ведь перекармливание тоже может испортить характер… Лучше заранее оценить хотя бы приблизительно, как отразятся на настроении кота те или иные объемы кормления.
(Код примера здесь. При создании примера данные были подобраны согласно ощущениям автора и не пострадало ни одно животное!)
Интересно распределение возраста кошек среди наших сотрудников. Наблюдается явный скачок графика в сторону молодых котов. Этот пик не даёт рассмотреть в деталях график животных, которые чуть старше. Тут пригодится возможность масштабирования графика:
Код примера масштабирования графика.
Позвольте ещё немного снизить градус серьезности!
Появившись в доме, кошка занимает весь дом. Следы её пребывания можно найти везде.
Сколько шерсти в среднем кошка оставляет на одежде хозяина? Если, конечно, оставляет в принципе… Потому что иногда нам нужно показать зрителю не просто значение, равное нулю, а отсутствие значения как таковое:
Код примера Null Values.
Ну и последним пунктом — отдельный вопрос, конкретно посвященный нашей профессии.
Как влияет любимый язык программирования хозяина на общую кошкость животного?
Ну, тут конечно приходится как-то количественно определять понятие «кошкость»… После некоторых дебатов были выбраны два критерия:
- длина хвоста;
- количество царапин, получаемое хозяином во время игры.
Надо понимать, что эти два показателя измеряются в разных единицах — первый в сантиметрах, второй — в штуках (ну, или в десятках штук...); показывать их на одной оси — академически неправильно.
Что мы делаем — добавляем на график вторую ось, первый график ассоциируем с основной осью, второй — с только что добавленной.
Чтобы читать график было чуть проще, опционально можно отрисовать их тем же цветом, что мы рисуем данные, и перенести одну из осей на правый край полотна.
Получается вот такая картина:
Выводы из картинки весьма интересны. По длине хвоста бесспорным лидером является С++ — оно и неудивительно! За ним, довольно неожиданно, следует Delphi, а замыкает тройку лидеров довольно неожиданные Photoshop Action Script — есть сильное подозрение, что это постарались коты Design Team… Они же, кстати, показали вполне уверенно и на когтевом поле… Но и вполовину не так, как коты C#! Вот те, очевидно, настоящие звери!
Тут, однако же, кроется подвох. На графике показаны средние значения; вероятно, мы бы их и анализировали, имей на руках только цифры.
Если же на график добавить коридор распределения величин в опросе, картина меняется:
Видно, что среднее значение по C# хоть и велико, но находится почти в самом низу распределения величин. То есть большая часть C#-котов — нормальные милые друзья человека. За высокое же среднее значение, вероятно, отвечают один или несколько кошачьих терминаторов.
На этом позвольте завершить наш краткий визуальный анализ кошек DX.
Вопрос о породе давался открытым, со свободным заполнением; в итоге пришлось-таки обработать результаты. Представителя породы «полусиамская» записали в сиамские; гордых же представителей пород «дворняга», «обыкновенная», «рыжий» и «тульская машзаводская» и вовсе поместили в категорию «беспородная». В общем, всё как в настоящей статистике!
Исключением являются график, посвященный количеству оставляемой кошками шерсти, и схема с индикатором настроения кота в зависимости от кормления. Эти две визуализации полностью являются плодом фантазии автора.
И в любом случае, стоить помнить о специфике статистики как науки. Не забывайте — 100% людей, которые ели огурцы в 1884 году, уже мертвы. Остерегайтесь огурцов!
А кроме котяток эти графики на что-то годятся?
Мы верим, что да.
Конечно, моя аналитика выше зачастую носила явно шуточный характер.
Однако на примере наших кошек я постарался показать некоторые вполне серьезные подходы к визуализации данных. Показать, как выраженные в графической форме данные меняют восприятие тех или иных цифр, и как изменение типа графика изменяет точку зрения, с которой мы эти цифры рассматриваем.
Все графики являются полностью живыми и позволяют в различной форме активно взаимодействовать с пользователем.
Прозрачное изменение типа графиков позволяет пользователю взглянуть с разных сторон на одни и те же данные, вывести новые закономерности, придти к свежим выводам.
Применение индикаторов для оценки выбора пользователя привлекает его внимание и позволяет лучше представить последствия решения.
Масштабирование графика зачастую необходимо для возможности как оценить широкий диапазон данных, так и проанализировать локальные изменения в пределах небольшого диапазона.
Ну и, разумеется, наша библиотека используется в реальных проектах.
Как закалялась сталь
В полном соответствии с принципами гибкой разработки, мы отдали нашу библиотеку на растерзание соседним отделам уже после первых итераций. Нет ничего более полезного для развития продукта, чем его использование в реальных проектах и получение обратной связи от людей.
Отдел техподдержки встроил их в свой сайт, посвященный их вечной борьбе за качество и скорость — анализу поступивших запросов; внутренний отдел использовал для интеграции с багтрекером. А на кухне каждого этажа на телевизоре крутится мини-сайт с графиком количества багов по отделам и динамике изменения количества багов (меня давно посещает желание сопоставить эти графики и графики потребления печенок на кухне — определить корреляцию, но все никак руки не доходят...).
Таким образом, мы могли получать обратную связь максимально рано.
На основе полученных отзывов библиотека расширялась и дополнялась.
Сама наша команда тоже использует наши графики — в инструменте статистики производительности. Конечно, нам далеко до компиляторов C++, написанных на C++, но все равно приятно!
Ближе к релизу библиотеку начали использовать и для более серьезных вещей. Элементы библиотеки используются в новом продукте DevExpress — Dashboards, посвященном анализу большого количества данных, в том числе финансовых. Пример Dashboards на сайте DevExpress.
Виджеты ChartJS годны не только для энтерпрайз-решений. Библиотека вполне успешно работает с железками и микроконтроллерами — что и было успешно продемонстрировано на примере единения решения virt2real и набора метеодатчиков — результаты с графиками в реальном времени доступны в блоге автора.
Под капотом
Реакция довольно большого числа людей (посещающих Хабр), увидевших в интернете что-то интересное — это кликнуть на интересном правой клавишей мыши и выбрать “Inspect element”.
Позвольте мне немного спойлеров.
Для рендеринга графиков мы используем SVG. Эта технология прекрасно работает в большинстве современных браузеров, местами даже использует аппаратное ускорение и при некотором желании стайлится с помощью таблиц стилей CSS. Рендеринг может происходить в несколько этапов, асинхронно, чтобы не занимать движок JavaScript на долгое время и не провоцировать уменьшение отзывчивости пользовательского интерфейса.
Ввиду специфики и цепочки “чарты” -> “анализ данных” -> “корпоративный сектор” -> “windows xp” -> IE 8 у нас просто не было выхода, кроме как подержать этот браузер с помощью использования технологии VML. Переход происходит внутри и незаметно для пользователя.
Это подводит нас к тому, что сами чарты архитектурно устроены во многом по принципу Dependency Injection (DRY и SOLID для нас тоже не пустые аббревиатуры). Я являюсь большим фанатом этого подхода и всячески пропагандирую его. В мире JavaScript этот подход приобрел некоторые интересные черты, о которых я планирую отдельно рассказать в будущем.
Каждый визуальный элемент реализован в виде самостоятельного объекта, принимающего на вход некоторые зависимые объекты (визуальные и невизуальные).
Почти все элементы для расчёта экранных координат полагаются на объект-“транслятор”, задача которого — перевести единицы предметной области (“business values”) в пиксели экрана. Таким образом, этот перевод хорошо изолирован, не дублируется и легко поддается централизованной модификации (например, когда мы выполням изменение масштаба графика).
Если изобразить зависимости между компонентами в виде графа, то мы увидим достаточно чистую иерархическую пирамиду — и мы прикладываем довольно много усилий, чтобы не скатиться в “паутину”, неизбежно заканчивающуюся трудно модифицируемым кодом для нас и длительным ожиданием простейших фич — для наших пользователей. Уже сейчас мы предоставляем из коробки большое количество интересных вещей, а ведь планов у нас ещё громадьё!
Кроме классического подхода к созданию виджетов из чистого JS, мы полностью поддерживаем стремительно набирающий популярность фреймворк Knockout, позволяющий использовать MVVM подход для создания приложений на HTML + JavaScript. Ближайший пример использования — приложение DXWorkout, написанное на PhoneJS.
Почем опиум для народа?
Если вы энтузиаст, если вы работаете на благо общества, если вы ведете опенсурсный проект — то вам оно будет совершенно бесплатно.
Если у вас коммерческий проект, и благодаря нашей библиотеке к вам потекут золотые реки — мы просим некоторую цену за коммерческое использование. Что вы за это получаете? Право использовать библиотеку на любом количестве сайтов и проектов. Неограниченное число вопросов в нашу службу поддержки в течение годового срока подписки. Возможность распространять нашу библиотеку со своими продуктами — а если понадобится, то даже исправленную и дополненную вами — исходный код открыт.
Где можно посмотреть и попробовать?
Библиотека доступна для скачивания на сайте ChartJS.
В нашей демо-галерее ChartJS опубликовано большое количество примеров, позволяющих ознакомиться с различными варинтами конфигурации наших виджетов, ознакомиться с фичами и поиграть с кодом онлайн.
На сайте будут регулярно публиковаться блоги, рассказывающие о фичах, методах, подходах к визуализации данных, методиках выбора правильного отображения данных и связанным с этим вещам.
Я не могу гарантировать наличие там котяток, но это весьма вероятно.
Спасибо за внимание, и хорошего вам всем настроения!
Хорошее настроение всегда помогает творить серьезные дела.
P. S. В статье и примерах использован замечательный сайт placekitten.com, несколько фотографий с российского раздела Википедии (имеющей внушающий раздел про кошек) и несколько фотографий, авторов которых я не смог найти, но чрезвычайно им признателен. И ещё больше — моим коллегам, не пожалевшим времени и рассказавшим мне о своих котах.
Примеры размещены на JSFiddle и доступны в репозитории GitHub.
Автор: kaatula