First acquaintance with D3.js: Create exclusive visualization

I. Introduction

With the increasing demand for custom visualization nowadays, highly encapsulated visualization frameworks such as Highcharts and echarts can no longer meet the various highly customizable visualization needs of users. At this time, D3's unlimited customization capabilities stand out.

If you want to complete visualization through D3, in addition to learning D3's own API, the concepts and standards of HTML, SVG, CSS, Javascript and data visualization on the web standards need to be learned. This undoubtedly brings a higher learning threshold, but it is also worth it, because after mastering D3, we can almost achieve any 2D visualization needs.

This article analyzes the core modules of D3 and practices specific cases to help beginners learn to understand the drawing ideas of D3.

Second, what is D3

The full name of D3 is Data-Driven Documents, which is a JavaScript library for manipulating documents based on data. Its core is to use drawing instructions to convert data, create new drawable data based on source data, and generate SVG Path and create data visualization elements (such as axes) in the DOM through data and methods.

Compared with the out-of-the-box visualization frameworks such as Echats, D3 is closer to the bottom layer. It can directly control native SVG elements and does not directly provide any kind of ready-made visualization charts. All charts need us in its library Choose the appropriate method to build it, which also greatly improves its visual customization capabilities. And D3 does not introduce new graphic elements. It follows web standards (HTML, CSS, SVG and Canvas) to display data, so it can run independently in modern browsers without relying on other frameworks.

3. D3 core module

After the V4 version, the D3 API has now been split into modules, and we can load them on demand according to our own visualization needs. The sense D3 API pan module can be divided into the following categories: the DOM operations, data processing, data analysis, conversion, geographical paths and behavior .

First acquaintance with D3.js: Create exclusive visualization

Here we mainly analyze the D3-selection and D3-scale modules:

3.1  D3-selection

D3-selection (selection set) is the core module of D3js, mainly used to select elements, set attributes, data binding, event binding and other operations.

Select element: D3-selection provides two methods to get the target element, d3.select(): returns the first node of the target element, d3.selectAll(): returns a collection of target elements, which looks a bit similar to native API at first glance QuerySelector and querySelectorAll, but d3.select returns a selection object, and querySelector returns a NodeList array. From the information printed on the console, you can see that the groups under selection store the collection of all selected elements, and the parents store the parent nodes of all selected elements.

First acquaintance with D3.js: Create exclusive visualization

Setting properties or binding events: We don't need to care about the structure of groups. When calling selection.attr or selection.style, all the child elements of all the groups in the selection will be called. The only effect of the existence of the group is: When we pass the parameter as a function, for example, selection.attr('attrName' , function(data, i)) or selection.on('click', function(data, i)), in the passed function(data, i), the second parameter i is the index of the element in the group instead of The index in the entire selection.

Data binding: Actually assign values ​​to the __data__ attribute of the selected DOM element. Here are three ways to bind data:

(1) Call selection.datum for each individual DOM element: d3.select('body').datum(20) is equivalent to document.body.__data__ = 20

(2) Inherit data from the parent node, such as append, insert, select, the child node will actively inherit the data of the parent node:

First acquaintance with D3.js: Create exclusive visualization

(3) Call the selection.data() method to support the input of data with basic data types, and also support the input of a function (parentNode, groupIndex) to map the data according to the node index. The data() method is introduced in d3. Important join ideas: 

Bind data to DOM elements. In D3, the corresponding relationship is found by comparing the key values ​​of data and DOM. If we do not set the key value separately, then the default is set according to the subscript index of data, but when the order of the data is changed, the default subscript key value becomes unreliable, then we can use selection.data(data , keyFunction) The second parameter keyFunction, returns a corresponding key value according to the current data. As can be seen from the following illustration, whether there is one or multiple groups (each group is independent), as long as we ensure that the key value in any group is unique, once the data changes, it will be reflected to the corresponding DOM elements (the update process):

First acquaintance with D3.js: Create exclusive visualization

3.2 Join thought

The above mentioned are data binding when the number of data data and DOM elements are the same. If the number of data data and DOM elements is not the same, let's take a look at how D3 performs data binding: now it is finally possible Let’s introduce the core Join idea of ​​the D3-selecion module. In simple terms, this idea is "not to tell D3 how to create elements, but to tell D3 that the selecion collection obtained by .selectAll() should be bound to .data(data) How to correspond to the data in one to one".  

First acquaintance with D3.js: Create exclusive visualization

As can be seen from the figure above, when d3.data(data) is bound, a selection set of three states will be generated:

  • Update: A   collection of DOM elements that have been bound to data

  • Enter: data data did not find the corresponding DOM element set (that is, the missing DOM element)

  • Exit: A  collection of DOM elements that are not data-bound (extra DOM elements)

Understanding in the way of Join means that what we have to do is to declare the relationship between the DOM collection and the data collection, and describe this relationship by processing the three different states of the collection enter, update, and exit. This method can greatly simplify our operations on DOM elements. We don't need to use if and for loops to make complex logical judgments to get the set of elements we need. And when processing dynamic data, you can easily display real-time data and add smooth dynamic interaction effects by processing these three states.

3. 3 D3-scale

D3-scale (proportion scale) provides many different types of scales. Often used with D3-axis coordinate axis module.

D3-scale provides a variety of continuous and non-continuous scales, which can be divided into three categories:

  • Continuous input (domain) and continuous output (range)

  • Continuous input (domain) and discrete output (range)

  • Discrete input (domain) and discrete output (range)

Some commonly used scales:

(1) d3-scaleLinear linear scale (continuous input and continuous output)

It can be seen that calling d3.scaleLinear() can generate a linear scale, domain() is the input domain, and range() is the output domain, which is equivalent to mapping the data set in domain to the data set of range.

Usage example:

First acquaintance with D3.js: Create exclusive visualization

Mapping relations:

First acquaintance with D3.js: Create exclusive visualization

(2) d3-scaleTime time scale (continuous input and continuous output)

The time scale is similar to the linear scale, except that the input field becomes a time axis. Normally we use the scale is a positive sequence, but D3 also provides invert() and invertExtent() methods, we can get the value of the corresponding input field through the specific value in the output field.

Usage example:

First acquaintance with D3.js: Create exclusive visualization

(3) d3.scaleQuantize quantization scale (continuous input and discrete output)

The quantization scale divides the continuous input domain into uniform segments according to the output domain, so its output domain is discrete.

Usage example:

First acquaintance with D3.js: Create exclusive visualization

Mapping relations:

First acquaintance with D3.js: Create exclusive visualization

(4) d3. scaleThreshold threshold scale (continuous input and discrete output)

The threshold scale can specify the segmentation threshold for a group of continuous data. The default domain of the threshold scale: [0.5] and the default range: [0, 1], so the default d3.scaleThreshold() is equivalent to the Math.round function. If the threshold scale input field is N, the output field must be N + 1, otherwise the scale may return undefined for some values, or the extra value of the output field will be ignored.

Usage example:

First acquaintance with D3.js: Create exclusive visualization

There are three mapping relationships:

a. When the data of domain and range is N: N+1   

First acquaintance with D3.js: Create exclusive visualization

b. When the data of domain and range is N: N + greater than 1         

First acquaintance with D3.js: Create exclusive visualization

c. When the data of domain and range is N + greater than 0: N 

First acquaintance with D3.js: Create exclusive visualization

(5) d3.scaleOrdinal ordinal scale (discrete input and discrete output)

Unlike continuous scales such as scaleLinear, the output and input fields of ordinal scales are both discrete.

Usage example:

First acquaintance with D3.js: Create exclusive visualization

There are three mapping relationships:

a. When the data of domain and range are one-to-one correspondence     

First acquaintance with D3.js: Create exclusive visualization

b. When domain is less than range data

First acquaintance with D3.js: Create exclusive visualization

c. When domain is more than range data

First acquaintance with D3.js: Create exclusive visualization

Four, actual combat

Through the above learning, you should have a certain understanding of how d3 manipulates the DOM and the data mapping of the coordinate axes to the corresponding visual performance. Let's actually use these two modules to realize our common visual chart: histogram.

(1) First add an SVG element.

First acquaintance with D3.js: Create exclusive visualization

(2) According to the d3.scale module and d3.axis module we mentioned above to draw the coordinate axis, d3.scaleBand() is called the ordinal scale, similar to the d3.scaleOrdinal() ordinal scale we said, but it supports continuous values Type of output domain, discrete input domain can divide the continuous range into uniform segments. Here is one more detail. When drawing the grid, we did not add additional line elements to achieve it. Instead, we  set the axis ticks through the axis.ticks() method of the d3.axis axis module  , and through tickSIze( ) The length of the tick mark is set to simulate a grid line equal to the width of the chart, and the Y-axis tick value can be formatted and converted by tickFormat().

First acquaintance with D3.js: Create exclusive visualization

(3) After the coordinate axis is drawn, we use data binding to draw the corresponding rect element.

First acquaintance with D3.js: Create exclusive visualization

(4) At this time, the histogram has been basically drawn. We will enrich the content display and add prompt information such as tags and titles.

First acquaintance with D3.js: Create exclusive visualization

(5) Finally, we realize the information floating layer interaction of tooltips by binding monitoring events to the pillars.

First acquaintance with D3.js: Create exclusive visualization

Five, summary

Through the learning of modules such as d3.selection, d3.scale and d3.axis, we can already draw commonly used histograms and other charts, and we can also draw more complex visualization effects through other modules provided by d3, such as through d3 -hierarchy (hierarchy module) realizes hierarchical tree graph visualization, d3-geo (geographic projection) realizes map data visualization, etc. The content explained in this article is only the tip of the iceberg of the D3 library. So when we have mastered D3, it is not technology but imagination that restricts our visualization.

Author: Ray

Guess you like

Origin blog.51cto.com/14291117/2588540