I’m new to d3.js and I’m trying to change this code. What I actually need is to have each slice’s name on it. The problem is that labels need to change for each button. For example, if you click on culture/Media the labels are – German, English, History but for medicine are – Dentist, Pharmacist…
any help is highly appreciated 🙂
JavaScript
x
360
360
1
var transitionSpeed = 2000;
2
3
var hareReturn = "";
4
var mixReturn = "";
5
var tortoiseReturn = "";
6
7
var currentData = [];
8
var dataset = [{
9
"label": "Mathematics",
10
"count": 16500
11
},
12
{
13
"label": "Computer Science",
14
"count": 58000
15
},
16
{
17
"label": "Physics",
18
"count": 35000
19
},
20
{
21
"label": "Chemistry",
22
"count": 12700
23
},
24
{
25
"label": "Biology",
26
"count": 13500
27
},
28
];
29
30
31
32
33
34
var tortoiseData = [{
35
"label": "English / American Studies",
36
"count": 5800
37
},
38
{
39
"label": "History",
40
"count": 7900
41
},
42
{
43
"label": "German",
44
"count": 11000
45
},
46
{
47
"label": "",
48
"count": 0
49
},
50
{
51
"label": "",
52
"count": 0
53
}
54
];
55
56
var mixData = [{
57
"label": "Electro technology",
58
"count": 17500
59
},
60
{
61
"label": "Civil Engineering",
62
"count": 13700
63
},
64
{
65
"label": "Architecture",
66
"count": 8850
67
},
68
{
69
"label": "Mechanical Engineering / Process Engineering",
70
"count": 37000
71
},
72
{
73
"label": "",
74
"count": 0
75
},
76
{
77
"label": "",
78
"count": 0
79
},
80
{
81
"label": "",
82
"count": 0
83
},
84
];
85
86
87
var socialData = [{
88
"label": "Social Studies",
89
"count": 25400
90
},
91
{
92
"label": "Social Sciences",
93
"count": 8200
94
},
95
{
96
"label": "Pedagogic",
97
"count": 10500
98
},
99
{
100
"label": "Psychology",
101
"count": 10800
102
},
103
{
104
"label": "",
105
"count": 0
106
}
107
108
];
109
var lawData = [{
110
"label": "Economics",
111
"count": 102000
112
},
113
{
114
"label": "Business Engineering",
115
"count": 19900
116
},
117
{
118
"label": "Jurisprudence",
119
"count": 32000
120
},
121
{
122
"label": "Administration & Public Management",
123
"count": 20000
124
},
125
{
126
"label": "",
127
"count": 0
128
},
129
{
130
"label": "",
131
"count": 0
132
},
133
{
134
"label": "",
135
"count": 0
136
},
137
];
138
var MedData = [{
139
"label": "Medicine",
140
"count": 16500
141
},
142
{
143
"label": "Pharmacy",
144
"count": 15100
145
},
146
{
147
"label": "Dentist",
148
"count": 14800
149
},
150
{
151
"label": "",
152
"count": 0
153
},
154
{
155
"label": "",
156
"count": 0
157
}
158
];
159
160
161
162
163
164
165
166
167
168
var width = 360;
169
var height = 360;
170
var radius = Math.min(width, height) / 2;
171
var donutWidth = 75;
172
var legendRectSize = 18;
173
var legendSpacing = 4;
174
175
var color = d3.scale.category20b();
176
177
var svg = d3.select('#chart')
178
.append('svg')
179
.attr('width', width)
180
.attr('height', height)
181
.append('g')
182
.attr('transform', 'translate(' + (width / 2) +
183
',' + (height / 2) + ')');
184
185
var arc = d3.svg.arc()
186
.innerRadius(radius - donutWidth)
187
.outerRadius(radius);
188
189
var pie = d3.layout.pie()
190
.value(function(d) {
191
return d.count;
192
})
193
.sort(null);
194
195
var tooltip = d3.select('#chart')
196
.append('div')
197
.attr('class', 'tooltip');
198
199
tooltip.append('div')
200
.attr('class', 'label');
201
202
tooltip.append('div')
203
.attr('class', 'count');
204
205
206
currentData = dataset;
207
208
var path = svg.selectAll('path')
209
.data(pie(currentData))
210
.enter()
211
.append('path')
212
.attr('d', arc)
213
.attr('fill', function(d, i) {
214
return color(d.data.label);
215
})
216
.each(function(d) {
217
this._current = d;
218
});
219
220
path.on('mouseover', function(d) {
221
var total = d3.sum(currentData.map(function(d) {
222
return d.count; // UPDATED
223
}));
224
var percent = Math.round(transitionSpeed * d.data.count / total) / 10;
225
tooltip.select('.label').html(d.data.label);
226
tooltip.select('.count').html(d.data.count);
227
228
tooltip.style('display', 'block');
229
});
230
231
path.on('mouseout', function() {
232
tooltip.style('display', 'none');
233
});
234
235
svg.append("text")
236
.attr("class", "return")
237
.text(hareReturn + "%")
238
.attr("y", ".3em")
239
.attr("text-anchor", "middle")
240
.style('fill', 'white')
241
242
var tortoise = d3.select("#tortoise")
243
.on("click", function(e) {
244
//alert("tortoise");
245
d3.select(".return")
246
.transition()
247
.duration(transitionSpeed)
248
.tween('text', textTween(tortoiseReturn));
249
currentData = tortoiseData;
250
path = path.data(pie(currentData));
251
path.transition()
252
.duration(transitionSpeed)
253
.attrTween('d', arcTween);
254
});
255
256
var mix = d3.select("#mix")
257
.on("click", function(e) {
258
//alert("tortoise");
259
d3.select(".return")
260
.transition()
261
.duration(transitionSpeed)
262
.tween('text', textTween(mixReturn));
263
264
path = path.data(pie(mixData));
265
path.transition()
266
.duration(transitionSpeed)
267
.attrTween('d', arcTween);
268
})
269
270
var hare = d3.select("#hare")
271
.on("click", function(e) {
272
//alert("tortoise");
273
d3.select(".return")
274
.transition()
275
.duration(transitionSpeed)
276
.tween('text', textTween(hareReturn));
277
278
path = path.data(pie(dataset));
279
path.transition()
280
.duration(transitionSpeed)
281
.attrTween('d', arcTween);
282
})
283
var social = d3.select("#socialStudies")
284
.on("click", function(e) {
285
286
d3.select(".return")
287
.transition()
288
.duration(transitionSpeed)
289
.tween('text', textTween(mixReturn));
290
291
path = path.data(pie(socialData));
292
path.transition() // NEW
293
.duration(transitionSpeed) // NEW
294
.attrTween('d', arcTween);
295
})
296
var ecolaw = d3.select("#law")
297
.on("click", function(e) {
298
//alert("tortoise");
299
d3.select(".return")
300
.transition()
301
.duration(transitionSpeed);
302
303
path = path.data(pie(lawData));
304
path.transition() // NEW
305
.duration(transitionSpeed) // NEW
306
.attrTween('d', arcTween);
307
})
308
309
var Med = d3.select("#med")
310
.on("click", function(e) {
311
//alert("tortoise");
312
d3.select(".return")
313
.transition()
314
.duration(transitionSpeed);
315
316
path = path.data(pie(MedData));
317
path.transition() // NEW
318
.duration(transitionSpeed) // NEW
319
.attrTween('d', arcTween);
320
})
321
322
function textTween(newValue) {
323
return function() {
324
// get current value as starting point for tween animation
325
var currentValue = +this.textContent;
326
// create interpolator and do not show nasty floating numbers
327
var i = d3.interpolate(this.textContent, newValue);
328
329
return function(t) {
330
331
this.textContent = d3.round(i(t), 2) + "%";
332
};
333
}
334
}
335
336
// Store the displayed angles in _current.
337
// Then, interpolate from _current to the new angles.
338
// During the transition, _current is updated in-place by d3.interpolate.
339
function arcTween(d) {
340
var interpolate = d3.interpolate(this._current, d); // NEW
341
this._current = interpolate(0); // NEW
342
return function(t) { // NEW
343
return arc(interpolate(t)); // NEW
344
};
345
}
346
347
d3.interpolators.push(function(a, b) {
348
var re = /^(dd.dd)%$/,
349
ma, mb, f = d3.format('05.2f');
350
351
if ((ma = re.exec(a)) && (mb = re.exec(b))) {
352
353
a = parseFloat(ma[1]);
354
b = parseFloat(mb[1]) - a;
355
356
return function(t) {
357
return f(a + b * t) + '%';
358
};
359
}
360
});
JavaScript
1
99
99
1
#left {
2
float: left;
3
width: 250px;
4
overflow: hidden;
5
margin-right: 130px;
6
}
7
8
h1,
9
h2,
10
h3,
11
h4 {
12
font-weight: 400;
13
letter-spacing: 0.3rem;
14
text-transform: uppercase;
15
color: #777;
16
}
17
18
.buttons {
19
margin-left: 250px;
20
margin-bottom: 70px;
21
margin-top: 80px;
22
width: 805px;
23
}
24
25
#chart {
26
overflow: hidden;
27
height: 360px;
28
margin: 0 auto;
29
/* NEW */
30
position: relative;
31
}
32
33
.tooltip {
34
background: #eee;
35
box-shadow: 0 0 5px #999999;
36
color: #333;
37
display: none;
38
font-size: 12px;
39
left: 130px;
40
padding: 10px;
41
position: Absolute;
42
text-align: center;
43
top: 95px;
44
width: 80px;
45
z-index: 10;
46
}
47
48
.legend {
49
font-size: 12px;
50
}
51
52
rect {
53
cursor: pointer;
54
/* NEW */
55
stroke-width: 2;
56
}
57
58
rect.disabled {
59
/* NEW */
60
fill: transparent !important;
61
/* NEW */
62
}
63
64
65
/* NEW */
66
67
h1 {
68
/* NEW */
69
font-size: 14px;
70
/* NEW */
71
text-align: center;
72
/* NEW */
73
}
74
75
.return {
76
font-size: 3.8rem;
77
}
78
79
.tooltip {
80
text-align: left;
81
}
82
83
.container {
84
width: 1200px;
85
height: 500px;
86
margin: 25px auto 25px auto;
87
padding: 50px 50px 50px 50px;
88
background-color: white;
89
box-shadow: 0 0 20px #ccc;
90
font-family: 'Source Sans Pro', sans-serif;
91
}
92
93
p {
94
color: #777;
95
font-size: 16px;
96
line-height: 28px;
97
word-spacing: 1px;
98
letter-spacing: 1px;
99
}
JavaScript
1
24
24
1
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
2
<div class="container">
3
<div id="left">
4
<h2> Description </h2>
5
<p> This Donut Diagram shows you the number of enrolled students in 2018 in each Major and Specialization just click on your desired major and hover on each piece of donut for more information!</p>
6
<h2> Category:</h2>
7
<p>
8
Academic Data</p>
9
</div>
10
<div id="chart"></div>
11
12
13
<div class='buttons'>
14
<button id="tortoise">Culture / Media
15
</button>
16
<button id="mix">Engineering</button>
17
<button id="hare">Mathematics and Natural Science</button>
18
<button id="socialStudies">Social Studies</button>
19
<button id="law">Economy and law </button>
20
<button id="med">Medicine </button>
21
</div>
22
23
24
</div>
Advertisement
Answer
I’ve refactored your code a bit, since you kept doing the same thing a lot. Look at the update
function for that.
You also didn’t account for more/fewer slices depending on the selection, so I added that as well.
The texts do not animate yet, but I think you should be able to manage that.
JavaScript
1
347
347
1
var transitionSpeed = 2000;
2
3
var hareReturn = "";
4
var mixReturn = "";
5
var tortoiseReturn = "";
6
var socialReturn = "";
7
var lawReturn = "";
8
var medReturn = "";
9
10
var dataset = [{
11
"label": "Mathematics",
12
"count": 16500
13
},
14
{
15
"label": "Computer Science",
16
"count": 58000
17
},
18
{
19
"label": "Physics",
20
"count": 35000
21
},
22
{
23
"label": "Chemistry",
24
"count": 12700
25
},
26
{
27
"label": "Biology",
28
"count": 13500
29
},
30
];
31
32
var tortoiseData = [{
33
"label": "English / American Studies",
34
"count": 5800
35
},
36
{
37
"label": "History",
38
"count": 7900
39
},
40
{
41
"label": "German",
42
"count": 11000
43
},
44
{
45
"label": "",
46
"count": 0
47
},
48
{
49
"label": "",
50
"count": 0
51
}
52
];
53
54
var mixData = [{
55
"label": "Electro technology",
56
"count": 17500
57
},
58
{
59
"label": "Civil Engineering",
60
"count": 13700
61
},
62
{
63
"label": "Architecture",
64
"count": 8850
65
},
66
{
67
"label": "Mechanical Engineering / Process Engineering",
68
"count": 37000
69
},
70
{
71
"label": "",
72
"count": 0
73
},
74
{
75
"label": "",
76
"count": 0
77
},
78
{
79
"label": "",
80
"count": 0
81
},
82
];
83
84
var socialData = [{
85
"label": "Social Studies",
86
"count": 25400
87
},
88
{
89
"label": "Social Sciences",
90
"count": 8200
91
},
92
{
93
"label": "Pedagogic",
94
"count": 10500
95
},
96
{
97
"label": "Psychology",
98
"count": 10800
99
},
100
{
101
"label": "",
102
"count": 0
103
}
104
105
];
106
var lawData = [{
107
"label": "Economics",
108
"count": 102000
109
},
110
{
111
"label": "Business Engineering",
112
"count": 19900
113
},
114
{
115
"label": "Jurisprudence",
116
"count": 32000
117
},
118
{
119
"label": "Administration & Public Management",
120
"count": 20000
121
},
122
{
123
"label": "",
124
"count": 0
125
},
126
{
127
"label": "",
128
"count": 0
129
},
130
{
131
"label": "",
132
"count": 0
133
},
134
];
135
var MedData = [{
136
"label": "Medicine",
137
"count": 16500
138
},
139
{
140
"label": "Pharmacy",
141
"count": 15100
142
},
143
{
144
"label": "Dentist",
145
"count": 14800
146
},
147
{
148
"label": "",
149
"count": 0
150
},
151
{
152
"label": "",
153
"count": 0
154
}
155
];
156
157
var width = 360;
158
var height = 360;
159
var radius = Math.min(width, height) / 2;
160
var donutWidth = 75;
161
var legendRectSize = 18;
162
var legendSpacing = 4;
163
164
var color = d3.scale.category20b();
165
166
var svg = d3.select('#chart')
167
.append('svg')
168
.attr('width', width)
169
.attr('height', height)
170
.append('g')
171
.attr('transform', 'translate(' + (width / 2) +
172
',' + (height / 2) + ')');
173
174
var arc = d3.svg.arc()
175
.innerRadius(radius - donutWidth)
176
.outerRadius(radius);
177
178
var pie = d3.layout.pie()
179
.value(function(d) {
180
return d.count;
181
})
182
.sort(null);
183
184
var tooltip = d3.select('#chart')
185
.append('div')
186
.attr('class', 'tooltip');
187
188
tooltip.append('div')
189
.attr('class', 'label');
190
191
tooltip.append('div')
192
.attr('class', 'count');
193
194
svg.append("text")
195
.attr("class", "return")
196
.text(hareReturn + "%")
197
.attr("y", ".3em")
198
.attr("text-anchor", "middle")
199
.style('fill', 'white')
200
201
function textTween(newValue) {
202
return function() {
203
// get current value as starting point for tween animation
204
var currentValue = +this.textContent;
205
// create interpolator and do not show nasty floating numbers
206
var i = d3.interpolate(this.textContent, newValue);
207
208
return function(t) {
209
210
this.textContent = d3.round(i(t), 2) + "%";
211
};
212
}
213
}
214
215
// Store the displayed angles in _current.
216
// Then, interpolate from _current to the new angles.
217
// During the transition, _current is updated in-place by d3.interpolate.
218
function arcTween(d) {
219
var dummy = {
220
endAngle: 0,
221
padAngle: 0,
222
startAngle: 0,
223
value: 0
224
};
225
226
var old = this._current || dummy;
227
var _new = d || dummy;
228
229
var interpolate = d3.interpolate(old, _new); // NEW
230
this._current = interpolate(0); // NEW
231
return function(t) { // NEW
232
return arc(interpolate(t)); // NEW
233
};
234
}
235
236
d3.interpolators.push(function(a, b) {
237
var re = /^(dd.dd)%$/,
238
ma, mb, f = d3.format('05.2f');
239
240
if ((ma = re.exec(a)) && (mb = re.exec(b))) {
241
242
a = parseFloat(ma[1]);
243
b = parseFloat(mb[1]) - a;
244
245
return function(t) {
246
return f(a + b * t) + '%';
247
};
248
}
249
});
250
251
update(hareReturn, dataset);
252
253
function update(currentReturn, currentData) {
254
d3.select(".return")
255
.transition()
256
.duration(transitionSpeed)
257
.tween('text', textTween(currentReturn));
258
259
var path = svg.selectAll('path')
260
.each(function(d) {
261
this._current = d; // set current before updating
262
})
263
.data(pie(currentData));
264
265
path
266
.enter()
267
.append('path')
268
// We use a dummy value in arcTween to make new slices appear
269
.attr('fill', function(d, i) {
270
return color(d.data.label);
271
});
272
273
path
274
.exit()
275
.transition()
276
.duration(transitionSpeed)
277
.attrTween('d', function() {
278
// We use a dummy value in arcTween to make old slices disappear
279
return arcTween();
280
});
281
282
path
283
.transition()
284
.duration(transitionSpeed)
285
.attrTween('d', arcTween);
286
287
/* Add labels here */
288
svg.selectAll('.pie-label')
289
.data(pie(currentData))
290
.enter()
291
.append('text')
292
.classed('pie-label', true);
293
294
svg.selectAll('.pie-label')
295
.attr('x', function(d) {
296
return arc.centroid(d)[0];
297
})
298
.attr('y', function(d) {
299
return arc.centroid(d)[1];
300
})
301
.text(function(d, i) {
302
return d.data.label;
303
});
304
305
path.on('mouseover', function(d) {
306
var total = d3.sum(currentData.map(function(d) {
307
return d.count; // UPDATED
308
}));
309
var percent = Math.round(transitionSpeed * d.data.count / total) / 10;
310
tooltip.select('.label').html(d.data.label);
311
tooltip.select('.count').html(d.data.count);
312
313
tooltip.style('display', 'block');
314
});
315
316
path.on('mouseout', function() {
317
tooltip.style('display', 'none');
318
});
319
}
320
321
var tortoise = d3.select("#tortoise")
322
.on("click", function(e) {
323
update(tortoiseReturn, tortoiseData);
324
});
325
326
var mix = d3.select("#mix")
327
.on("click", function(e) {
328
update(mixReturn, mixData);
329
})
330
331
var hare = d3.select("#hare")
332
.on("click", function(e) {
333
update(hareReturn, dataset);
334
})
335
var social = d3.select("#socialStudies")
336
.on("click", function(e) {
337
update(socialReturn, socialData);
338
})
339
var ecolaw = d3.select("#law")
340
.on("click", function(e) {
341
update(lawReturn, lawData);
342
})
343
344
var Med = d3.select("#med")
345
.on("click", function(e) {
346
update(medReturn, MedData);
347
})
JavaScript
1
106
106
1
#left {
2
float: left;
3
width: 250px;
4
overflow: hidden;
5
margin-right: 130px;
6
}
7
8
h1,
9
h2,
10
h3,
11
h4 {
12
font-weight: 400;
13
letter-spacing: 0.3rem;
14
text-transform: uppercase;
15
color: #777;
16
}
17
18
.buttons {
19
margin-left: 250px;
20
margin-bottom: 70px;
21
margin-top: 80px;
22
width: 805px;
23
}
24
25
#chart {
26
overflow: hidden;
27
height: 360px;
28
margin: 0 auto;
29
/* NEW */
30
position: relative;
31
}
32
33
.tooltip {
34
background: #eee;
35
box-shadow: 0 0 5px #999999;
36
color: #333;
37
display: none;
38
font-size: 12px;
39
left: 130px;
40
padding: 10px;
41
position: Absolute;
42
text-align: center;
43
top: 95px;
44
width: 80px;
45
z-index: 10;
46
}
47
48
.legend {
49
font-size: 12px;
50
}
51
52
rect {
53
cursor: pointer;
54
/* NEW */
55
stroke-width: 2;
56
}
57
58
rect.disabled {
59
/* NEW */
60
fill: transparent !important;
61
/* NEW */
62
}
63
64
65
/* NEW */
66
67
h1 {
68
/* NEW */
69
font-size: 14px;
70
/* NEW */
71
text-align: center;
72
/* NEW */
73
}
74
75
.return {
76
font-size: 3.8rem;
77
}
78
79
.tooltip {
80
text-align: left;
81
}
82
83
.container {
84
width: 1200px;
85
height: 500px;
86
margin: 25px auto 25px auto;
87
padding: 50px 50px 50px 50px;
88
background-color: white;
89
box-shadow: 0 0 20px #ccc;
90
font-family: 'Source Sans Pro', sans-serif;
91
}
92
93
p {
94
color: #777;
95
font-size: 16px;
96
line-height: 28px;
97
word-spacing: 1px;
98
letter-spacing: 1px;
99
}
100
101
102
/* Styles to make the labels nicer */
103
104
text.pie-label {
105
text-anchor: middle;
106
}
JavaScript
1
24
24
1
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
2
<div class="container">
3
<div id="left">
4
<h2> Description </h2>
5
<p> This Donut Diagram shows you the number of enrolled students in 2018 in each Major and Specialization just click on your desired major and hover on each piece of donut for more information!</p>
6
<h2> Category:</h2>
7
<p>
8
Academic Data</p>
9
</div>
10
<div id="chart"></div>
11
12
13
<div class='buttons'>
14
<button id="tortoise">Culture / Media
15
</button>
16
<button id="mix">Engineering</button>
17
<button id="hare">Mathematics and Natural Science</button>
18
<button id="socialStudies">Social Studies</button>
19
<button id="law">Economy and law </button>
20
<button id="med">Medicine </button>
21
</div>
22
23
24
</div>