As mentioned earlier, SVG has been able to easily control its DOM objects by using JavaScript scripting language since its birth. Of course, there are many control methods, including direct control of SVG objects, such as using native JS, and JS class libraries that help you encapsulate a single interface for direct control, such as Rapha ë L. However, as I mentioned in the first article, the important reason why D3 stands out as an intermediate class library is that it breaks through the direct control of the presentation layer mechanism of other class libraries, the adoption of a novel data-driven mechanism (2011) in the web graphics processing field has achieved great success.
Data-driven history
Data-driven programming is not a new concept. In the old book "Unix programming art", when the author introduces the Unix design principles, one of them is"Representation principle: Fold knowledge into data to make the logic simple and robust". Its core starting point is that humans are better at processing data than procedural logic. Data is easier to control than program logic, so we should try our best to transfer the complexity of design from program code to Data. This principle was proven as early as the software crisis in 1970s: Any code persistently focused on logical implementation is ultimately difficult to maintain, and logical changes are precipitated into the programs in the dataset, the time test is passed. The MVC Architecture has been popular in the Web development field for more than 20 years. Its core is to separate data, performance, and operations to reduce program complexity. The Java Community has been discussing the field of programming for many years. The principle of data-driven is also indispensable.
However, for the Web Front-end, especially in the graphic image processing field, people have been focusing on graphic rendering APIs for a long time to design such as VAR Circle = paper. image Rendering interfaces such as circle (50, 40, 10. The use of graphic elements remains in the State directly controlled by the application for a long time. Of course, if the interaction logic is small, This is not impossible even if the image is slightly complicated. However, when creating a data visualization project with complex interaction logic, the Code complexity of this method will increase with the scale of the interaction logic, and bring about many unexpected program conflicts-all of which are the same reason as the web development field before MVC or the software crisis in 1970s. People of insight had long been surprised by this problem. As a result, the basic rendering technology for web graphics processing was gradually improved. In 2011, d3js was born, and quickly set off a tornado in the field of data visualization and web graphics rendering.
Understanding of D3 Data Conversion
In the original article on the official website, it focuses on transformation rather than performance (transformation, not representation ). D3 is not a new class library for graph rendering. Unlike processing, Rapha ë L, or protovis class libraries, D3 does not focus on the encapsulation of graphic presentation interfaces, but uses standard Web HTML, SVG, and CSS to process the presentation layer. This means that if the browser supports the new graphic rendering feature one day, you can use it immediately without any special modifications at the code layer. D3 focuses on the binding between data and graphics. Data is generally an object in JSON format, or XML format. images not only include SVG objects, HTML objects, or graphical objects supported by other browsers. In short, you can use D3 to create an HTML table or an SVG column chart for the same group of data.
So how does D3 bind data to a DOM node?
The first step is to select a DOM object to build a selection area ). The method for selecting a DOM object is exactly the same as that for jquery. They all use a syntax similar to the CSS selector. For example, select a group of Div nodes with the CSS class name my-node and set the text to White:
1 |
D3.selectall ("Div. My-node"). style ("color", "White "); |
Step 2: bind the dataset to the DOM object in the selection area. D3 provides a very useful data function for Data Object serialization and possible preprocessing (see the API for details). It also returns the collection elements one by one for further processing. For example:
123 |
D3.selectall ("p "). data ([4, 8, 15, 16, 23, 42]). style ("font-size", function (d) {return D + "PX ";}); |
In this example, each P tag in the selection area is bound to a number in the data in order (we assume that the number of P tags is equal to the length of the array ). In this way, the bound data can be retrieved in the callback function to dynamically calculate the text size in each P tag. Programmers familiar with jquery or prototype class libraries can easily find common similarities between them, especially through callback functions to perform operations on each element in a collection.
The above example seems simple and easy to understand. However, a major problem in shadow is that the dataset changes frequently. Once the dataset changes, each data object in the dataset does not match the DOM object in the selection area, so what should we do with extra data or extra DOM objects?
Therefore, D3 provides a mechanism for binding data sets (data) and selection of three behaviors: Enter, update, and exit. To understand this mechanism, it is better to look at the figure to see the example, or else it is not easy to understand. Here is a simple D3 tutorial to download. The following figure shows the D3 Data Binding Mechanism extracted from this tutorial. Its explanation is as follows:
- Objects in the dataset (data) and selection should be bound one by one. Once the bound data changes, it is reflected to the corresponding DOM object, which is called the update process.
- If the number of data exceeds the number of nodes, some data cannot be stored, and the enter process is generated.
- Otherwise, if the data is obtained from the node and the node is idle, the exit process occurs.
You can customize the update, enter, and exit processes. For example, you can use ajax to obtain data. When initializing a graph, you can customize the enter process to display the image gradient. When you click a graph object, change the data value corresponding to the graphic object, and then modify the graphic object at the same time through the update process. When you want to delete a graphic object, the exit process is triggered to achieve the effect of fading. Therefore, we can see that the code of a large number of D3 examples on GitHub is similar to the following: Update, enter, exit...
1234567891011 |
// Update... VaR P = d3.select ("body "). selectall ("p "). data ([4, 8, 15, 16, 23, 42]). text (string); // Enter... P. Enter (). append ("p"). Text (string); // exit... P. Exit (). Remove (); |
Let's look at the specific code.I have created an online example based on the case in the above-mentioned Tutorial: http://runjs.cn/detail/8enw0npq. here we can see the Code directly, so I will not go into details here. Let's take a look at how the data binding mechanism of D3 works, including entering, update, and exit.
<IFRAME Style = "width: 100%; Height: 300px" src = "http://sandbox.runjs.cn/show/8enw0npq” allowfullscreen =" allowfullscreen "frameborder =" 0 "> </iframe>
Reflection on Learning Process
As far as my interview experience is concerned, most front-end programmers in China are learning JavaScript from jquery. After reading the above Code, everyone will think that it is very similar to jquery. The style of chained programming and callback functions are easy to understand.
But why does D3 have a relatively high learning curve? This is because we generally only read one or two D3 demos on GitHub. Without specific explanations, it is difficult for common programmers to thoroughly understand the data (and the container containing data) of D3) as the core idea. At least I didn't understand why I had to update, enter, and exit all at once. This is because of conventional thinking. For image operations, we focus on the image itself first. For example, a common jquery programmer has a need: After clicking a graph, the figure is doubled and the data is updated to twice the original one. This is the general idea of the entire process: first select the graphic object, change the graphics, and then update the data (or first update the data and then change the graphics ). Although this logic is simple, it will undoubtedly isolate data and graphics. If this graphic is bound to many other interactions and the dataset is complex, you will often encounter maintenance difficulties that ignore the need of your head. When D3 processes the interaction logic, it usually finds data through the graphic object, changes the data, and then updates the graphic object. It seems that the image itself is returned only after a circle is switched, which is more difficult than directly operating the image. But here is the essence of D3. Only by accumulating complex logic on the data can we maintain code clarity during complex interactions.
Of course, if you just want to draw a few pictures and there is not much complicated interaction, I think D3 has no advantages. There are many simple charts implemented using the jquery chart plug-in, which do not have much code than D3 to implement similar cases, and can also receive good results. So I thought that the main application of D3 was in the development of complex interactive visualization projects. In addition, once you understand the data-driven model of D3, the idea will be much broader. Comparing it with frameworks such as backbone, angularjs, and Ember. JS, it is true that the so-called front-end development revolution begins with data-driven.
D3 visualization 02: understanding the true meaning of D3 data driver