Public
Edited
Mar 10
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const margin = { top: 10, right: 30, bottom: 20, left: 40 };
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})`);
const x = d3.scaleTime()
.domain([minStockDate, maxStockDate])
.range([0, visWidth]);
const y = d3.scaleLinear()
.domain([0, maxPrice]).nice()
.range([visHeight, 0]);
const xAxis = d3.axisBottom(x);
const yAxis = d3.axisLeft(y);
g.append('g')
.attr('transform', `translate(0,${visHeight})`)
.call(xAxis);
g.append('g')
.call(yAxis)
.call(g => g.selectAll('.domain').remove())
.append('text')
.attr('text-anchor', 'start')
.attr('dominant-baseline', 'middle')
.attr('fill', 'black')
.attr('x', 5)
.text('Stock Price ($)');
const line = d3.line()
.x(d => x(d.date))
.y(d => y(d.price));

const colorScale = d3.scaleOrdinal(d3.schemeCategory10);

const series = g.selectAll('.series')
.data(companyToPrices)
.join('g')
.attr('class', 'series')
.append('path')
.datum(([company, prices], i) => prices)
.attr('fill', 'none')
.attr('stroke', ([company, prices], i) => colorScale(i))
.attr('stroke-width', 1.5)
.attr('d', line);
return svg.node();
}

Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const margin = {top: 20, right: 10, bottom: 10, left: 30};
const visWidth = width - margin.left - margin.right;

const x = d3.scaleBand()
.domain(d3.range(53))
.range([0, visWidth])
.padding(0.05);

const visHeight = x.step() * 7;

const svg = d3.select(DOM.svg(visWidth + margin.left + margin.right,
visHeight + margin.top + margin.bottom));

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

const y = d3.scaleBand()
.domain(['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'])
.range([0, visHeight])
.padding(0.05);

const yAxis = d3.axisLeft(y)
.tickPadding(10)
.tickSize(0);

g.append('g')
.call(yAxis)
.call(g => g.selectAll('.domain').remove());

const firstOfMonths = weather.filter(d => d.date.getDate() === 1);

g.selectAll('.month')
.data(firstOfMonths)
.join('text')
.attr('class', 'month')
.attr('font-family', 'sans-serif')
.attr('font-size', 10)
.attr('x', d => x(d.week))
.attr('y', -5)
.text(d => d3.timeFormat('%b')(d.date));

const colorScale = d3.scaleSequentialQuantile(d3.range(100).map(() => Math.random() ** 2), d3.interpolateBlues);

g.selectAll('rect')
.data(weather)
.join('rect')
.attr('x', d => x(d.week))
.attr('y', d => y(d.day))
.attr('width', x.bandwidth())
.attr('height', y.bandwidth())
.attr('fill', d => colorScale(d.precipitation));

const legend = g.append('g')
.attr('transform', `translate(${visWidth + margin.left + 10}, 0)`);

const legendScale = d3.scaleSequentialQuantile(d3.range(100).map(() => Math.random() ** 2), d3.interpolateBlues);

const legendAxis = d3.axisRight(legendScale)
.ticks(9)
.tickFormat(d3.format(".2f"));

legend.append('g')
.call(legendAxis);

return svg.node();
}

Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const margin = { top: 0, right: 0, bottom: 0, left: 0 };
const visWidth = 600 - margin.left - margin.right;
const visHeight = 400 - 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})`);

const colorScale = d3.scaleSequential(d3.interpolateRdBu)
.domain([percentChangeExtent[0], percentChangeExtent[1]]);

const projection = d3.geoAlbersUsa()
.fitSize([visWidth, visHeight], usaGeo);

const path = d3.geoPath().projection(projection);

const getChangeForState = (stateName) => {
const stateData = stateToPopulation[stateName];
return stateData ? stateData.change : 0;
};

g.selectAll('.state')
.data(usaGeo.features.filter(d => d.properties.NAME !== 'Puerto Rico'))
.join('path')
.attr('class', 'state')
.attr('d', path)
.attr('fill', d => {
const change = getChangeForState(d.properties.NAME);
return colorScale(change);
})
.attr('stroke', 'white');

return svg.node();
}

Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const margin = {top: 0, right: 0, bottom: 0, left: 0};
const visWidth = 600 - margin.left - margin.right;
const visHeight = 400 - 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})`);
const colorScale = d3.scaleQuantize()
.domain([d3.min(populations, d => d.change), d3.max(populations, d => d.change)])
.range(d3.schemeBlues[5]);

const projection = d3.geoAlbersUsa()
.fitSize([visWidth, visHeight], usaGeo);

const path = d3.geoPath().projection(projection);

g.selectAll('.state')
.data(usaGeo.features)
.join('path')
.attr('class', 'state')
.attr('d', path)
.attr('fill', function(d) {
const state = d.properties.NAME;
const population = stateToPopulation[state] ? stateToPopulation[state].change : 0;
return colorScale(population);
})
.attr('stroke', 'white');

g.selectAll('.border')
.data(usaGeo.features.filter(d => d.properties.NAME !== 'Puerto Rico'))
.join('path')
.attr('class', 'border')
.attr('d', path)
.attr('fill', 'none')
.attr('stroke', 'white');

return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const margin = {top: 10, right: 100, bottom: 20, left: 40};
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})`);
const x = d3.scaleTime()
.domain([minYear, maxYear])
.range([0, visWidth]);
const y = d3.scaleLinear()
.domain([0, maxLifeExpect]).nice()
.range([visHeight, 0]);
const xAxis = d3.axisBottom(x);
const yAxis = d3.axisLeft(y);
g.append('g')
.attr('transform', `translate(0,${visHeight})`)
.call(xAxis);
g.append('g')
.call(yAxis)
.call(g => g.selectAll('.domain').remove())
.append('text')
.attr('text-anchor', 'start')
.attr('dominant-baseline', 'middle')
.attr('fill', 'black')
.attr('x', 5)
.text('Life Expectancy');
const line = d3.line()
.x(d => x(d.year))
.y(d => y(d.life_expect));

const series = g.selectAll('.series')
.data(Array.from(countryToLifeExpectancies.entries()))
.join('g')
.attr('class', 'series')
.attr('stroke', ([country, info]) => highlightCountries.includes(country) ? 'red' : 'grey')
.attr('stroke-width', 1)
.append('path')
.datum(([country, info]) => info)
.attr('fill', 'none')
.attr('d', line);
g.selectAll('.country-label')
.data(labelPoints)
.join('text')
.attr('class', 'country-label')
.attr('x', d => x(d.year) + 2)
.attr('y', d => y(d.life_expect))
.attr('font-size', 10)
.attr('font-family', 'sans-serif')
.attr('dominant-baseline', 'middle')
.text(d => d.country);
return svg.node();
}

Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const margin = {top: 10, right: 120, bottom: 50, left: 100}; // increased right margin for the legend
const visWidth = 510 - margin.left - margin.right;
const visHeight = 460 - 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})`);

const x = d3.scaleLinear()
.domain(d3.extent(cars, d => d.horsepower)).nice()
.range([0, visWidth]);

const y = d3.scaleLinear()
.domain(d3.extent(cars, d => d.weight)).nice()
.range([visHeight, 0]);

const xAxis = d3.axisBottom(x);

g.append("g")
.attr('transform', `translate(0, ${visHeight})`)
.call(xAxis)
.call(g => g.selectAll('.domain').remove())
.append('text')
.attr('x', visWidth / 2)
.attr('y', 40)
.attr('fill', 'black')
.attr('text-anchor', 'middle')
.text('horsepower');

const yAxis = d3.axisLeft(y);

g.append('g')
.call(yAxis)
.call(g => g.selectAll('.domain').remove())
.append('text')
.attr('x', -40)
.attr('y', visHeight / 2)
.attr('fill', 'black')
.attr('dominant-baseline', 'middle')
.text('weight (lbs)');

const grid = g.append('g')
.attr('class', 'grid');

grid.append('g')
.selectAll('line')
.data(y.ticks())
.join('line')
.attr('stroke', 'lightgray')
.attr('x1', 0)
.attr('x2', visWidth)
.attr('y1', d => 0.5 + y(d))
.attr('y2', d => 0.5 + y(d));

grid.append('g')
.selectAll('line')
.data(x.ticks())
.join('line')
.attr('stroke', 'lightgray')
.attr('x1', d => 0.5 + x(d))
.attr('x2', d => 0.5 + x(d))
.attr('y1', d => 0)
.attr('y2', d => visHeight);

const colorScale = {
"USA": "blue",
"Europe": "green",
"Japan": "red"
};

g.selectAll('circle')
.data(cars)
.join('circle')
.attr('cx', d => x(d.horsepower))
.attr('cy', d => y(d.weight))
.attr('fill', d => colorScale[d.origin])
.attr('opacity', 1)
.attr('r', 3);

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

const legendData = [
{ origin: 'USA', color: 'blue' },
{ origin: 'Europe', color: 'green' },
{ origin: 'Japan', color: 'red' }
];

legendData.forEach((d, i) => {
const legendItem = legend.append('g')
.attr('transform', `translate(0, ${i * 20})`);

legendItem.append('rect')
.attr('width', 15)
.attr('height', 15)
.attr('fill', d.color);

legendItem.append('text')
.attr('x', 20)
.attr('y', 12)
.attr('fill', 'black')
.text(d.origin);
});

return svg.node();

}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more