Published
Edited
Oct 29, 2020
Insert cell
d3 = require('d3@6')
Insert cell
Insert cell
html`
<table class="my-document">
<tr>
<td><span><p>1</p></span>
<span><p>2</p></span>
<span><p>3</p></span>
<span><p>4</p></span></td>
<td><span><p>5</p></span>
<span><p>6</p></span>
<span><p>7</p></span>
<span><p>8</p></span></td>
<td><span><p>9</p></span>
<span><p>10</p></span>
<span><p>11</p></span>
<span><p>12</p></span></td>
<td><span><p>13</p></span>
<span><p>14</p></span>
<span><p>15</p></span>
<span><p>16</p></span></td>
</tr>
</table>
`
Insert cell
Insert cell
d3.select('table.my-document').select('tr').selectAll('p')
Insert cell
d3.select('table.my-document').select('tr').selectAll('td').selectAll('p')
Insert cell
d3.select('table.my-document').select('tr').selectAll('td').selectAll('span').selectAll('p')
Insert cell
Insert cell
Insert cell
d3.select('table.my-document').select('tr').selectAll('p').text((datum, idx) => idx * 2)
Insert cell
Insert cell
d3.select('table.my-document').select('tr').selectAll('td').selectAll('p').text((datum, idx) => idx * 2)
Insert cell
Insert cell
d3.select('table.my-document').select('tr').selectAll('td').selectAll('span').selectAll('p').text((datum, idx) => idx * 2)
Insert cell
Insert cell
Insert cell
{
// Create initial svg canvas, width is provided by observable notebook
// `` is templated string in javascript ES6
// https://github.com/observablehq/stdlib
const svg = d3.create('svg')
.attr('width', width)
.attr('height', 33)
.attr('viewBox', `0 -25 ${width} 33`);
svg.selectAll('text')
.data([1,2,3,4,5,6,7,8])
return svg.node();
}
Insert cell
{
const svg = d3.create('svg')
.attr('width', width)
.attr('height', 33)
.attr('viewBox', `0 -25 ${width} 33`);
svg.selectAll('text')
.data([1,2,3,4,5,6,7,8])
.enter()
// create new <text> nodes for each data element in the enter set to bind to
.append('text')
// svg x coordinate for each letter (<text> node)
.attr('x', (dat, idx) => idx * 16)
// set text content for each letter (<text> node)
// integer `dat` will be auto transformed to strings
.text(dat => dat)
return svg.node();
}
Insert cell
Insert cell
{
const svg = d3.create('svg')
.attr('width', width)
.attr('height', 33)
.attr('viewBox', `0 -25 ${width} 33`);
svg.selectAll('text')
.data([1,2,3,4,5,6,7,8])
.enter()
.append('text')
.attr('x', (dat, idx) => idx * 16)
.text(dat => dat)
svg.selectAll('text')
.data([-1,-2,-3,-4,-5,-6,-7,-8])
return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
baseSVG = {
const svg = d3.create('svg')
.attr('width', width)
.attr('height', 33)
.attr('viewBox', `0 -25 ${width} 33`);
svg.selectAll('text')
.data([1,2,3,4,5,6,7,8])
.enter()
.append('text')
.attr('x', (dat, idx) => idx * 16)
.text(dat => dat)
return svg;
}
Insert cell
Insert cell
Insert cell
sel = baseSVG.selectAll('text')
.data([4,5,6,7,8,9,10,11])
Insert cell
sel.size()
Insert cell
sel.exit().size()
Insert cell
sel.enter().size()
Insert cell
Insert cell
baseSVGLarger = {
const svg = d3.create('svg')
.attr('width', width)
.attr('height', 33)
.attr('viewBox', `0 -25 ${width} 33`);
svg.selectAll('text')
.data([1,2,3,4,5,6,7,8])
.enter()
.append('text')
.attr('x', (dat, idx) => idx * 16)
.text(dat => dat)
return svg;
}
Insert cell
selLarger = baseSVGLarger.selectAll('text')
.data([4,5,6,7,8,9,10,11,12,13,14])
Insert cell
Insert cell
selLarger.size()
Insert cell
selLarger.data()
Insert cell
selLarger.enter().size()
Insert cell
selLarger.enter().data()
Insert cell
selLarger.exit().size()
Insert cell
Insert cell
baseSVGSmaller = {
const svg = d3.create('svg')
.attr('width', width)
.attr('height', 33)
.attr('viewBox', `0 -25 ${width} 33`);
svg.selectAll('text')
.data([1,2,3,4,5,6,7,8])
.enter()
.append('text')
.attr('x', (dat, idx) => idx * 16)
.text(dat => dat)
return svg;
}
Insert cell
selSmaller = baseSVGSmaller.selectAll('text')
.data([-1,-2,-3,-4,-5])
Insert cell
Insert cell
selSmaller.size()
Insert cell
selSmaller.data()
Insert cell
selSmaller.enter().size()
Insert cell
selSmaller.exit().size()
Insert cell
selSmaller.exit().data()
Insert cell
Insert cell
baseSVGRemap = {
const svg = d3.create('svg')
.attr('width', width)
.attr('height', 33)
.attr('viewBox', `0 -25 ${width} 33`);
svg.selectAll('text')
.data([1,2,3,4,5,6,7,8])
.enter()
.append('text')
.attr('id', (dat, idx) => idx + 1)
.attr('x', (dat, idx) => idx * 16)
.text(dat => dat)
return svg;
}
Insert cell
Insert cell
baseSVGRemap.html()
Insert cell
Insert cell
selRemap = baseSVGRemap.selectAll('text')
.data([1,12,13,14,15,16,17,18],
function (dat) { return this.id || dat; })
Insert cell
Insert cell
selRemap2 = baseSVGRemap.selectAll('text')
.data([1,12,13,14,15,16,17,18],
dat => dat)
Insert cell
Insert cell
selRemap.enter().data()
Insert cell
selRemap.exit().data()
Insert cell
selRemap.data()
Insert cell
selRemap.attr('id')
Insert cell
Insert cell
{
const svg = d3.create('svg')
.attr('width', width)
.attr('height', 33)
.attr('viewBox', `0 -25 ${width} 33`);
svg.selectAll('text')
.data([1,2,3,4,5,6,7,8])
.enter()
.append('text')
.attr('x', (dat, idx) => idx * 16)
.text(dat => dat)
yield svg.node()
// execute after 2 seconds
setTimeout(function () {
const sel = svg.selectAll('text').data([-1,-2,-3,-4,-5,-6,-7,-8,-9,-10]);
// set color to green for update set
sel.attr('fill', 'green').text(d => d);
sel.enter().append('text').attr('x', (d, i) => i * 16).text(d => d);
// no exit set here so not specified
}, 2000)
}
Insert cell
Insert cell
{
const svg = d3.create('svg')
.attr('width', width)
.attr('height', 33)
.attr('viewBox', `0 -25 ${width} 33`);
svg.selectAll('text')
.data([1,2,3,4,5,6,7,8])
.enter()
.append('text')
.attr('x', (dat, idx) => idx * 16)
.text(dat => dat)
yield svg.node()
// execute after 2 seconds
setTimeout(function () {
svg.selectAll('text')
.data([-1,-2,-3,-4,-5,-6,-7,-8,-9,-10])
.join(
enter => enter.append('text').attr('x', (d, i) => i * 16).text(d => d),
update => update.attr('fill', 'green').text(d => d)
// no exit set here so not specified
);
}, 2000)
}
Insert cell
Insert cell
{
const svg = d3.create('svg')
.attr('width', width)
.attr('height', 33)
.attr('viewBox', `0 -25 ${width} 33`);
svg.selectAll('text')
.data([1,2,3,4,5,6,7,8])
.enter()
.append('text')
.attr('x', (dat, idx) => idx * 16)
.text(dat => dat)
yield svg.node()
// execute after 2 seconds
// We cannot only color the update set as green in this case
setTimeout(function () {
svg.selectAll('text')
.data([-1,-2,-3,-4,-5,-6,-7,-8,-9,-10])
.join('text')
.attr('x', (d, i) => i * 16)
.text(d => d);
}, 2000)
}
Insert cell
Insert cell
html`
<table class="my-document2">
<tr>
<td><span><p>1</p></span>
<span><p>2</p></span>
<span><p>3</p></span>
<span><p>4</p></span></td>
<td><span><p>5</p></span>
<span><p>6</p></span>
<span><p>7</p></span>
<span><p>8</p></span></td>
</tr>
</table>
`
Insert cell
d3.select('table.my-document2')
.selectAll('td')
.selectAll('p')
.data([8, 7, 6, 5, 4, 3, 2, 1]) // wrong
.text(d => d)
Insert cell
d3.select('table.my-document2')
.selectAll('td')
.selectAll('p')
.data([[8, 7, 6, 5], [4, 3, 2, 1]]) // also wrong
.text(d => d)
Insert cell
d3.select('table.my-document2')
.selectAll('td')
.data([[8, 7, 6, 5], [4, 3, 2, 1]]) // correct
.selectAll('p')
.data(d => d) // will split array eg: [8, 7, 6, 5] and assign each sub datum
.text(d => d)
Insert cell
d3.select('table.my-document2')
.selectAll('td')
.data([[8, 7, 6, 5], [4, 3, 2, 1]]) // correct
.selectAll('p')
.data(d => d, (d, i) => i) // key unique for each group, i is 0~3 for two groups
.text(d => d)
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