| 
					
				 | 
			
			
				@@ -1,64 +1,34 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const scores = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  { name: "Alice", score: 96 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  { name: "Billy", score: 83 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  { name: "Cindy", score: 81 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  { name: "David", score: 96 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  { name: "Emily", score: 88 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function scaleBar(selection, scale) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  selection.style('transform', `scaleX(${scale})`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function fade(selection, opacity) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  selection.style('fill-opacity', opacity); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function setFill(selection, color) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  selection.style('fill', color); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const bar = d3.select(".chart") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* global d3 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// D3 convention: define margin as an object called margin with these props: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let margin = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  top: 10, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  right: 20, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  bottom: 25, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  left: 25 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let width = 425 - margin.left - margin.right; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let height = 625 - margin.top - margin.bottom; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let svg = d3.select('.chart') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   .append('svg') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .attr('width', 225) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .attr('height', 300) // 5 * 33 = 165 < 300 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .selectAll("g") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .data(scores) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .enter() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // In D3, the SVG <g> is used as a generic container like a HTML <div>. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .append("g") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // D3 convention: d for data, i for index. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // <g> doesn't support x,y, but needs transform. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // translate take a comma-separated list of x,y coordinates. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .attr('transform', (d, i) => 'translate(0, ' + i * 33 + ')'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// Notice how we don't pass data again or use a loop: they are included in the selection. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bar.append('rect') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .style("width", d => d.score) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .text(d => d.name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .attr("class", "bar") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .on('mouseover', function (d, i, elements) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    d3.select(this) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      .call(scaleBar, 1.5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      .call(setFill, 'orange'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    d3.selectAll(elements) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      .filter(':not(:hover)') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      .call(fade, 0.2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .on('mouseout', function (d, i, elements) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    d3.select(this) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      .call(scaleBar, 1) // call returns the (modified) selection. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      .call(setFill, 'palegreen'); // ...which allows chaining. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    d3.selectAll(elements) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      .call(fade, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .on('click', (who) => console.log(`hi ${who.name}`)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bar.append('text') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .attr('y', 20) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .text(d => d.name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Match the size of the chart-containing <div>. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .attr('width', width + margin.left + margin.right) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .attr('height', height + margin.top + margin.bottom) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .append('g') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .attr('transform', () => `translate(${margin.left},${margin.top})`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Everything below this line no longer needs to care about margins. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// At this point, the "svg" variable actually contains the <g> selection. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+svg.append('rect') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .attr('width', width / 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .attr('height', height) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .style('fill', 'lightblue') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .style('stroke', 'green'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+svg.append('rect') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .attr('x', width / 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .attr('width', width / 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .attr('height', height) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .style('fill', 'lightblue') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .style('stroke', 'green'); 
			 |