This is a basketball court that I implemented using D3.jS. This court has a interactive feature that user can use a slider to choose a specific season's data. The initial version of this visualization is plotting the marks for each shot is using the intuitive green dot and red cross which represent those he made and those he missed. And the data update is following the general update pattern.
After looking at the suggestion from professor, I switch to use contour map for better display. When Kobe shoots a lot in a single seaon, the marks will overlap but the heatmap will not.
User can use the slider to choose a specific season's Kobe Bryant shoting data. Begin with his rookie season 1996-97 and ending with his final season 2015-16. By using the control, the basketball court will automatically update the data represent different season. The heatmap will show where Kobe liked to make his moves.
The contour is referencing Mike Bostock's block Density Contours
The Slider is referencing Andrew Wang's block Chart Slider
The function that I use to draw the arc of the court is referencing virajsanghvi/d3.basketball-shot-chart.
The size of the court is referencing Basketball Court Dimensions & Measurements
xxxxxxxxxx
<html>
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width'>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.min.js'></script>
<script src="https://d3js.org/d3-contour.v1.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src='Court.js'></script>
<script src='Shot.js'></script>
<script src='Slider.js'></script>
<script src='Table.js'></script>
<script src='HeatMap.js'></script>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700' rel='stylesheet'>
<title>Visualization Project</title>
<link rel='stylesheet' href='css/styles.css'>
</head>
<body>
<style>
body {
font-family: 'Open Sans', sans-serif;
}
#court {
position: fixed;
left: 0px;
right: 0px;
top: 50px;
bottom: 0px;
}
.slider rect {
fill: gray;
shape-rendering: crispEdges;
}
.slider line {
fill: none;
stroke: red;
opacity: 0.3;
shape-rendering: crispEdges;
}
</style>
<h2 id='caption'></h2>
<div id='court'></div>
<div id='stats'></div>
<script>
const margin = { left: 20, right: 20, top: 20, bottom: 20 };
var chartDiv = document.getElementById('court');
var court = d3.select(chartDiv).append('court').append('svg');
court.attr('width', 480)
.attr('height', 480/50*47)
court.append('table');
var heat_g = court.append('g')
var court_g = court.append('g');
var title = d3.select(document.getElementById('caption')).append('text');
// var data_g = d3.select(chartDiv).append('shot').append('svg')
var slider_axis = court.append('g')
.attr('class', 'slider-axis');
var slider_rect = court.append('g')
.attr('class', 'slider-rect');
var rect_entity = slider_rect.append('rect');
const court_xScale = d3.scaleLinear()
.domain([-25, 25]);
const court_yScale = d3.scaleLinear()
.domain([-4,43]);
const shot_xScale = d3.scaleLinear()
.domain([-250, 250]);
const shot_yScale = d3.scaleLinear()
.domain([-45,420]);
var color = d3.scaleSequential(d3.interpolateOrRd)
.domain([5e-6, 3e-2]); // Points per square pixel.
var Basket = court_g.append('circle');
var Backboard = court_g.append('rect');
var Outterbox = court_g.append('rect');
var Innerbox = court_g.append('rect');
var CornerThreeLeft = court_g.append('rect');
var CornerThreeRight = court_g.append('rect');
var OuterLine = court_g.append('rect');
var RestrictedArea = court_g.append('path')
var TopFreeThrow = court_g.append('path')
var BottomFreeThrow = court_g.append('path')
var ThreeLine = court_g.append('path')
var CenterOuter = court_g.append('path')
var CenterInner = court_g.append('path')
draw_court();
// add_shot();
Slider();
// window.addEventListener('resize', draw_court);
// window.addEventListener('resize', Slider);
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js
https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.min.js
https://d3js.org/d3-contour.v1.min.js
https://d3js.org/d3-scale-chromatic.v1.min.js