-
Notifications
You must be signed in to change notification settings - Fork 0
/
25_adding_values_exercise_complete.html
187 lines (156 loc) · 5.41 KB
/
25_adding_values_exercise_complete.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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3: Adding values and elements to a chart</title>
<script type="text/javascript" src="../d3/d3.v3.js"></script>
<style type="text/css">
/* No style rules here yet */
</style>
</head>
<body>
<p id="addButton" >Click on this text to add a new data value to the chart!</p>
<!-- <p id="removeButton">Click on this text to remove a data value
from the chart!"</p> -->
<script type="text/javascript">
//Width and height
var w = 600;
var h = 250;
var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,
11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
var xScale = d3.scale.ordinal()
.domain(d3.range(dataset.length))
.rangeRoundBands([0, w], 0.05);
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset)])
.range([0, h]);
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Create bars
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function(d, i) {
return xScale(i);
})
.attr("y", function(d) {
return h - yScale(d);
})
.attr("width", xScale.rangeBand())
.attr("height", function(d) {
return yScale(d);
})
.attr("fill", function(d) {
return "rgb(0, 0, " + (d * 10) + ")";
});
//Create labels
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {
return d;
})
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
return xScale(i) + xScale.rangeBand() / 2;
})
.attr("y", function(d) {
return h - yScale(d) + 14;
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "white");
d3.select("#removeButton")
.on("click", function() {
// step 1: remove an item from the dataset
dataset.shift();
var bars = svg.selectAll("rect") //Select all bars
.data(dataset); //Re-bind data to existing bars, return the 'update' selection
bars.exit()
.transition()
.duration(500)
.attr("x", w)
.remove()
;
}) // END ON CLICK
;
//On click of addbutton, update with new data
d3.select("#addButton")
.on("click", function() {
//Add one new value to dataset
var maxValue = 25;
var newNumber = Math.floor(Math.random() * maxValue); //New random integer (0-24)
dataset.push(newNumber); //Add new number to array
//Update scale domains
xScale.domain(d3.range(dataset.length)); //Recalibrate the x scale domain, given the new length of dataset
yScale.domain([0, d3.max(dataset)]); //Recalibrate the y scale domain, given the new max value in dataset
//Select…
var bars = svg.selectAll("rect") //Select all bars
.data(dataset); //Re-bind data to existing bars, return the 'update' selection
//'bars' is now the update selection
//Enter…
bars.enter() //References the enter selection (a subset of the update selection)
.append("rect") //Creates a new rect
.attr("x", w) //Sets the initial x position of the rect beyond the far right edge of the SVG
.attr("y", function(d) { //Sets the y value, based on the updated yScale
return h - yScale(d);
})
.attr("width", xScale.rangeBand()) //Sets the width value, based on the updated xScale
.attr("height", function(d) { //Sets the height value, based on the updated yScale
return yScale(d);
})
.attr("fill", function(d) { //Sets the fill value
return "rgb(0, 0, " + (d * 10) + ")";
});
//Update…
bars.transition() //Initiate a transition on all elements in the update selection (all rects)
.duration(500)
.attr("x", function(d, i) { //Set new x position, based on the updated xScale
return xScale(i);
})
.attr("y", function(d) { //Set new y position, based on the updated yScale
return h - yScale(d);
})
.attr("width", xScale.rangeBand()) //Set new width value, based on the updated xScale
.attr("height", function(d) { //Set new height value, based on the updated yScale
return yScale(d);
}); // END BARS UPDATE
//Update all labels
// re-binds all the data to the existing labels, returns the 'update' selection.
var text = svg.selectAll("text")
.data(dataset);
// enter the new label
text.enter()
.append("text")
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "white")
.text(function(d) {
console.log("d is" + d);
return d;
})
.attr("x", w) // create it offscreen, move it on later.
.attr("y", function(d) {
return h - yScale(d) + 14; // magic number...
})
;
// update
text.transition() // initiate a transition on all elements in the update selection (all texts)
.duration(500)
.attr("x", function (d, i) {
return xScale(i) + (xScale.rangeBand() / 2); // place each label in the middle of its bar.
})
.attr("y", function (d) {
return h - yScale(d) + 14;
})
; // END TEXT UPDATE
}); // END ON CLICK
</script>
</body>
</html>