Объединение данных — еще одна важная концепция в D3.js. Он работает вместе с выборками и позволяет нам манипулировать HTML-документом относительно нашего набора данных (ряд числовых значений). По умолчанию D3.js дает набору данных самый высокий приоритет в своих методах, и каждый элемент в наборе данных соответствует элементу HTML. В этой главе подробно описываются объединения данных.
Что такое объединение данных?
Объединение данных позволяет нам вводить, изменять и удалять элементы (элемент HTML, а также встроенные элементы SVG) на основе набора данных в существующем документе HTML. По умолчанию каждый элемент данных в наборе данных соответствует элементу (графическому) в документе.
При изменении набора данных соответствующим элементом также можно легко управлять. Объединение данных создает тесную связь между нашими данными и графическими элементами документа. Объединение данных делает манипулирование элементами на основе набора данных очень простым и легким процессом.
Как работает объединение данных?
Основная цель объединения данных — сопоставить элементы существующего документа с заданным набором данных. Он создает виртуальное представление документа относительно заданного набора данных и предоставляет методы для работы с виртуальным представлением. Давайте рассмотрим простой набор данных, как показано ниже.
[10, 20, 30, 25, 15]
Набор данных состоит из пяти элементов, поэтому его можно сопоставить с пятью элементами документа. Давайте сопоставим его с элементом li следующего документа, используя метод selectAll () селектора и метод data () объединения данных.
HTML
<ul id = "list"> <li><li> <li></li> </ul>
Код D3.js
d3.select("#list").selectAll("li").data([10, 20, 30, 25, 15]);
Теперь в документе есть пять виртуальных элементов. Первые два виртуальных элемента — это два элемента li, определенные в документе, как показано ниже.
1. li - 10 2. li - 20
Мы можем использовать все методы изменения элементов селектора, такие как attr (), style (), text () и т. Д., Для первых двух li, как показано ниже.
d3.select("#list").selectAll("li")
   .data([10, 20, 30, 25, 15])
   .text(function(d) { return d; });
Функция в методе text () используется для получения данных, сопоставленных элементам li . Здесь d представляет 10 для первого элемента li и 20 для второго элемента li .
Следующие три элемента могут быть сопоставлены с любыми элементами, и это можно сделать с помощью метода enter () объединения данных и метода append () селектора. Метод enter () предоставляет доступ к остальным данным (которые не сопоставлены с существующими элементами), а метод append () используется для создания нового элемента из соответствующих данных. Давайте создадим li и для остальных элементов данных. Карта данных выглядит следующим образом —
3. li - 30 4. li - 25 5. li - 15
Код для создания нового элемента li выглядит следующим образом:
d3.select("#list").selectAll("li")
   .data([10, 20, 30, 25, 15])
   .text(function(d) { return "This is pre-existing element and the value is " + d; })
   .enter()
   .append("li")
   .text(function(d) 
      { return "This is dynamically created element and the value is " + d; });
Присоединение к данным предоставляет другой метод, называемый методом exit (), для обработки элементов данных, динамически удаляемых из набора данных, как показано ниже.
d3.selectAll("li")
   .data([10, 20, 30, 15])
   .exit()
   .remove()
Здесь мы удалили четвертый элемент из набора данных и соответствующий ему li, используя методы exit () и remove ().
Полный код выглядит следующим образом —
<!DOCTYPE html>
<html>
   <head>
      <script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script>
      <style>
         body { font-family: Arial; }
      </style>
   </head>
   <body>
      <ul id = "list">
         <li></li>
         <li></li>
      </ul>
        
      <input type = "button" name = "remove" value = "Remove fourth value" 
         onclick = "javascript:remove()" />
      
      <script>
         d3.select("#list").selectAll("li")
            .data([10, 20, 30, 25, 15])
            .text(function(d) 
               { return "This is pre-existing element and the value is " + d; })
            .enter()
            .append("li")
            .text(function(d) 
               { return "This is dynamically created element and the value is " + d; });
             
         function remove() {
            d3.selectAll("li")
            .data([10, 20, 30, 15])
            .exit()
            .remove()
         }
      </script>
   </body>
</html>
Результат приведенного выше кода будет следующим:
Методы объединения данных
Объединение данных предоставляет следующие четыре метода для работы с набором данных:
- точка привязки ()
- данные()
- войти()
- выход()
Давайте подробно рассмотрим каждый из этих методов.
Метод данных ()
Метод datum () используется для установки значения для одного элемента в документе HTML. Он используется после выбора элемента с помощью селекторов. Например, мы можем выбрать существующий элемент (тег p) с помощью метода select (), а затем установить данные с помощью метода datum (). После того, как данные установлены, мы можем либо изменить текст выбранного элемента, либо добавить новый элемент и назначить текст, используя данные, установленные методом datum ().
Создайте страницу «datajoin_datum.html» и добавьте следующий код:
<!DOCTYPE html>
<html>
   <head>
      <script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script>
   </head>
   <body>
      <p></p>
      <div></div>
      <script>
         d3.select("p")
         .datum(50)
         .text(function(d) { 
            return "Used existing paragraph element and the data " + d + " is assigned."; 
         });
         
         d3.select("div")
         .datum(100)
         .append("p")
         .text(function(d) { 
            return "Created new paragraph element and the data " + d + " is assigned."; 
         });
      </script>
   </body>
</html>
Вывод вышеприведенного кода будет следующим.
Метод data ()
Метод data () используется для назначения набора данных коллекции элементов в документе HTML. Он используется после выбора элементов HTML с помощью селекторов. В нашем примере списка мы использовали его для установки набора данных для селектора li .
d3.select("#list").selectAll("li")
   .data([10, 20, 30, 25, 15]);
Метод enter ()
Метод enter () выводит набор элементов данных, для которых ранее не было графического элемента. В нашем примере со списком мы использовали его для создания новых элементов li .
d3.select("#list").selectAll("li")
   .data([10, 20, 30, 25, 15])
   .text(function(d) { return "This is pre-existing element and the value is " + d; })
   .enter()
   .append("li")
   .text(function(d) { return "This is dynamically created element and the value is " + d; });
Метод exit ()
Метод exit () выводит набор графических элементов, для которых больше нет данных. В нашем примере со списком мы использовали его для динамического удаления одного из элементов li путем удаления элемента данных из набора данных.
function remove() {
   d3.selectAll("li")
      .data([10, 20, 30, 15])
      .exit()
      .remove()
}
Функция данных
В главе о манипулировании DOM мы узнали о различных методах манипулирования DOM в D3.js, таких как style (), text () и т. Д. Каждая из этих функций обычно принимает постоянное значение в качестве своего параметра. Тем не менее, в контексте объединения данных , он принимает анонимную функцию в качестве параметра. Эта анонимная функция принимает соответствующие данные и индекс набора данных, назначенного с помощью метода data (). Таким образом, эта анонимная функция будет вызываться для каждого из наших значений данных, связанных с DOM. Рассмотрим следующую функцию text ().
.text(function(d, i) {
   return d;
});
В рамках этой функции мы можем применять любую логику для манипулирования данными. Это анонимные функции, что означает, что с этой функцией не связано имя. Помимо параметров data (d) и index (i), мы можем получить доступ к текущему объекту, используя это ключевое слово, как показано ниже —
.text(function (d, i) {
   console.log(d); // the data element
   console.log(i); // the index element
   console.log(this); // the current DOM object
   return d;
});
Рассмотрим следующий пример.
<!DOCTYPE html>
<html>
   <head>
      <script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script>
      <style>
         body { font-family: Arial; }
      </style>
   </head>
   <body>
      <p></p>
      <p></p>
      <p></p>
      <script>
         var data = [1, 2, 3];
         var paragraph = d3.select("body")
         .selectAll("p")
         .data(data)
         .text(function (d, i) {
            console.log("d: " + d);
            console.log("i: " + i);
            console.log("this: " + this);
            return "The index is " + i + " and the data is " + d;
         });
      </script>
   </body>
</html>
Приведенный выше скрипт сгенерирует следующий результат —
В приведенном выше примере параметр «d» дает вам элемент данных, «i» — индекс данных в массиве, а «this» — это ссылка на текущий элемент DOM. В данном случае это элемент абзаца. Обратите внимание, что мы вызвали функцию .data (data) выше. Функция data () предоставляет данные для выбранных элементов, в нашем случае это массив данных.