Introduction

Following the Learn D3: Shapes , it is only an English translation. The part of the code that can be modified is replaced with a static picture. If you want to interact in real time, please read the original text.

text

Unlike graphics drawn on paper, computer graphics do not have to be static; like Frankenstein's monsters, they can come to life through animation! ✨

91-1

The line chart above is shown step by step. This dispensable effect should be used with caution, because it will attract attention, but it at least strengthens x represent time, and brings a little suspense to an otherwise boring chart.

The code here is similar to the axis rendering we saw earlier: we select an SVG path element, call a function ( reveal ) to apply the transformation, and finally embed the element in the HTML template text.

91-2

Before we get into the technical details, let's take a step back and think about animation more fully.

The animation is not a single graphic, but a series graphic that changes over time. The sequence can be expressed as a unit (or function) that returns a graph at a given time t For simplicity, we usually use regular time, where t =0 is the beginning of the animation, and t =1 is the end.

91-3

We can theoretically unit returns the given time T of any graphics, but the time T pattern generally time T + [epsilon] similar pattern. This similarity between frames helps the viewer follow along (in the above, only the stroke-dasharray attribute is animated; the rest of the graph remains unchanged.) Therefore, continuous animation is usually defined by discrete key frames, and the intermediate frames are interpolated Or complement generate.

Take a look at the properties of stroke-dasharray It is two comma-separated numbers: the first is the length of the dash, and the second is the length of the gap between the dashes. If the length of the dashed line is zero, the line will not be visible; if the length of the dashed line is as long as the line, the line will not be interrupted. By adjusting the length of the dotted line and making the gap at least as long as the straight line, we can control how many straight lines are drawn. We only need two key frames: zero dash length and line dash length.

To aid animation (and other purposes), D3 provides the interpolator . The most common one is d3.interpolate , which accepts numbers, colors, numeric strings, and even arrays and objects. Given start and value value, d3.interpolate returns a function, this function takes a time 0 ≤ t ≤ 1 and returns the corresponding intermediate value.

91-4

When defining the transition, you can specify the interpolator explicitly (as described above, use transition.attrTween ) or let D3 choose (use transition.attr or transition.style ). Explicit specification allows the use of more advanced interpolation methods, such as scaling , gamma-corrected RGB blending , and even shape blending .

91-5

However, animation is not just interpolation: it is also timing. We need to redraw 60 times per second, and calculate the normalized time t based on the expected start time and duration of real-time and animation.

So far, we have seen two timing methods.

The first type depends on the D3 transformation, creates the initial figure, and then starts the transformation to modify it (insert the stroke-dasharray array).

The second kind of data flow relies on Observable t changes, and relies on a scrubber for timing. This is less efficient than the previous method because the graphics are created from scratch every frame, but it is easier to write.

Observable has another powerful tool for controlling animation: generator . When the generator unit generates a value, its execution will pause until the next animation frame, up to 60 times per second. The generated value can be as simple as an integer, or it can be an incrementally updated SVG element!

91-6
91-7

Given that Observable provides various methods for animation, which one should I use? It depends on the situation!

If the graphics are simple enough, you can recreate each frame from scratch, or if you actually don’t need animation transitions, write the graphics declaratively. In other words, do nothing! Thanks to Observable's data flow, "static" graphics can respond, interact or animate without changing the code.

On the other hand, for more complex dynamic graphics whose performance requires efficient incremental updates, use transforms or generators.

You can also combine various methods. The figure below is initially static, but given the x domain a converted chart method; when the single-selection value changes, another unit will call this method. (This code is written using the d3 selector instead of HTML template text, but the graphic structure is the same as the previous example, so try to infer the meaning of the code by comparison.)

91-8
91-9

By providing one or more update methods, the chart can selectively animate the transition of specific value changes. If there are any other changes, the chart will return to a reactive state and re-draw from the beginning.

(If you want to know: you can define the update in a separate unit instead of exposing it as a method. However, this is not recommended because editing the updated code will not redraw the diagram from the beginning, which may cause uncertainty The behavior. 😱 By defining the update in the chart unit, it can access the local variables that persist during the update process.)

This example demonstrates another convenient function of the D3 axis: by switching to transition.call instead of selection .call, x axis are now dynamic rather than instantaneous and synchronized with the transition path!

The above animation only involves one element: the lines of the chart. What if you want to animate multiple elements? What if the element set changes over time, and new elements enter the old elements and exit? Read on!

Next

appendix

If you are interested in designing effective animations, I strongly recommend reading Heer and Robertson's 2007 paper Animated Transitions in Statistical Data Graphics .

91-10
91-11

Attached

According to the source code, the platform dependency is removed, and the main code is extracted. The following examples are shown:

Reference


XXHolic
363 声望1.1k 粉丝

[链接]