ChartJS — JavaScript-библиотека визуализации данных

в 7:21, , рубрики: charts, html5, javascript, javascript library, Блог компании DevExpress, Веб-разработка, визуализация данных, метки: , , , ,

ChartJS — JavaScript библиотека визуализации данных

С каждым годом мир вычислительной техники всё больше и больше переползает в глобальную паутину. HTML5 шагает по планете, и пока никаких признаков замедления его развития и распространения не заметно. Кажется, даже холодильники скоро начнут понимать HTML5!

Мы в DevExpress как никто чувствуем эту тенденцию. И хорошо поработали в этом году!

читатели уже знает о нашем новом фреймворке PhoneJS, которой позволяет опытным веб-разработчикам чувствовать себя уверенно и в разработке для мобильных устройств.

Однако и классическую сторону веб-разработки мы не забыли.

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

Живая картинка, взаимодействующая со смотрящим её человеком, бесценна.

Чтобы веб-разработчики могли показать своим клиентам живые чарты, мы создали библиотеку визуализации данных ChartJS.

Графики? Оно же всё уже есть!

Есть, конечно.
Но всегда есть к чему стремиться и что улучшать.

Что нам хотелось улучшить:

  • графики должны рендериться на клиенте. Зачем — для того, чтобы на клиенте же они могли меняться;
  • создание графика должно быть простым. Если вам для создания графика нужно 100 строчек кода, то это уже как-то немного перебор;
  • однако, если встаёт задача график дополировать до идеала — то и она должна быть решаемой. Только решаться она должна отдельно от первой, и как эволюция кода, а не революция;
  • элегантность. Когда мы рисуем график на основе данных — мы хотим видеть данные, а не рюшечки;
  • графики должны работать во всех браузерах. И не в последнюю очередь, учитывая, куда катится мир — на мобильных устройствах;
  • ну и, собственно, визуализация данных — это не только графики. В нашу библиотеку также входит набор Gauges — “индикаторов” — визуальных элементов, позволяющих визуально оценить значение, и виджет RangeSelector, упрощающий такие манипуляции над данными как фильтрация и масштабирование.
Примеры

К сожалению, я стараюсь не смешивать работу и политику, поэтому классных графиков с “общественных инициатив” у меня не будет.

Чтобы сохранить интерес интернет-аудитории, выход у меня фактически один — нарисовать график с котятками!

ChartJS — JavaScript библиотека визуализации данных

Кошки окружают нас. Многие кухонные разговоры рано или поздно сводятся к пушистым любимцам.

Я задался вопросом — какой, в действительности, процент DevExpress’овцев держит питомца? Каков их любимец, насколько похож на идеального котёнка с фотографии, или же больше напоминает кота Саймона из небезызвестных мультиков?

Мысль порождает действие. Был организован небольшой социологический опрос среди наших коллег. Шуточный, конечно — ведь мы же всё-таки говорим о котятках! — но с претензией на некоторую репрезентативность.

Результаты этого опроса представляют собой табличку с цифрами.

Но лишь определенный процент людей действительно получает удовольствие, глядя на таблички с сухими цифрами (ну, если мы не говорим о таблицах, показывающих рост зарплаты!)

Давайте лучше посмотрим на эти данные в картинках.

Какова же доля людей — любителей кошачьих — в компании, преимущественно занимающейся разработкой?
ChartJS — JavaScript библиотека визуализации данных

(да, код лежит тут, а рядом можно будет найти код всех нижеследующих примеров)

Не так уж и много, но, с другой стороны, не так уж и мало — почти каждый четвертый или уже делит своё жилище с четвероногим другом, или собирается. А некоторые — и не с одним!

А кто они, эти коты и кошки?
В мире сейчас существует около семи десятков пород кошек. В России можно встретить порядка 40 пород, а широко распространены и того меньше. Какие же кошки живут у наших программистов? Насколько одних больше, чем других?

Для представления такой информации можно взять простейший тип серий — столбики, или Bar chart. Такой график на бумаге не даёт одного важного момента — невозможно, с первого взгляда определив наиболее распространенную породу, представить её себе вживую. К счастью, современный веб полностью построен на интерактивности и взаимодействии с пользователем. И с помощью ChartJS совсем не тяжело добавить возможность показать фотографию кота при взаимодействии пользователя с диаграммой:
ChartJS — JavaScript библиотека визуализации данных

Играться можно тут.

И тут при взгляде на картинку не нужно никаких сомнений и раздумий — факты бросаются в глаза: хотя некоторые виды породистых кошек и пользуются определенной популярностью (есть даже довольно экзотические виды) — всё же неуклонную победу над котами-аристократами одерживают обычные серо-бело-рыжие кошки и коты.

Кстати, а кошки или коты?
Это тоже показать несложно — давайте рассматривать данные по кошкам и котам как две отдельные величины, которые можно представить с помощью двух серий данных:

ChartJS — JavaScript библиотека визуализации данных

Уже хорошо видно, сколько кого — кошек или котов, и кого больше. Можно сравнить количество британских кошек с количеством сиамских котов.
Но зато стало чуть хуже видно, каких пород больше в сумме.
Продолжим улучшать график — вместо рядом стоящих баров покажем те же данные в виде составных баров (stacked bar):

ChartJS — JavaScript библиотека визуализации данных

Кстати, если точное количество животных нам вообще не интересно, а важно только соотношения внутри каждой породы, мы можем вообще избавиться от визуальной составляющей количества, используя серию Full Stacked Bar:

ChartJS — JavaScript библиотека визуализации данных

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

Единственное хорошее решение — предоставить пользователям самим выбирать, что и как они хотят увидеть:

ChartJS — JavaScript библиотека визуализации данных

Именно для динамического изменения типа графиков, которого можно добиться с помощью трех строк кода — считая египетские скобки — мы и создавали ChartJS.

Количество — не единственный показатель, посвященный нашим котам.
Например: мало кто с тем же успехом, как типичный представитель семейства кошачьих, способен убеждать людей в том, что последние сутки он голодал. Нередко результатом становятся коты, помаленьку догоняющие своим весом хозяев.

Каков же вес DX-котов? Какой кот самый легкий, а какой — самый тяжелый? И зависит ли это от породы?
Давайте посмотрим на средний вес для каждой из пород, а также на то, до каких пределов доходят их представители. Для отображения диапазонов прекрасно подходят типы серий RangeBar и RangeArea:

ChartJS — JavaScript библиотека визуализации данных

(Да, к сожалению, некоторые кошки присутствуют в единственном экземпляре; для них средний вес естественным образом совпадает с ним самим. Код примера — тут)

Уже становится потихоньку ясно, у какой породы глаза могут стать самыми жалостливыми!..
Ну, или кого стоит бояться в тёмном переулке…

Главное, конечно, помнить, что в кормлении кошки нельзя впадать в крайности; напротив, нужно придерживаться золотой середины!

ChartJS — JavaScript библиотека визуализации данных

Ведь перекармливание тоже может испортить характер… Лучше заранее оценить хотя бы приблизительно, как отразятся на настроении кота те или иные объемы кормления.

ChartJS — JavaScript библиотека визуализации данных

(Код примера здесь. При создании примера данные были подобраны согласно ощущениям автора и не пострадало ни одно животное!)

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

ChartJS — JavaScript библиотека визуализации данных

Код примера масштабирования графика.

Позвольте ещё немного снизить градус серьезности!

Появившись в доме, кошка занимает весь дом. Следы её пребывания можно найти везде.
Сколько шерсти в среднем кошка оставляет на одежде хозяина? Если, конечно, оставляет в принципе… Потому что иногда нам нужно показать зрителю не просто значение, равное нулю, а отсутствие значения как таковое:

ChartJS — JavaScript библиотека визуализации данных

Код примера Null Values.

Ну и последним пунктом — отдельный вопрос, конкретно посвященный нашей профессии.
Как влияет любимый язык программирования хозяина на общую кошкость животного?

Ну, тут конечно приходится как-то количественно определять понятие «кошкость»… После некоторых дебатов были выбраны два критерия:

  1. длина хвоста;
  2. количество царапин, получаемое хозяином во время игры.

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

ChartJS — JavaScript библиотека визуализации данных

Выводы из картинки весьма интересны. По длине хвоста бесспорным лидером является С++ — оно и неудивительно! За ним, довольно неожиданно, следует Delphi, а замыкает тройку лидеров довольно неожиданные Photoshop Action Script — есть сильное подозрение, что это постарались коты Design Team… Они же, кстати, показали вполне уверенно и на когтевом поле… Но и вполовину не так, как коты C#! Вот те, очевидно, настоящие звери!

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

ChartJS — JavaScript библиотека визуализации данных

Видно, что среднее значение по C# хоть и велико, но находится почти в самом низу распределения величин. То есть большая часть C#-котов — нормальные милые друзья человека. За высокое же среднее значение, вероятно, отвечают один или несколько кошачьих терминаторов.

На этом позвольте завершить наш краткий визуальный анализ кошек DX.

О данных для анализа

Да, предваряя неизбежные вопросы — мы действительно делали онлайн-опрос среди сотрудников. При расчете количества людей мы приняли, что 90% сотрудников нашего основного офиса заметили этот опрос и поучавствовали в нём, и график количества людей строили на этом предположении.
Вопрос о породе давался открытым, со свободным заполнением; в итоге пришлось-таки обработать результаты. Представителя породы «полусиамская» записали в сиамские; гордых же представителей пород «дворняга», «обыкновенная», «рыжий» и «тульская машзаводская» и вовсе поместили в категорию «беспородная». В общем, всё как в настоящей статистике!
Исключением являются график, посвященный количеству оставляемой кошками шерсти, и схема с индикатором настроения кота в зависимости от кормления. Эти две визуализации полностью являются плодом фантазии автора.
И в любом случае, стоить помнить о специфике статистики как науки. Не забывайте — 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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js