Я использую D3 уже несколько лет в таких проектах, как 100 компаний и Михмихи, я также писал туториалы по таким вещам, как как рисовать карты. Тем не менее, я никогда не писал введение в D3, потому что трудно передать его великолепие, не просто используя его. Итак, давайте начнем.
Документы, управляемые данными
Прежде всего, D3 — это функциональный набор инструментов для визуализации данных, который привязывает данные к визуальным элементам. Используя связанные данные, атрибуты и внешний вид элементов можно определить с помощью утилит и функций. В этом сила D3; он не ориентирован на визуализацию, он ориентирован на данные и функции для использования этих данных.
Примечание. D3 может использовать любой элемент объектной модели документа (DOM), например элементы SVG или HTML. В этом руководстве будет использоваться D3 с HTML и CSS (вместо SVG), так как с ними знакомо больше разработчиков.
Связывание данных
Давайте привяжем часть данных к элементу body:
d3.select('body').datum('red')
Строка «красный» теперь привязана к телу.
Теперь давайте извлечем эти данные:
d3.select('body').datum() // 'red'
Что может быть за данные? Любой элемент Javascript, например объекты, строки, массивы и т. д. D3 просто запоминает отношения между элементом и данными, чтобы их можно было использовать позже.
Вы можете использовать D3 для установки атрибутов элемента, к которому вы привязали данные:
// changes the body's CSS color to red d3.select('body').style('color', function(datum){ // datum == 'red' return datum } )
Вы также можете связать многие функции, предлагаемые D3, для более удобного использования:
// changes the CSS background-color to 'blue' d3.select('body') .datum('blue') .style('background-color', function(datum){ // datum == 'blue' return datum } )
Если у вас много данных, вы можете выбрать несколько элементов с помощью selectAll и привязать их к этим элементам с помощью функции данных.
Примечание. Многие функции в D3 возвращают Selection, включая данные selectAll и select
// Selection of all p elements p = d3.selectAll('p') // bind data to the first 5 p elements p.data(['red','green','blue','black','white']) // changes the CSS background-color to bound datum p.style('background-color', function(datum){ return datum } )
D3 также помогает, если у вас больше (или меньше) данных, чем существующих элементов. Функции ввода и выхода используются с добавлением и удалением соответственно, чтобы вы могли создавать и уничтожать элементы.
Примечание: функция данных возвращает ограниченный выбор только элементов, которые могут быть привязаны к данным.
// Selection of all p elements in body p = d3.select('body').selectAll('p') // bind data to the first 5 p elements, get restricted Selection pdata = p.data(['red','green','blue','black','white']) // add p elements if they don't already exist pdata.enter().append('p') // remove p elements if there are too many pdata.exit().remove()
Создание функций
Привязка данных к элементам с помощью D3 — это круто, но знаете, что действительно круто? Функции! В D3 есть огромный набор функций высшего порядка (функций, возвращающих функции), которые позволяют легко создавать полезные инструменты для управления данными.
В частности, моя любимая функция в D3 — Весы.
В следующем примере я буду использовать шкалу Сковилла того, насколько остротой отличается перец для нашего примера. Вот некоторые данные (shu расшифровывается как Scoville Heat Unit):
data = [ { name: 'Pimento', shu: 100}, { name: 'Anaheim', shu: 2500}, { name: 'Jalapeno', shu: 10000}, { name: 'Cayenne', shu: 50000}, { name: 'Habanero', shu: 350000}, { name: 'Ghost', shu: 1500000} ]
Квантовать весы
Я начну с создания функции для описания этих данных такими словами, как средний и горячий. Для этого от 0 до 1 500 000 SHU необходимо преобразовать в слова, используя Шкалу квантования, которая имеет непрерывный домен (вход) и дискретный диапазон (выход).
Первое, на что следует обратить внимание, это то, что данные SHU выглядят экспоненциально, поэтому, чтобы сделать их полезными для других функций, можно использовать логарифмическую шкалу.
logscale = d3.scale.log() .domain([1,1500000]) .range([0,1])
Эта шкала создает функцию, которая принимает число от 1 до 1 500 000 и возвращает число от 0 до 1 на логарифмической кривой.
Примечание. Это не очень точная шкала, и вы можете изменить цифры, чтобы получить то, что вам нужно, но для этого примера этого достаточно.
Теперь давайте определим список слов, используя шкалу квантования:
qscale = d3.scale.quantize() .domain([0,1]) .range(['nothing', 'mild','medium','hot' ,'burning','scorching','hellfire'])
Эта функция принимает число от 0 до 1 и возвращает элемент из предоставленного списка слов. Например, qscale(0) вернет «ничего», а qscale(1) вернет «адский огонь».
Чтобы быть полезной, необходима функция, которая объединяет и отображает предоставленные данные:
textscale = function(datum){ return qscale( logscale(datum.shu) ) }
Текстовая шкала возьмет объект перца и вернет слово, соответствующее его остроте. Для проверки результатов карта может быть использована:
data.map(textscale) // ["medium", "hot", "burning", "scorching", "hellfire", "hellfire"]
Линейные шкалы
В некоторых местах используется несколько значков, отображающих, насколько что-то горячо, например. от 0 до 4 чили. Для этого можно использовать Линейную шкалу:
linearscale = d3.scale.linear() .domain([0,1]) .range([0,4])
Эта шкала принимает число от 0 до 1 и возвращает число от 0 до 4 на линейной линии, например. linearscale(.5) возвращает 2. Однако она может возвращать нецелые числа, поэтому при создании функции отображения она должна округлять выходные данные.
chiliscale = function(datum){ return Math.round( linearscale( logscale(datum.shu) ) ) } data.map(chiliscale) // [1, 2, 3, 3, 4, 4]
Цветовые шкалы
Еще один способ визуализировать остроту перца — использовать цвет. Одной из лучших особенностей D3 является то, что он позволяет использовать шестнадцатеричные цвета в диапазонах функций масштабирования. Вот как вы можете использовать линейную шкалу для определения цвета:
colorscale = d3.scale.linear() .domain([0,1]) .range(['#FFF', '#933'])
Эта шкала принимает число от 0 до 1 и возвращает цвет от белого до красноватого. Опять же, необходима простая функция отображения:
burnscale = function(datum){ return colorscale( logscale(datum.shu) ) } data.map(burnscale) // ["#debdbd", "#c78f8f", "#bd7b7b", "#b16464", "#a34848", "#993333"]
Добавление визуальных элементов
Используя инструменты, которые я обсуждал ранее, давайте создадим простую визуализацию для набора данных о перцах.
Сначала давайте создадим несколько div для наших перцев:
peppers = d3.select('.peppers').selectAll('div') pepperssdata = peppers.data(data) .enter().append('div').attr('class','pepper')
Примечание. Я добавил класс перец для некоторого стиля
Используя текстовую функцию, текст внутри div может быть установлен на имя перца:
pepperssdata.text( function(datum){ return datum.name } )
Добавляется div с классом how-spicy с текстом, назначенным функцией textscale:
pepperssdata.append('div').attr('class','how-spicy').text( function(datum){ return 'is ' + textscale(datum) } )
Цвет фона задается функцией Burnscale:
pepperssdata.style('background-color', burnscale)
Это самый сложный кусок кода, но он не содержит ничего такого, чего раньше не видели:
pepperssdata.append('div').attr('class','fire').selectAll('i') .data( function(datum){ return new Array(chiliscale(datum)) } ) .enter().append('i').attr('class','fa fa-fire')
Сначала добавляется div с классом fire, затем выбираются все элементы i (пока их нет). Затем, передав в данные функцию, которая создает пустой массив длиной в хилискаль, для каждого перца создается новый набор данных. Наконец, он добавляет элемент i с классами значков для каждой части данных в пустом массиве.
Примечание. К сожалению, в Font Awesome нет значка чили (см. здесь)
Добавьте немного CSS и:
http://bl.ocks.org/grahamjenson/raw/9950335/
Просмотреть код здесь
Это не самая красивая, или очень полезная, или самая интересная визуализация в мире. Тем не менее, это хорошее начало для изучения D3.
Вывод
D3 — мощный инструмент, и этот пост лишь немного коснулся поверхности. Если вы хотите изучить D3, я рекомендую найти интересующие вас данные, а затем сделать для них небольшую визуализацию. D3 определенно является инструментом, который вы изучаете, используя его, так что идите и используйте его.
Читать далее
Время от времени я захожу в блоки и смотрю, что строит Майк Босток (создатель D3). Вы можете получить несколько удивительных примеров D3 оттуда.
Визуальное отображение количественной информации — Эдвард Тафте
Начало работы с D3 — Майк Дьюар