This is the alpha version of my visualization for the kobe's shot history record. In this visualizaion, I create a pie chart to display the proportion of the shot zone that kobe has decided to make a move.
This data is from Kobe Bryant Shot Selection. This is a kaggle playgroup event. The data contains the location and circumstances of every field goal attempted by Kobe Bryant took during his 20-year career. Your task is to predict whether the basket went in. For data visualization purpose, I remove this column for better use.
forked from curran's block: Donut Chart
forked from curran's block: Data Table Summary
forked from YouthBread's block: Data Table Summary - Kobe
xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<title>Data Summary</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.min.js"></script>
<style>
body {
margin: 0px;
}
.tick text, .legendCells text {
fill: #111111;
font-size: 10pt;
font-family: 'Open Sans', sans-serif;
}
.axis-label, .legend-label {
fill: #AAAAAA;
font-size: 10pt;
font-family: 'Open Sans', sans-serif;
}
.subtitle {
font-size: 40pt;
font-family: 'Open Sans', sans-serif;
alignment-baseline: middle;
fill: #001f3f;
}
circle:hover {
fill: #F012BE;
}
div.tooltip {
position: absolute;
text-align: center;
width: 280px;
height: 60px;
vertical-align: middle;
line-height: 30px;
font-family:'Open Sans', sans-serif;
background: #FFDC00;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
</style>
</head>
<body>
<script>
const colorLabel = 'Basic Shot Zone';
const margin = { left: 120, right: 120, top: 20, bottom: 120 };
const svg = d3.select("body").append("svg")
.attr("width", 1000)
.attr("height", 500);
const width = svg.attr('width');
const height = svg.attr('height');
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top+50})`);
const colorLegendG = g.append('g')
.attr('transform', `translate(${innerWidth - 100}, 50)`);
const canvas = g.append('g')
.attr('transform', `translate(${innerWidth / 2},${innerHeight / 2})`);
var temp = d3.select('body').append('div')
.attr('class', 'tooltip')
.style('opacity', 0);
g.append('text')
.attr('class', 'subtitle')
.attr('x', 0)
.attr('y', margin.top-50)
.style('font-weight', 'bold')
.text('Kobe\'s basic shot zone');
colorLegendG.append('text')
.attr('class', 'legend-label')
.attr('x', -30)
.attr('y', -20)
.text(colorLabel);
const colorScale = d3.scaleOrdinal()
.range(d3.schemeCategory10);
const colorLegend = d3.legendColor()
.scale(colorScale)
.shape('square');
const pie = d3.pie().value(d => d.value);
const arc = d3.arc()
.innerRadius(innerHeight / 4)
.outerRadius(innerHeight / 2);
var temp = d3.select('body').append('div')
.attr('class', 'tooltip')
.style('opacity', 0);
d3.csv('kobe.csv', data => {
var temp_data = d3.nest()
.key(function(d) { return d.shot_zone_basic; })
.rollup(d => d.length)
.entries(data);
const arcs = pie(temp_data);
canvas.selectAll('path')
.data(arcs)
.enter()
.append('path')
.attr('d', arc)
.attr('fill', d => colorScale(d.data.key))
.on("mouseover", function(d) {
temp.transition()
.duration(200)
.style("opacity", 1);
temp.html("Basic shot zone:"+d.data.key + '<br>' +
"Shot Count:" + d.data.value)
.style("left", (d3.event.pageX - 60) + "px")
.style("top", (d3.event.pageY + 20) + "px");
})
.on("mouseout", function(d) {
temp.transition()
.duration(500)
.style("opacity", 0);
});
colorLegendG.call(colorLegend)
.selectAll('.cell text')
.attr('dy', '0.1em');
});
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js
https://d3js.org/d3.v4.min.js
https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.min.js