📜 ⬆️ ⬇️

Introduction to D3


D3.js (or simply D3) is a JavaScript library for processing and visualizing data. It provides handy utilities for handling and loading data arrays and creating DOM elements. This note describes the work with the main methods of the library, it is suitable for learning the basics of the library and immersing it in its logic and capabilities.

To understand the article useful knowledge of JS, HTML and CSS.


Fluent interface (fluent interface)


D3 implements an approach called fluent interface. When reading the code, it looks like a chain of methods. Each method is called on the object that returned the previous method. To make the code easy to read, each call is located on a separate line:

d3.select('body') //    body .append('svg') //   body svg- .append('text') //   svg-  text .text('Click somewhere, please...') //     text .attr('x', 50) //    text .attr('y', 50) .style("fill","firebrick") //    

This example is on jsfiddle.net
')

Sample


In D3, as in other JS libraries that work with DOM elements, interaction with a document begins with searching for elements in a document and creating a selection — a wrapper for a set of elements. It gives access to library methods for modifying selected items.

Selection (selection) in D3 is created using the methods d3.select () and d3.selectAll () . To create a sample, D3 uses querySelector / querySelectorAll or Sizzle if it is connected to a page (for example, with jQuery).
 d3.select('span') //   span   d3.selectAll('span') //   span   

The resulting selection is used to work with elements and to create a selection of descendants (subselection).

 <span> </span> <p> <span> </span> <span></span> <span></span> <span></span> </p> <p> </p> 

 d3.select('span') //   span   .style('color', 'darkgreen') //   d3.selectAll('p') //    .selectAll('span') //   span   . .style('color', 'goldenrod') //   d3.select('p') //      .select('span') //   span    .style('color', 'firebrick') //   

This example is on jsfiddle.net

Always remember which sample you're currently working with. Common mistakes when working with D3: call on a descendant element instead of a parent and attempt to change the properties of a nonexistent (deleted or not yet created) element.

The example already uses operations on elements ( selection.style (name [, value]) ), then we will consider them in more detail.

Calculation of values ​​and functors


To work with the DOM, the D3 uses a similar API for all calls. Let's analyze it on the example of a popular task: adding or removing a class from an element. For this we need some sampling methods:


 var pressed = false var button = d3.select('button') //   .on('click', function (data, index) { //     button.classed('pressed', pressed = !pressed) //         }) 

This example is on jsfiddle.net

Note that we use the selection stored in the button variable: calls on (as well as classed, attr, style, property, html, text) return the selection on which they are called, which is typical for fluid interfaces.

D3 handles transmitted values ​​in a similar way. If you see in the [value] documentation, then most likely this is about:


It is important to remember about the last nuance if you are building a call chain (such a getter should usually be the last element of the chain).

It is important to understand that values ​​or functions are used once for each element in the sample, after which D3 “forgets” about them. In other words, changes in the data set or events in the document will not force D3 to “re-compute” the value, so this behavior must be set on our own, as we did with classed above.

Pay attention to the function arguments (data and index). They have a special meaning: index is the number of the element in the sample, and data is the data element specified for it. The presence of these parameters in each function called on the sample is one of the most important contracts in D3. This allows you to write a concise code that calculates the state of the properties of the elements depending on the data.

Typical work with sampling


Consider the popular methods on a more complex example, demonstrating how to work with DOM nodes of a document through sampling:
 var svg = d3.select('body').append('svg') svg .append('text') .text('click somewhere') .attr('x', 50) .attr('y', 50) var events = [] svg.on('click', function () { events.push(d3.event) if (events.length > 5) events.shift() var circles = svg.selectAll('circle') .data(events, function (e) { return e.timeStamp }) .attr('fill', 'gray') circles .enter() .append('circle') .attr('cx', function (d) { return dx || d.pageX }) .attr('cy', function (d) { return dy || d.pageY }) .attr('fill', 'red') .attr('r', 10) circles .exit() .remove() }) 

This example is on jsfiddle.net



Related sets


In the example, special attention should be paid to the data () method. Unlike other methods, it returns a modified sample that stores, in addition to a list of elements, the correspondence of these elements to elements. In the translation of the article Thinking with Joins, we tell in detail about the methods of enter () and exit () that this sample has and the possibilities that they give.

Animation and customization


It is easy to animate changing the properties of an element in D3; you need to call the selection.transition () method. This method returns a sample that gradually changes the current values ​​to new ones, creating an animated effect. The duration of the animation is set by the transition.duration () method.

Add an animation when adding and removing items to the previous example:

 var svg = d3.select('body').append('svg') svg .append('text') .text('click here') .attr('x', 50) .attr('y', 50) var events = [] svg.on('click', function () { events.push(d3.event) if (events.length > 5) events.shift() var circles = svg.selectAll('circle') .data(events, function (e) { return e.timeStamp }) .attr('fill', 'gray') circles .enter() .append('circle') .attr('cx', function (d) { return dx || d.pageX }) .attr('cy', function (d) { return dy || d.pageY }) .attr('fill', 'red') .attr('r', 0) //   .transition() .duration(1000) //        .attr('r', 10) //   circles .exit() .transition() .attr('r', 0) .remove() }) 

This example is on jsfiddle.net

In this article, I talked about the D3 sampling capabilities. I plan to devote the following notes to utilities for processing and loading data, drawing sets of SVG elements and creating interactive visualization elements.

I teach D3 on the “Data Visualization” course. If you want to master this tool and start applying it in your work, come to us. The closest course will take place in Moscow this weekend, recording and feedback from participants of the January course: http://brainwashing.pro/dataviz .

Source: https://habr.com/ru/post/217905/


All Articles