Public
Edited
Jan 5
2 forks
Importers
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
netRatingDomain = {
const extent = d3.extent(draftPicks, player => player.net_rating);
return extent;
}
Insert cell
activePlayerNetRatingColor = d3.scaleSequential()
.domain(netRatingDomain)
.interpolator(d3.interpolateGreens)
Insert cell
nonActivePlayerColor = d3.scaleOrdinal()
.domain(['< 25% games played', 'inactive'])
.range(['red', 'white'])
Insert cell
Insert cell
{
// dimensions and set up

const margin = {top: 0, right: 0, bottom: 40, left: 80};

const maxWidth = width;
const maxHeight = 500;

const numCols = draftNumbers.length;
const numRows = draftYears.length;

// calculate the maximum size that a cell can be
const cellSize = Math.min(
(maxWidth - margin.left - margin.right) / numCols,
(maxHeight - margin.top - margin.bottom) / numRows
);

const visWidth = cellSize * numCols;
const visHeight = cellSize * numRows;
const svg = d3.create('svg')
.attr('width', visWidth + margin.left + margin.right)
.attr('height', visHeight + margin.top + margin.bottom);

const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);

// scales

const x = d3.scaleBand()
.domain(draftNumbers)
.range([0, visWidth])
// space betwen columns
.padding(0.05);

const y = d3.scaleBand()
.domain(draftYears)
.range([visHeight, 0])
// space between rows
.padding(0.6);

// axis generators

const xAxis = d3.axisBottom(x).tickSize(0);
const yAxis = d3.axisLeft(y).tickSize(0);

// draw axes

// x-axis

g.append('g')
.attr('transform', `translate(0,${visHeight})`)
.call(xAxis)
.call(g => g.select('.domain').remove())
// axis label
.append('text')
.attr('x', visWidth / 2)
.attr('y', 30)
.attr('fill', 'black')
.attr('text-anchor', 'center')
.text('draft position');

// y-axis
g.append('g')
.call(yAxis)
.call(g => g.select('.domain').remove())
// axis label
.append('text')
.attr('x', -35)
.attr('y', visHeight / 2)
.attr('fill', 'black')
.attr('dominant-baseline', 'center')
.attr('text-anchor', 'end')
.text('draft year');

// draw squares

// create one group for each cell
const cells = g.append('g')
.selectAll('g')
.data(draftPicks)
.join('g')
// move the cell into its position
.attr('transform', d => `translate(${x(d.number)},${y(d.year)})`);

// add rectangle to each cell
cells.append('rect')
.attr('width', x.bandwidth())
.attr('height', y.bandwidth())
.attr('fill', d => {
// the color scale that we use depends on whether or not the
// player is active
if (d.type === 'active') {
return activePlayerNetRatingColor(d.net_rating);
} else {
return nonActivePlayerColor(d.type);
}
})
// out of curiosity, add tooltip
.append('title')
.text(d => d.name);

// add text label to each cell
cells.filter(d => d.type === 'active')
.append('text')
.attr('dominant-baseline', 'middle')
.attr('text-anchor', 'middle')
.attr('x', x.bandwidth() / 2)
.attr('y', y.bandwidth() / 2)
.attr('font-size', 9)
.attr('font-weight', 'bold')
.attr('font-family', 'sans-serif')
// use white labels on dark cells and black labels on light cells
.attr('fill', d => d3.hcl(activePlayerNetRatingColor(d.net_rating)).l < 60 ? 'white' : 'black')
.text(d => d.net_rating)

return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
lineColor = d3.scaleOrdinal()
.domain(types)
.range(['Moccasin', 'blue'])
Insert cell
Insert cell
{
// set up
const margin = {top: 10, right: 10, bottom: 20, left: 20};

const visWidth = 300 - margin.left - margin.right;
const visHeight = 600 - margin.top - margin.bottom;

const svg = d3.create('svg')
.attr('width', visWidth + margin.left + margin.right)
.attr('height', visHeight + margin.top + margin.bottom);

const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);

// scales

const x = d3.scaleTime()
.domain(monthExtent)
.range([0, visWidth]);

const y = d3.scaleLinear()
.domain([0, maxCount])
.range([visHeight, 0]);

// line generator

const line = d3.line()
.x(d => x(d.month))
.y(d => y(d.count));

// axes

const xAxis = d3.axisBottom(x);
const yAxis = d3.axisLeft(y);

// draw lines

g.append('g')
.selectAll('path')
.data(titlesAddedByMonth)
.join('path')
.attr('d', d => line(d.counts))
.attr('fill', 'none')
.attr('stroke', d => lineColor(d.type))
.attr('stroke-width', 2);

// draw axes and grids

// x-axis and verical grid lines
g.append('g')
.attr('transform', `translate(0,${visHeight})`)
.call(xAxis)
.call(
// clone the axis tick marks to create the grid lines
g => g.selectAll('.tick > line').clone()
.attr('y1', 0)
.attr('y2', -visHeight)
.attr('stroke', 'black')
.attr('stroke-width', 1)
)

// y-axis and horizontal grid lines
g.append('g')
.call(yAxis)
.call(
// clone the axis tick marks to create the grid lines
g => g.selectAll('.tick > line')
// skip the first tick mark, since that's the baseline
// of the x-axis
.filter((d, i) => i !== 0).clone()
.attr('x1', 0)
.attr('x2', visWidth)
.attr('stroke', 'black')
.attr('stroke-width', 1)
)

return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
// set up
const margin = {top: 10, right: 10, bottom: 20, left: 50};

const visWidth = width - margin.left - margin.right;
const visHeight = 500 - margin.top - margin.bottom;

const svg = d3.create('svg')
.attr('width', visWidth + margin.left + margin.right)
.attr('height', visHeight + margin.top + margin.bottom);

const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);

// scales

const x = d3.scaleLinear()
.domain([0, d3.max(topActors, d => d.total)])
.range([0, visWidth]);

const y = d3.scaleBand()
.domain(topActors.map(d => d.name).sort())
.range([0, visHeight]);

// axes

const xAxis = d3.axisBottom(x);
const yAxis = d3.axisLeft(y);

// draw bars

const layers = g.append('g')
.selectAll('g')
.data(stacked)
.join('g')
.attr('fill', d => typeColor(d.key));

layers.selectAll('rect')
.data(d => d)
.join('rect')
.attr('x', d => x(d[0]))
.attr('width', d => x(d[1]) - x(d[0]))
.attr('y', d => y(d.data.name))
.attr('height', y.bandwidth());

// draw axes

// x-axis
g.append('g')
.attr('transform', `translate(0,${visHeight})`)
.call(xAxis);

// y-axis
g.append('g')
.call(yAxis);

return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more