Оригинальная ссылка:D3.js Tutorial: Building Interactive Bar Charts with JavaScript
Переводчик:OFED
Недавно мы имели удовольствие работать над проектом машинного обучения с участием таких библиотек, как React и D3.js. Для многих задач я разработал несколько графиков, чтобы показать результаты моделей машинного обучения, таких как Наивный Байес, представленных в виде линейных графиков или сгруппированных столбчатых диаграмм.
В этой статье я расскажу о процессе использования D3.js и продемонстрирую базовое использование библиотеки на примере простой гистограммы.
Прочитав эту статью, вы научитесь легко создавать подобные диаграммы D3.js:
Вот полныйисходный код
Нам нравится экосистема JavaScript в RisingStack (компания), как на интерфейсе, так и на сервере. Лично меня интересует и перед и зад. Благодаря внутренней разработке я могу видеть основную бизнес-логику приложения, а также иметь возможность создавать потрясающие эффекты во внешнем интерфейсе. Здесь на помощь приходит D3.js!
Что такое D3.js?
D3.js — это библиотека JavaScript для управления документами на основе данных.
«D3 помогает вам представлять данные с помощью HTML, CSS, SVG и Canvas. D3 соответствует существующим веб-стандартам, может работать в современных браузерах без какой-либо другой платформы и сочетает в себе мощные визуальные компоненты для управления DOM-манипулированием».d3js.org
Сначала подумайте, зачем использовать D3.js для создания диаграмм? Почему бы просто не показать фотографии?
Диаграммы основаны на информации из сторонних ресурсов и должны динамически визуализироваться при рендеринге. Кроме того, SVG — очень мощный инструмент, идеально подходящий для этого случая.
Давайте сначала посмотрим, что хорошего в SVG.
Преимущества SVG
SVG расшифровывается как Scalable Vector Graphics, технически это язык разметки на основе XML.
Он часто используется для рисования векторной графики, такой как линии и фигуры, или для изменения существующих изображений. ты сможешьздесьНайдите список доступных элементов.
преимущество:
- Поддержка всех основных браузеров;
- Есть интерфейс DOM, сторонняя библиотека не требуется;
- Масштабируемость для поддержания высокого разрешения;
- По сравнению с другими форматами изображений, меньше.
недостаток:
- Только двумерные изображения могут быть отображены только;
- долгая кривая обучения;
- Для операций с интенсивными вычислениями рендеринг может занять много времени.
Несмотря на свои недостатки, SVG — отличный инструмент для отображения значков, логотипов, иллюстраций или диаграмм, упомянутых в этой статье.
Начало работы с D3.js
Я решил начать с гистограммы, потому что она представляет собой визуальный элемент низкой сложности, а также учит основам самого D3.js. Без шуток, D3 предоставляет отличный набор инструментов для визуализации данных. посмотри на этоgithub pageстраницу, оцените некоторые действительно хорошие варианты использования!
Гистограмма может быть горизонтальной или вертикальной, в зависимости от ее ориентации. Начнем с вертикальной гистограммы.
В этой диаграмме я буду основываться на Stack Overlow 2018.Результаты опроса разработчиковОтображает десятку самых популярных языков программирования.
Нарисуй это!
Система координат SVG начинается в верхнем левом углу (0;0). Положительная ось x направлена вправо, положительная ось y – вниз. Поэтому при вычислении координаты y элемента необходимо учитывать высоту SVG.
Базовые знания почти готовы, давайте кодить!
Я хочу создать диаграмму шириной 1000 пикселей и высотой 600 пикселей.
<body>
<svg />
</body>
<script>
const margin = 60;
const width = 1000 - 2 * margin;
const height = 600 - 2 * margin;
const svg = d3.select('svg');
</script>
В приведенном выше фрагменте кода я использую d3select
Создано с выбранным HTML<svg>
элемент. Этот метод выбора принимает различные типыстрока выбораи возвращает первый соответствующий элемент. Если вы хотите получить все совпадающие элементы, используйтеselectAll
.
Я также определяю значение поля, которое дает небольшой интервал на диаграмме. Интервал также может быть применен к<g>
элемент, черезtranslate
Переместите нужное значение. С этого момента я буду рисовать в этой группе, соблюдая разумный интервал от остальной части страницы.
const chart = svg.append('g')
.attr('transform', `translate(${margin}, ${margin})`);
Добавление атрибутов к элементу похоже на вызовattr
Метод так же просто. Первый параметр метода принимает свойства для выбранного элемента DOM. Второй параметр - это значение свойства или функция обратного вызова, которая возвращает его значение. Приведенный выше код просто перемещает происхождение диаграммы в положение (60; 60) положение SVG.
Формат источника данных, поддерживаемый D3.js
Чтобы начать построение графика, мне нужно определить источник данных для использования. Для этого руководства я использовал простой массив JavaScript, который содержит объекты с названиями языков и их процентами, но здесь важно упомянуть, что D3.js поддерживает различные форматы данных.
Библиотека имеет встроенные функции для загрузки данных из источников данных, таких как XMLHttpRequest, файлы .csv, текстовые файлы и т. д. Каждый источник данных может содержать данные, доступные D3.js, и самое главное — собрать их в массивы. Обратите внимание, что изВерсия 5.0Первоначально библиотека D3 использовала промисы вместо обратных вызовов для загрузки данных, что было изменением, несовместимым с предыдущими версиями.
масштабирование, ось
Перейдем к осям диаграммы. Чтобы нарисовать ось Y, мне нужно установить минимальное и максимальное значения, равные 0 и 100 соответственно.
В этом уроке я рассматриваю использование процентов, но есть вспомогательные функции для других типов данных, помимо чисел, которые я объясню позже.
Я должен разделить высоту диаграммы поровну между этими двумя значениями. Для этого я создал функцию масштабирования.
const yScale = d3.scaleLinear()
.range([height, 0])
.domain([0, 100]);
Линейное масштабирование является наиболее распространенным типом масштабирования. Он преобразует непрерывный входной диапазон в непрерывный выходной диапазон. осторожностьrange
а такжеdomain
метод. Первыйrange
Длина, полученная методом, должна быть вdomain
между граничными значениями.
Помните, что система координат SVG начинается с верхнего левого угла, поэтомуrange
Возьмите высоту в качестве первого параметра вместо нуля.
Создать ось слева так же просто, как добавить еще одну группу, вызвав d3.axisLeft
метод и принимает функцию масштабирования в качестве аргумента.
chart.append('g')
.call(d3.axisLeft(yScale));
Теперь добавим ось X.
const xScale = d3.scaleBand()
.range([0, width])
.domain(sample.map((s) => s.language))
.padding(0.2)
chart.append('g')
.attr('transform', `translate(0, ${height})`)
.call(d3.axisBottom(xScale));
Обратите внимание, что я используюscaleBandМетод создает ось x, которая делит ось x на сегменты, и использует оставшиеся промежутки для вычисления координат и ширины гистограммы.
D3.js также может обрабатывать многие другие типы дат.scaleTimeа такжеscaleLinearОчень похоже, только здесь домен — это массив дат.
Нарисуйте гистограмму с помощью D3.js
Подумайте о том, какие входные данные нам нужны для рисования столбцов. Каждый из них представляет значение, представленное простой формой, особенно прямоугольником. В следующем коде я добавляю их к созданному элементу группировки.
chart.selectAll()
.data(goals)
.enter()
.append('rect')
.attr('x', (s) => xScale(s.language))
.attr('y', (s) => yScale(s.value))
.attr('height', (s) => height - yScale(s.value))
.attr('width', xScale.bandwidth())
во-первых, яselectAll
Все элементы на диаграмме, возвращаемый результат пуст. Потом,data
Функция сообщает DOM, сколько элементов следует обновить в зависимости от длины массива. Если количество данных больше, чем количество DOM, тоenter
Выявляются недостающие элементы.enter
Возвращает элемент, который необходимо добавить.
Обычно вслед заappend
Метод добавит элемент в DOM.
По сути, я использую D3.js для добавления прямоугольника к каждому элементу массива.
В настоящее время только прямоугольники без ширины и высоты добавляются друг к другу. Эти два свойства должны быть вычислены из предыдущей функции масштабирования.
Я звонюattr
метод добавляет координаты прямоугольника. Второй параметр может быть обратным вызовом, который возвращает 3 параметра: текущие связанные данные, индекс и массив всех данных.
.attr(’x’, (actual, index, array) =>
xScale(actual.value))
Функция масштабирования возвращает координаты для заданного диапазона значений. Вычислить координаты несложно, хитрость в том, чтобы использовать высоту столбцов. Вычисленная координата y должна быть вычтена из высоты диаграммы, чтобы получить правильное значение столбца.
Функция масштабирования также используется для определения ширины прямоугольника.scaleBand
есть одинbandwidth
Функция, которая возвращает расчетную ширину элемента на основе заданного интервала.
Хорошая работа, но не такая красивая, правда?
Чтобы зрители не устали, давайте добавим немного информации для улучшения визуальных эффектов!
Советы по созданию столбчатых диаграмм
Есть несколько основных правил, о которых стоит упомянуть.
- Избегайте использования 3D-эффектов;
- Сортировать точки данных визуально - по алфавиту или по номерам;
- Соблюдайте определенное расстояние между прутьями;
- Ось Y начинается с 0, а не с минимального значения;
- используйте однородные цвета;
- Добавьте метки осей, заголовки, направляющие.
Система сетки D3.js
Я хочу добавить линии сетки на заднем плане, чтобы выделить эти значения.
Можно добавить как вертикальные, так и горизонтальные линии, я предлагаю добавить только одну. Слишком большое количество линий может отвлекать. Следующие фрагменты кода демонстрируют, как добавить горизонтальную и вертикальную сетки.
chart.append('g')
.attr('class', 'grid')
.attr('transform', `translate(0, ${height})`)
.call(d3.axisBottom()
.scale(xScale)
.tickSize(-height, 0, 0)
.tickFormat(''))
chart.append('g')
.attr('class', 'grid')
.call(d3.axisLeft()
.scale(yScale)
.tickSize(-width, 0, 0)
.tickFormat(''))
В этом случае я предпочитаю вертикальные линии сетки, потому что они направляют взгляд и сохраняют общую картину четкой и ясной.
Метки в D3.js
Я также хотел бы добавить несколько текстовых руководств, чтобы сделать диаграмму более всеобъемлющей. Давайте назвать диаграмму и добавить этикетки на оси.
Текст — это элемент SVG, который также можно добавить в SVG или сгруппировать. Их можно расположить с помощью координат x и y, а выравнивание текста выполняется с помощьюtext-anchor
реализованы свойства.
Чтобы добавить текст метки, просто вызовите текстовый элементtext
метод.
svg.append('text')
.attr('x', -(height / 2) - margin)
.attr('y', margin / 2.4)
.attr('transform', 'rotate(-90)')
.attr('text-anchor', 'middle')
.text('Love meter (%)')
svg.append('text')
.attr('x', width / 2 + margin)
.attr('y', 40)
.attr('text-anchor', 'middle')
.text('Most loved programming languages in 2018')
Взаимодействие с D3.js
Наши диаграммы уже богаты, но мы все еще можем добавить немного интерактивности.
В следующем коде показано, как добавить прослушиватели событий к элементам SVG.
svgElement
.on('mouseenter', function (actual, i) {
d3.select(this).attr(‘opacity’, 0.5)
})
.on('mouseleave’, function (actual, i) {
d3.select(this).attr(‘opacity’, 1)
})
Обратите внимание, что я использовал функциональное выражение вместо функции со стрелкой, потому что я обращаюсь к элементам через ключевое слово this.
Когда указатель мыши наводится на выбранный элемент SVG, его прозрачность становится равной половине исходного значения, а когда указатель мыши покидает элемент, прозрачность возвращается к исходному значению.
Вы также можете пройтиd3.mouse
Получить координаты мыши. Он возвращает массив с координатами x и y. Этого можно добиться, отображая подсказку о положении курсора.
Создание потрясающих диаграмм не так просто.
Может потребоваться мудрость графических дизайнеров, исследователей UX и других замечательных людей. В следующих примерах показано несколько возможностей улучшить производительность диаграммы!
Наши графики показывают очень похожие значения, поэтому, чтобы выделить различия между значениями столбцов, я добавилmouseenter
мероприятие. Всякий раз, когда пользователь наводит курсор на определенный столбец, в верхней части этого столбца рисуется горизонтальная линия. Также я рассчитал разницу с другими барами и отобразил на соответствующих барах.
Очень аккуратно, правда? Я также увеличил прозрачность в этом примере и сделал полосы шире.
.on(‘mouseenter’, function (s, i) {
d3.select(this)
.transition()
.duration(300)
.attr('opacity', 0.6)
.attr('x', (a) => xScale(a.language) - 5)
.attr('width', xScale.bandwidth() + 10)
chart.append('line')
.attr('x1', 0)
.attr('y1', y)
.attr('x2', width)
.attr('y2', y)
.attr('stroke', 'red')
// 部分实现,整体效果见源码
})
transition
указывает, что я хочу анимировать изменения DOM. Его временной интервал используетсяduration
Устанавливается функцией, которая принимает миллисекунды в качестве аргумента. Переход выше осветлит цвет полос и увеличит ширину полос.
Чтобы нарисовать линию SVG, мне нужны начальная и конечная точки. Это можно сделать с помощьюx1
,y1
а такжеx2
,y2
координаты для установки. пока я не используюstroke
Свойство задает цвет линии до того, как она станет видимой.
показано только здесьmouseenter
Помните, что эта часть мероприятия должна быть вmouseout
Отменить или удалить изменения в событии. Полный исходный код приведен в конце этой статьи.
Давайте добавим стиль к диаграмме!
Давайте рассмотрим, что мы сделали до сих пор, и как стилизовать диаграмму.через ранее использованныйattr
Метод для добавления атрибута класса к элементу SVG.
В отличие от неподвижных статических изображений, наши диаграммы многофункциональны и показывают разницу между отдельными столбцами при наведении курсора мыши. Заголовок пересекает фон сетки, а метки помогают определить единицы измерения для осей. Я также добавил новую метку в правом нижнем углу с указанием источника данных.
Остальное только цвета и шрифты!
Диаграммы с темным фоном заставляют яркие столбцы выглядеть круто. я также использовалopen Sans
шрифт и установить разные размеры и толщину для разных надписей.
Обратите внимание на эту пунктирную линию? это черезstroke-width
а такжеstroke-dasharray
реализованы свойства. использоватьstroke-dasharray
, вы можете определить шаблон и расстояние между пунктирными линиями, тем самым изменив контур фигуры.
line#limit {
stroke: #FED966;
stroke-width: 3;
stroke-dasharray: 3 6;
}
.grid path {
stroke-width: 3;
}
.grid .tick line {
stroke: #9FAAAE;
stroke-opacity: 0.2;
}
Линии сетки сложны, я использовал элементы контура в группировке.stroke-width: 0
, чтобы скрыть рамку таблицы, я также уменьшаю видимость линий, устанавливая их прозрачность.
Все остальные CSS, связанные с размером и цветом шрифта, могут ссылаться на исходный код.
Завершение нашего руководства по гистограмме D3.js
D3.js — потрясающая библиотека для работы с DOM. Внутри него скрыты бесчисленные сокровища, ожидающие вашего исследования (точнее, не закопанные и хорошо задокументированные). В этой статье используется лишь верхушка айсберга набора инструментов для создания необычной гистограммы.
Продолжайте исследовать, и вы обязательно создадите невероятные визуальные эффекты!
Это пример этой статьиисходный кодссылка на.
Вы сделали что-то классное с D3.js? Поделись с нами! Если у вас есть какие-либо вопросы или вы хотите еще один урок по этой теме, пожалуйста, оставьте комментарий!
Спасибо за чтение, увидимся в следующий раз!