D3 ловко использует технику, которая называется цепочками методов, которую вы можете легко узнать, если пользовались библиотекой jQuery. Методы вызываются последовательно один за другим в одной строке кода, выполняя несколько действий - это называется цепочкой методов. Эта техника может быть очень быстрой и удобной, но необходимо понимать, как это работает, чтобы потом часами не сидеть за отладкой кода.
Так, функции и методы это лишь два разных слова, обозначающих одно и тоже: кусок кода, который может принимать аргументы на вход, выполняет некоторые действия, после чего возвращает некоторые данные тому, кто вызвал метод.
Давайте заново посмотрим на нашу первую строку кода, использующую D3(Демо страница тут):
d3.select("body").append("p").text("New paragraph!");
Это может выглядеть как большая каша, в особенности, если вы новичок в программировании. Итак, первым делом нужно усвоить, что JavaScript, также как и HTML, не волнуют пробелы и переходы на новую строку, так что вы можете написать каждый метод на отдельной строке для лучшей наглядности:
d3.select("body") .append("p") .text("New paragraph!");
Каждый придерживается своего стиля оформления кода. Использование отступов, переходов на новую строку или пробелов(либо табов) работает на вас, помогая лучше воспринимать код.
Давайте разберем каждый кусок кода:
d3 - ссылается на D3 объект, из которого мы имеем доступ к методам D3.
.select("body") - дает методу select() CSS-селектор на вход, а метод, в свою очередь, возвращает ссылку на первый элемент в DOM'e, который подходит под описание селектора(необходимо использовать метод selectAll() для получения группы объектов). В данном случае, нам нужен элемент body, поэтому ссылка на body используется следующим методом в нашей цепочке.
.append("p") - метод append() создает любой DOM-элемент, указанный вами и добавляет его в конец(внутрь) выборки. В нашем случае мы хотим создать новый параграф p внутри тега body. Мы указали p как аргумент функции, которая вызывается у элемента body, который мы выбрали вызовом предыдущего метода select(). В конце-концов, append() возвращает ссылку на новый элемент, который только что был создан.
.text("New paragraph!") - метод text() в качестве аргумента принимает строку и вставляет ее между открывающимся и закрывающимся тегами выборки. Так как предыдущий метод возвращает ссылку на наш новый тег p, этот код вставляет переданный текст между тегами <p> и </p>.(Если между тегами будет существовать текст, то он будет перезаписан).
; - самый важный символ, который указывает на окончание этой строки кода.
Многие, но не все D3 методы возвращают выборку(хотя, по правде говоря, ссылку на эту выборку), что открывает возможность создавать цепочки методов. Обычно, метод возвращает ссылку на элемент, у которого этот метод был вызван, но не всегда.
Поэтому необходимо запомнить: когда пользуешься цепочками методов - порядок следования методов важен. Следующий вызываемый метод должен соответствовать методу объекта, возвращаемого текущим методом. Если вы соблюдаете порядок, действия методов не приведут к ожидаемому результату.
Если вы не знаете, что нужно передавать функции на вход, и что получится на выходе - смело пользуйтесь документацией, она ваш лучший друг. В документации есть информация по каждому методу, включая информацию, возвращает ли метод какую-нибудь выборку.
Наш простой код может быть переписан без использования цепочек методов:
var body = d3.select("body"); var p = body.append("p"); p.text("New paragraph!");
Фу, какое безобразие! Такой синтаксис действительно нужен, если, например, вы вызываете так много функций, что просто не имеет смысла их вызывать одна за другой. Или просто потому, что организовав таким образом код, он стал более понятен вам.