Unlisted
Edited
May 19
Importers
Insert cell
Insert cell
Insert cell
{
const svg = d3.create('svg')
.attr('width', width)
.attr('height', '100px');

for (const x of [50, 150, 250, 350, 450]) {
svg.append('circle')
.attr('cx', x)
.attr('cy', 50)
.attr('r', 25)
}

return svg.node()
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
// Start by creating the svg container as usual.
const svg = d3.create('svg')
.attr('width', width)
.attr('height', 50);

// Draw a circle per data point.
svg.selectAll('circle') // <-- Select all circles in the SVG; these circles may or may not exist yet.
.data(csEnrollmentData) // <-- After this step, the circles that follow are drawn per data point
.join('circle') // <-- Loop over the provided data and draw circles for each record
.attr('cx', 25)
.attr('cy', 25)
.attr('r', 5);

return svg.node();
}
Insert cell
Insert cell
{
// Code here.
// Set the circle's cx attributes according to their position in the list
const svg = d3.create('svg')
.attr('width', width)
.attr('height', 50);

// Draw a circle per data point.
svg.selectAll('circle') // <-- Select all circles in the SVG; these circles may or may not exist yet.
.data(csEnrollmentData) // <-- After this step, the circles that follow are drawn per data point
.join('circle') // <-- Loop over the provided data and draw circles for each record
.attr('cx', (d, i) => i * 25)
.attr('cy', 25)
.attr('r', 5);

return svg.node();
}
Insert cell
Insert cell
Insert cell
function scaleWidth(index) {
return Math.floor(
(index / (csEnrollmentData.length)) * width
);
}
Insert cell
Insert cell
{
// Code here
// Use the `scaleWidth` function to determine each circle's "cx" position
const svg = d3.create('svg')
.attr('width', width)
.attr('height', 50);

// Draw a circle per data point.
svg.selectAll('circle') // <-- Select all circles in the SVG; these circles may or may not exist yet.
.data(csEnrollmentData) // <-- After this step, the circles that follow are drawn per data point
.join('circle') // <-- Loop over the provided data and draw circles for each record
.attr('cx', d => x(d.county))
.attr('cy', 25)
.attr('r', 5);

return svg.node();
}
Insert cell
Insert cell
// Code here
x = d3.scaleBand() // Construct a band scale using d3.scaleBand
.domain(csEnrollmentData.map(d => d.county)) // Set its domain to the list of county names
.range([0, width]) // Set its range to the range of possible horizontal pixel values
Insert cell
x('San Luis Obispo')
Insert cell
Insert cell
Insert cell
y = d3.scaleLinear()
// 👇🏽 We don't want our y axis to start at the min income; we want to start at 0
.domain([0, d3.max(csEnrollmentData, d => d.ami)])
.range([0, 300]); // <-- Our figure will be 300 pixels tall
Insert cell
Insert cell
Insert cell
{
// Start by creating the svg container as usual.
const svg = d3.create('svg')
.attr('width', width)
.attr('height', 300); // <-- Increased the size of our SVG area

// Draw a rectangle per data point.
svg.selectAll('rect')
.data(csEnrollmentData)
.join('rect')
.attr('x', d => x(d.county)) // <-- set the x position based on the band scale
.attr('y', d => y(d.ami)) // <-- set the y position based on the linear scale
.attr('width', x.bandwidth() - 2) // <-- The band scale can tell us how wide each band should be. We leave 2 pixels between bars.
.attr('height', d => y(d.ami)) // <-- set the bar height based on the linear scale
return svg.node()
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
yInv = d3.scaleLinear()
.domain([0, d3.max(csEnrollmentData, d => d.ami)])
.range([300, 0]);
Insert cell
Insert cell
{
const height = 300;
// Start by creating the svg container as usual.
const svg = d3.create('svg')
.attr('width', width)
.attr('height', height);

// Draw a rectangle per data point.
svg.selectAll('rect')
.data(csEnrollmentData)
.join('rect')
.attr('x', d => x(d.county))
.attr('y', d => yInv(d.ami)) // <-- set the y position based on the linear scale, which is now inverted
.attr('height', d => yInv(0) - yInv(d.ami)) // <-- set the bar height so that each bar extends downward to the baseline
.attr('width', x.bandwidth() - 2)
return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const height = 300;

// x scale
const x = d3.scaleBand()
.domain(csEnrollmentData.map(d => d.county))
.range([margin.left, width - margin.right]); // <-- New! Use the margins for the range.

// y scale
const y = d3.scaleLinear()
.domain([0, d3.max(csEnrollmentData, d => d.ami)])
.range([height - margin.bottom, margin.top]); // <-- New! Use the margins for the range.

// Create the svg container as usual.
const svg = d3.create('svg')
.attr('width', width)
.attr('height', height)
.style('border', '1pt grey dashed');

// Draw a rectangle per data point.
svg.selectAll('rect')
.data(csEnrollmentData)
.join('rect')
.attr('x', d => x(d.county))
.attr('y', d => y(d.ami)) // <-- set the y position based on the linear scale, which is now inverted
.attr('height', d => y(0) - y(d.ami)) // <-- set the bar height so that each bar extends downward to the baseline
.attr('width', x.bandwidth() - 2);
return svg.node();
}
Insert cell
Insert cell
{
const height = 300;

// Start by creating the svg container as usual.
const svg = d3.create('svg')
.attr('width', width)
.attr('height', height)
.style('border', '1pt grey dashed');

// x scale
const x = d3.scaleBand()
.domain(csEnrollmentData.map(d => d.county)) // Domain stays the same
.range([margin.left, width - margin.right]);

// y scale
const y = d3.scaleLinear()
.domain([0, d3.max(csEnrollmentData, d => d.ami)])
.range([height - margin.bottom, margin.top])
.nice();

svg.append('g')
.attr('transform', `translate(${margin.left}, 0)`)
.call(d3.axisLeft(y).tickFormat(d3.format('$~s')));

svg.append('g')
.attr('transform', `translate(0, ${height - margin.bottom})`)
.call(d3.axisBottom(x)) // Calling axisBottom returns the axis selection.
.selectAll('text') // That selection includes text (the county names).
.attr('transform', 'rotate(-90)') // Rotate county names by -90º.
.attr('text-anchor', 'end') // Positioning should be done based on the end of the text.
.attr('y', 0) // After rotating, changing y position will move the text horizontally.
.attr('dy', '0.35em') // Control jitter from rotating the viewport for each text element.
.attr('x', 0) // After rotating, changing x position will move the text vertically.
.attr('dx', '-9'); // Control jitter from rotating the viewport for each text element.
return svg.node();
}
Insert cell
Insert cell
<svg width=300 height=200 style='border: 1pt black solid;'>
<line x1=0 y1=100 x2=300 y2=100 stroke='lightgrey' /> <!-- Axis line -->
<g transform='translate(150, 100)'>
<line x1=0 y1=0 x2=0 y2=10 stroke='grey' /> <!-- Axis tick -->
<text x=0 y=0 style='font: 10pt sans-serif;' transform='rotate(-90)' text-anchor='end'>San Luis Obispo</text> <!-- County name label -->
</g>
</svg>
Insert cell
Insert cell
Insert cell
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