Статьи

Работа с D3.js

Примечание редактора: Написано Мэттом Глисоном для Shine Technologies.

D3.js — это библиотека JavaScript, которая используется для генерации визуализаций, обычно основанных на наборах данных. В прошлом месяце я использовал его в проекте панели мониторинга и хотел поделиться некоторыми своими мыслями и впечатлениями как новый пользователь.

Первые впечатления

Первое, что привлекло меня при использовании D3, это то, что он использует доступные компоненты современных браузеров (HTML5, Javascript, CSS, SVG), не требуя установки плагина для его работы.

По мере разработки этих визуализаций вы можете видеть все компоненты, которые вы создаете и которыми манипулируете прямо в DOM. Использование инструментов Chrome dev для проверки DOM во время работы означает, что довольно легко увидеть, что происходит, когда вы научитесь использовать D3, и увидеть, где вы ошибаетесь.

Поскольку вы имеете дело с элементами DOM, вы можете в полной мере использовать преимущества CSS, сохраняя свой JavaScript-код относительно чистым.

Другим большим плюсом для меня было сходство с jQuery с его селекторами и операторами. Воспользовавшись jQuery в течение некоторого времени (и обнаружив, что само по себе откровение, когда я его обнаружил), знакомство определенно помогло в процессе обучения.

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

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

Получение технического

Я не буду вдаваться в полный пример, но попытаюсь дать вам понять, чего ожидать.

Скажем, вы хотите создать гистограмму для представления набора данных.
Сначала вы связываете данные с селектором DOM, затем объединяете enter()команду, которая выполняет итерации по данным, и затем объединяете append()команду в цепочку, чтобы создать элементы, соответствующие исходному селектору. Код может выглядеть примерно так:

var svg = d3.select("svg");

var bars = svg.selectAll("rect")
    .data(dataset)
    .enter()
    .append("rect")
    .attr({ x: …,
            y: …,
            height: …, // height based on dataset values.
            width: … });

Затем поразитесь тому, что происходит при обновлении значений в наборе данных:

bars.data(newDataset)
.transition()
.duration(2000)
.attr({ height: … }); // new height based on newDataset

Как и магия, график изменится на ваших глазах. Это действительно был «вау» момент для меня.

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

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

<path d="M75,82.40274599542334Q129.4,79.8350114416476,14

Помоги мне!

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

Система координат X, Y в D3 начинается с (0,0) в верхнем левом углу вашей страницы, причем X увеличивается вправо, а Y увеличивается вниз по странице. Сравните это со своей стандартной гистограммой, которая обычно имеет (0,0) в левом нижнем углу — так что, по сути, ось Y перевернута вверх дном.

К счастью, D3 приходит на помощь с удобной scale()функцией. Это помогает преобразовать ваши точки данных в пиксельные точки:

var myXScale = d3.scale.linear()
    .domain([0, 100])
    .range([20, 400]);

где домен — это минимальный и максимальный входные данные из вашего набора данных, а диапазон — минимальная и максимальная выходная точка для рисования на странице. Таким образом, переход в среднюю точку данных даст вам точку среднего пикселя. например. myXScale(50)возвращает 210

Самое умное в том, что для того, чтобы отобразить ваши данные на «перевернутую» ось Y, все, что вам нужно сделать, — это изменить значения диапазона. Это может выглядеть примерно так:

var myYScale = d3.scale.linear()
    .domain([0, 100])
    .range([400, 20]);

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

Масштабирование действительно помогло с этим.

Пример диаграммы, где использование scale () действительно помогло

Несмотря на то, предоставляется эти помощники, имеющие множество диапазонов чисел и связанное с ними (x,y)(или (x1,y1), (x2,y2)) атрибутами , чтобы иметь дело с может протянуть свою способность к умственной арифметике … или вы всегда можете обратиться к пробам и ошибкам. (В конце концов, простое обновление страницы немедленно покажет вам результат ваших изменений.)

Я нашел документацию D3 также немного недружелюбной. Тем не менее, обширный пул примеров и учебных пособий, доступных в Интернете, еще больше компенсирует это.

Еще у меня возникли проблемы с представлением карты Австралии с выделенными точками на основе координат широты и долготы. Использование данных GeoJSON выглядело как путь, и после того, как я начал искать правильный вид карты с подходящей проекцией (см. D3.geo ), моя функция перевода координат в широту в пиксели привела к тому, что некоторые точки приземлились в океан. В конце концов я обнаружил, что проекция, используемая для построения карты на странице, на самом деле представляет собой перевод широтно-длинных координат в пиксели — и я могу повторно использовать проекцию для своего отображения координат. Результат был, конечно же, идеальным для пикселей!

Итерация, Итерация, Итерация

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

Итерация 1

Итерация 2

Итерация 3

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

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

Вывод

Если вам нужны хорошие результаты без усилий на разработку, вы можете посмотреть на альтернативы, такие как Chart.js . Учитывая то, что мы изначально начали с Chart.js и создали несколько достаточно привлекательных диаграмм, решение использовать D3 было обусловлено великолепной продукцией нашего графического дизайнера.

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