Skip to main content

Selections & Data Binding

Core D3.js patterns for selecting elements and binding data.

Selections

Single Element Selection

// Select by tag
d3.select('body');

// Select by ID
d3.select('#myId');

// Select by class
d3.select('.myClass');

// Select by attribute
d3.select("[data-id='123']");

Multiple Element Selection

// Select all paragraphs
d3.selectAll('p');

// Select all elements with class
d3.selectAll('.item');

// Select nested elements
d3.select('body').selectAll('div');

Method Chaining

d3.select('body')
.append('svg')
.attr('width', 500)
.attr('height', 300)
.style('border', '1px solid black');

Data Binding

Basic Data Join

const data = [10, 20, 30, 40, 50];

d3.select('body')
.selectAll('div')
.data(data)
.join('div')
.text(d => `Value: ${d}`);

Enter/Update/Exit Pattern (Classic)

const data = [10, 20, 30, 40, 50];

const update = d3.select('ul').selectAll('li').data(data);

// Enter: Add new elements
update
.enter()
.append('li')
.text(d => d);

// Update: Modify existing elements
update.text(d => d);

// Exit: Remove old elements
update.exit().remove();

Modern Join Syntax (D3 v5+)

d3.select('ul')
.selectAll('li')
.data(data)
.join(
enter =>
enter
.append('li')
.text(d => d)
.style('color', 'green'),
update => update.text(d => d).style('color', 'blue'),
exit => exit.style('color', 'red').transition().duration(500).remove()
);

Data Join with Key Function

const data = [
{ id: 1, value: 10 },
{ id: 2, value: 20 },
{ id: 3, value: 30 },
];

d3.select('body')
.selectAll('div')
.data(data, d => d.id) // Key function
.join('div')
.text(d => `ID: ${d.id}, Value: ${d.value}`);

Element Manipulation

Creating Elements

// Append new elements
selection.append('div');
selection.append('svg');
selection.append('circle');

// Insert elements
selection.insert('div', ':first-child');

Setting Attributes

// Set single attribute
selection.attr('width', 500);

// Set attribute with function
selection.attr('width', (d, i) => d.width);

// Set multiple attributes
selection.attr('width', 500).attr('height', 300).attr('fill', 'blue');

Setting Styles

// Set single style
selection.style('color', 'red');

// Set style with function
selection.style('font-size', d => `${d.size}px`);

// Set multiple styles
selection
.style('color', 'red')
.style('font-size', '14px')
.style('margin', '10px');

Setting Properties

// Set property
selection.property('checked', true);
selection.property('value', 'Hello');

// Get property
const value = selection.property('value');

Setting Text and HTML

// Set text content
selection.text('Hello World');
selection.text(d => `Value: ${d}`);

// Set HTML content
selection.html('<strong>Bold Text</strong>');
selection.html(d => `<em>${d.name}</em>`);

Event Handling

// Add event listeners
selection.on('click', function (event, d) {
console.log('Clicked:', d);
console.log('Element:', this);
});

selection.on('mouseover', (event, d) => {
d3.select(event.currentTarget).style('fill', 'red');
});

// Remove event listener
selection.on('click', null);

Common Patterns

Conditional Attributes

selection
.attr('fill', d => (d.value > 50 ? 'red' : 'blue'))
.classed('highlight', d => d.important);

Nested Selections

const rows = d3.select('table').selectAll('tr').data(data);

const cells = rows.selectAll('td').data(d => d.values);