-
Notifications
You must be signed in to change notification settings - Fork 1
/
Three Little Circles.html
255 lines (175 loc) · 28.5 KB
/
Three Little Circles.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
<!DOCTYPE html>
<!-- saved from url=(0035)https://bost.ocks.org/mike/circles/ -->
<html class="ocks-org do-not-copy"><link type="text/css" rel="stylesheet" id="dark-mode-custom-link"><link type="text/css" rel="stylesheet" id="dark-mode-general-link"><style lang="en" type="text/css" id="dark-mode-custom-style"></style><style lang="en" type="text/css" id="dark-mode-native-style"></style><style lang="en" type="text/css" id="dark-mode-native-sheet"></style><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Three Little Circles</title>
<style>
@import url(../style.css?aea6f0a);
</style>
</head><body><header>
<aside>June 15, 2014</aside>
<a href="https://bost.ocks.org/mike/" rel="author">Mike Bostock</a>
</header>
<h1>Three Little Circles</h1>
<p>Once upon a time, there were three little circles.
</p><p><svg width="720" height="120">
<circle cx="40" cy="60" r="10"></circle>
<circle cx="80" cy="60" r="10"></circle>
<circle cx="120" cy="60" r="10"></circle>
</svg>
</p><pre style="position: relative;"><code class="html xml"><span class="tag"><<span class="title">svg</span> <span class="attribute">width</span>=<span class="value">"720"</span> <span class="attribute">height</span>=<span class="value">"120"</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"40"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"10"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"80"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"10"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"120"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"10"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"></<span class="title">svg</span>></span></code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>This tutorial shows you how to manipulate them using selections.
<script src="./Three Little Circles_files/d3.v3.min.js.download" charset="utf-8"></script>
</p><h2><a href="https://bost.ocks.org/mike/circles/#selecting" name="selecting">#</a>Selecting Elements</h2>
<p>The <a href="https://github.com/mbostock/d3/wiki/Selections#selectAll">d3.selectAll</a> method takes a <a href="https://www.w3.org/TR/CSS2/selector.html">selector</a> string, such as <code class="javascript"><span class="string">"circle"</span></code>, and returns a <i>selection</i> representing all elements that match the selector:
</p><pre style="position: relative;"><code class="javascript"><span class="keyword">var</span> circle = d3.selectAll(<span class="string">"circle"</span>);</code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>With a selection, we can make various changes to selected elements. For example, we might change the fill color using <a href="https://github.com/mbostock/d3/wiki/Selections#style">selection.style</a> and the radius using <a href="https://github.com/mbostock/d3/wiki/Selections#attr">selection.attr</a>:
</p><pre style="position: relative;"><code class="javascript">circle.style(<span class="string">"fill"</span>, <span class="string">"steelblue"</span>);
circle.attr(<span class="string">"r"</span>, <span class="number">30</span>);</code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>The above code sets styles and attributes for all selected elements to the same values.
</p><p><svg width="720" height="120">
<circle cx="40" cy="60" r="30" style="fill:steelblue;"></circle>
<circle cx="80" cy="60" r="30" style="fill:steelblue;"></circle>
<circle cx="120" cy="60" r="30" style="fill:steelblue;"></circle>
</svg>
</p><pre style="position: relative;"><code class="html xml"><span class="tag"><<span class="title">svg</span> <span class="attribute">width</span>=<span class="value">"720"</span> <span class="attribute">height</span>=<span class="value">"120"</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"40"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"30"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"80"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"30"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"120"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"30"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"></<span class="title">svg</span>></span></code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>We can also set values on a per-element basis by using anonymous functions. The function is evaluated once per selected element. Anonymous functions are used extensively in D3 to compute attribute values, particularly in conjunction with <a href="https://github.com/mbostock/d3/wiki/Quantitative-Scales">scales</a> and <a href="https://github.com/mbostock/d3/wiki/SVG-Shapes">shapes</a>. To set each circle’s <i>x</i>-coordinate to a random value:
</p><pre style="position: relative;"><code class="javascript">circle.attr(<span class="string">"cx"</span>, <span class="function"><span class="keyword">function</span><span class="params">()</span> {</span> <span class="keyword">return</span> Math.random() * <span class="number">720</span>; });</code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>If you run this code repeatedly, the circles will dance:
</p><p><svg id="circle-dance" width="720" height="120">
<circle cx="338.77828201494236" cy="60" r="30" style="fill:steelblue;"></circle>
<circle cx="399.84491452155333" cy="60" r="30" style="fill:steelblue;"></circle>
<circle cx="400.73614333945477" cy="60" r="30" style="fill:steelblue;"></circle>
</svg>
</p><pre style="position: relative;"><code class="html xml"><span class="tag"><<span class="title">svg</span> <span class="attribute">width</span>=<span class="value">"720"</span> <span class="attribute">height</span>=<span class="value">"120"</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"<span class="circle-dance-x">338.77828201494236</span>"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"30"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"<span class="circle-dance-x">399.84491452155333</span>"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"30"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"<span class="circle-dance-x">400.73614333945477</span>"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"30"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"></<span class="title">svg</span>></span></code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<script>(function() {
function dance() {
var circle = d3.selectAll("#circle-dance circle"),
span = d3.selectAll(".circle-dance-x"),
data = d3.range(3).map(function() { return Math.random() * 720; });
circle.data(data).attr("cx", function(d) { return d; });
span.data(data).text(function(d) { return d; });
}
dance();
setInterval(dance, 2500);
})();</script>
<h2><a href="https://bost.ocks.org/mike/circles/#binding" name="binding">#</a>Binding Data</h2>
<p>More commonly, we use <i>data</i> to drive the appearance of our circles. Let’s say we want these circles represent the numbers 32, 57 and 112. The <a href="https://github.com/mbostock/d3/wiki/Selections#data">selection.data</a> method binds the numbers to the circles:
</p><pre style="position: relative;"><code class="javascript">circle.data([<span class="number">32</span>, <span class="number">57</span>, <span class="number">112</span>]);</code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>Data is specified as an array of values; this mirrors the concept of a selection, which is an array of elements. In the code above, the first number (the first <i>datum</i>, 32) is bound to the first circle (the first <i>element</i>, based on the order in which they are defined in the DOM), the second number is bound to the second circle, and so on.
</p><p>After data is bound, it is accessible as the first argument to attribute and style functions. By convention, we typically use the name <code class="javascript">d</code> to refer to bound data. To set the radius using the data:
</p><pre style="position: relative;"><code class="javascript">circle.attr(<span class="string">"r"</span>, <span class="function"><span class="keyword">function</span><span class="params">(d)</span> {</span> <span class="keyword">return</span> Math.sqrt(d); });</code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>This results in a primitive visualization:
</p><p><svg width="720" height="120">
<circle cx="40" cy="60" r="5.656854249492381" style="fill:steelblue;"></circle>
<circle cx="80" cy="60" r="7.54983443527075" style="fill:steelblue;"></circle>
<circle cx="120" cy="60" r="10.583005244258363" style="fill:steelblue;"></circle>
</svg>
</p><pre style="position: relative;"><code class="html xml"><span class="tag"><<span class="title">svg</span> <span class="attribute">width</span>=<span class="value">"720"</span> <span class="attribute">height</span>=<span class="value">"120"</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"40"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"5.656854249492381"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"80"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"7.54983443527075"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"120"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"10.583005244258363"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"></<span class="title">svg</span>></span></code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>There’s a second optional argument to each function you can also use: the <i>index</i> of the element within its selection. The index is often useful for positioning elements sequentially. Again by convention, this is often referred to as <code class="javascript">i</code>. For example:
</p><pre style="position: relative;"><code class="javascript">circle.attr(<span class="string">"cx"</span>, <span class="function"><span class="keyword">function</span><span class="params">(d, i)</span> {</span> <span class="keyword">return</span> i * <span class="number">100</span> + <span class="number">30</span>; });</code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p><svg width="720" height="120">
<circle cx="30" cy="60" r="5.656854249492381" style="fill:steelblue;"></circle>
<circle cx="130" cy="60" r="7.54983443527075" style="fill:steelblue;"></circle>
<circle cx="230" cy="60" r="10.583005244258363" style="fill:steelblue;"></circle>
</svg>
</p><pre style="position: relative;"><code class="html xml"><span class="tag"><<span class="title">svg</span> <span class="attribute">width</span>=<span class="value">"720"</span> <span class="attribute">height</span>=<span class="value">"120"</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"30"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"5.656854249492381"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"130"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"7.54983443527075"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"230"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"10.583005244258363"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"></<span class="title">svg</span>></span></code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>Note that in SVG, the <a href="https://www.w3.org/TR/SVG/coords.html#Introduction">origin</a> is in the top-left corner.
</p><h2><a href="https://bost.ocks.org/mike/circles/#entering" name="entering">#</a>Entering Elements</h2>
<p>What if we had <i>four</i> numbers to display, rather than three? We wouldn’t have enough circles, and we would need to create more elements to represent our data. You can append new nodes manually, but a more powerful alternative is the <a href="https://github.com/mbostock/d3/wiki/Selections#enter"><i>enter</i></a> selection computed by a data join.
</p><p>When joining data to elements, D3 puts any leftover data — or equivalently “missing” elements — in the enter selection. With only three circles, a fourth number would be put in the enter selection, while the other three numbers are returned directly (in the <i>update</i> selection) by selection.data.
</p><p>By <a href="https://github.com/mbostock/d3/wiki/Selections#append">appending</a> to the enter selection, we can create new circles for any missing data. The new circles will be appended to the element defined by parent selection. So, we select the <code class="javascript"><span class="string">"svg"</span></code> element first, then select all <code class="javascript"><span class="string">"circle"</span></code> elements, and then join them to data:
</p><pre style="position: relative;"><code class="javascript"><span class="keyword">var</span> svg = d3.select(<span class="string">"svg"</span>);
<span class="keyword">var</span> circle = svg.selectAll(<span class="string">"circle"</span>)
.data([<span class="number">32</span>, <span class="number">57</span>, <span class="number">112</span>, <span class="number">293</span>]);
<span class="keyword">var</span> circleEnter = circle.enter().append(<span class="string">"circle"</span>);</code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>Entering elements are already bound to the data, so we can use data to compute attributes and styles, as well as set constant properties:
</p><pre style="position: relative;"><code class="javascript">circleEnter.attr(<span class="string">"cy"</span>, <span class="number">60</span>);
circleEnter.attr(<span class="string">"cx"</span>, <span class="function"><span class="keyword">function</span><span class="params">(d, i)</span> {</span> <span class="keyword">return</span> i * <span class="number">100</span> + <span class="number">30</span>; });
circleEnter.attr(<span class="string">"r"</span>, <span class="function"><span class="keyword">function</span><span class="params">(d)</span> {</span> <span class="keyword">return</span> Math.sqrt(d); });</code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>Now we have four circles:
</p><p><svg width="720" height="120">
<circle cx="30" cy="60" r="5.656854249492381" style="fill:steelblue;"></circle>
<circle cx="130" cy="60" r="7.54983443527075" style="fill:steelblue;"></circle>
<circle cx="230" cy="60" r="10.583005244258363" style="fill:steelblue;"></circle>
<circle cx="330" cy="60" r="17.11724276862369" style="fill:steelblue;"></circle>
</svg>
</p><pre style="position: relative;"><code class="html xml"><span class="tag"><<span class="title">svg</span> <span class="attribute">width</span>=<span class="value">"720"</span> <span class="attribute">height</span>=<span class="value">"120"</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"30"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"5.656854249492381"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"130"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"7.54983443527075"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"230"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"10.583005244258363"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"330"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"17.11724276862369"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"></<span class="title">svg</span>></span></code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>Taking this to the logical extreme, then, what if we have <i>no</i> existing elements, such as with an empty page? Then we’re joining data to an empty selection, and <i>all</i> data ends up in enter.
</p><p>This pattern is so common, you’ll often see the <a href="https://github.com/mbostock/d3/wiki/Selections#selectAll">selectAll</a> + <a href="https://github.com/mbostock/d3/wiki/Selections#data">data</a> + <a href="https://github.com/mbostock/d3/wiki/Selections#enter">enter</a> + <a href="https://github.com/mbostock/d3/wiki/Selections#append">append</a> methods called sequentially, one immediately after the other. Despite it being common, keep in mind that this is just one special case of a data join.
</p><pre style="position: relative;"><code class="javascript">svg.selectAll(<span class="string">"circle"</span>)
.data([<span class="number">32</span>, <span class="number">57</span>, <span class="number">112</span>, <span class="number">293</span>])
.enter().append(<span class="string">"circle"</span>)
.attr(<span class="string">"cy"</span>, <span class="number">60</span>)
.attr(<span class="string">"cx"</span>, <span class="function"><span class="keyword">function</span><span class="params">(d, i)</span> {</span> <span class="keyword">return</span> i * <span class="number">100</span> + <span class="number">30</span>; })
.attr(<span class="string">"r"</span>, <span class="function"><span class="keyword">function</span><span class="params">(d)</span> {</span> <span class="keyword">return</span> Math.sqrt(d); });</code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>This enter pattern is often used in conjunction with <a href="https://en.wikipedia.org/wiki/Method_chaining">method chaining</a>, another technique for abbreviating code. Because D3 methods returns the selection they act upon, you can apply multiple operations to the same selection.
</p><h2><a href="https://bost.ocks.org/mike/circles/#exiting" name="exiting">#</a>Exiting Elements</h2>
<p>Often you have the opposite problem from <i>enter</i>: you have too many existing elements, and you want to remove some of them. Again you can select nodes and <a href="https://github.com/mbostock/d3/wiki/Selections#remove">remove</a> them manually, but the <a href="https://github.com/mbostock/d3/wiki/Selections#exit"><i>exit</i></a> selection computed by a data join is more powerful.
</p><p>The exit selection is the reflection of the enter selection: it contains the leftover elements for which there is no corresponding data.
</p><pre style="position: relative;"><code class="javascript"><span class="keyword">var</span> circle = svg.selectAll(<span class="string">"circle"</span>)
.data([<span class="number">32</span>, <span class="number">57</span>]);</code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>All that’s left to do, then, is to remove the exiting elements:
</p><pre style="position: relative;"><code class="javascript">circle.exit().remove();</code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>And now we have two circles:
</p><p><svg width="720" height="120">
<circle cx="30" cy="60" r="5.656854249492381" style="fill:steelblue;"></circle>
<circle cx="130" cy="60" r="7.54983443527075" style="fill:steelblue;"></circle>
</svg>
</p><pre style="position: relative;"><code class="html xml"><span class="tag"><<span class="title">svg</span> <span class="attribute">width</span>=<span class="value">"720"</span> <span class="attribute">height</span>=<span class="value">"120"</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"30"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"5.656854249492381"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"><<span class="title">circle</span> <span class="attribute">cx</span>=<span class="value">"130"</span> <span class="attribute">cy</span>=<span class="value">"60"</span> <span class="attribute">r</span>=<span class="value">"7.54983443527075"</span> <span class="attribute">style</span>=<span class="value">"fill:steelblue;"</span>></span><span class="tag"></<span class="title">circle</span>></span>
<span class="tag"></<span class="title">svg</span>></span></code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>Of course, you aren’t required to remove exiting elements immediately; for example, you might apply a transition to have them fade out or slide away.
</p><h2><a href="https://bost.ocks.org/mike/circles/#all-together" name="all-together">#</a>All Together</h2>
<p>Putting everything together, consider the three possible outcomes that result from joining data to elements:</p><ol>
<li><i>enter</i> - incoming elements, entering the stage.
</li><li><i>update</i> - persistent elements, staying on stage.
</li><li><i>exit</i> - outgoing elements, exiting the stage.
</li></ol><p>By default, the data join happens by index: the first element is bound to the first datum, and so on. Thus, either the enter or exit selection will be empty, or both. If there are more data than elements, the extra data are in the enter selection. And if there are fewer data than elements, the extra elements are in the exit selection.
</p><p>You can control precisely which datum is bound to which element by specifying a <a href="https://bost.ocks.org/mike/constancy/">key function</a> to selection.data. For example, by using the identity function, you can rebind the circles to new data while ensuring that existing circles are rebound to the same value in the new data, if any.
</p><pre style="position: relative;"><code class="javascript"><span class="keyword">var</span> circle = svg.selectAll(<span class="string">"circle"</span>)
.data([<span class="number">32</span>, <span class="number">57</span>, <span class="number">293</span>], <span class="function"><span class="keyword">function</span><span class="params">(d)</span> {</span> <span class="keyword">return</span> d; });
circle.enter().append(<span class="string">"circle"</span>)
.attr(<span class="string">"cy"</span>, <span class="number">60</span>)
.attr(<span class="string">"cx"</span>, <span class="function"><span class="keyword">function</span><span class="params">(d, i)</span> {</span> <span class="keyword">return</span> i * <span class="number">100</span> + <span class="number">30</span>; })
.attr(<span class="string">"r"</span>, <span class="function"><span class="keyword">function</span><span class="params">(d)</span> {</span> <span class="keyword">return</span> Math.sqrt(d); });
circle.exit().remove();</code><div class="open_grepper_editor" title="Edit & Save To Grepper"></div></pre>
<p>Want to learn more about selections and transitions? Read <a href="https://bost.ocks.org/mike/bar/">Let’s Make a Bar Chart</a> and <a href="https://bost.ocks.org/mike/constancy/">Object Constancy</a> for practical examples of using enter and
exit to display data, and read <a href="https://bost.ocks.org/mike/join/">Thinking with Joins</a> and <a href="https://bost.ocks.org/mike/selection/">How Selections Work</a> for more detailed information on data joins and selections. Also see <a href="https://bost.ocks.org/mike/transition/">Working with Transitions</a>.
</p><footer>
<aside>June 15, 2014</aside>
<a href="https://bost.ocks.org/mike/" rel="author">Mike Bostock</a>
</footer>
<script>
GoogleAnalyticsObject = "ga", ga = function() { ga.q.push(arguments); }, ga.q = [], ga.l = +new Date;
ga("create", "UA-48272912-3", "ocks.org");
ga("send", "pageview");
</script>
<script async="" src="./Three Little Circles_files/highlight.min.js.download"></script>
<script async="" src="./Three Little Circles_files/analytics.js.download"></script>
</body></html>