Published
Edited
Nov 22, 2019
1 star
Insert cell
Insert cell
{
const body = html`<body></body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

d3.select(body)
.append("table")
.selectAll("tr")
.data(matrix)
.join("tr")
.selectAll("td")
.data(d => d)
// .data()
.join("td")
.text(d => d);
return body
}
Insert cell
{
const body = html`<body></body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.append("table")
.selectAll("tr")
.data(matrix)
.join("tr")
.selectAll("td")
.data(d => d)
.join("td")
// .text(d => d);
// return body
}
Insert cell
{// check _groups, _enter, _exit
const body = html`<body>
<table>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
</table>
</body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

d3.select(body)
.append("table")
.selectAll("tr")
.data(matrix)
.join("tr") // no need to worry about whether elements exist or not
.selectAll("td")
.data(d => d)
.join("td")
.text(d => d);

return body
}
Insert cell
{// check _groups, _enter, _exit
const body = html`<body>
<table>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
</table>
</body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.append("table")
.selectAll("tr")
.data(matrix)
.join("tr") // no need to worry about whether elements exist or not
// .selectAll("td")
// .data(d => d)
// .join("td")
// .text(d => d);

// return body
}
Insert cell
Insert cell
match_rows_with_data = {// check _groups, _enter, _exit
const body = html`<body>
<table>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
</table>
</body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.selectAll("tr")
.data(matrix)
}
Insert cell
match_cell_with_data_but_no_cell_elements = {// check _groups, _enter, _exit
const body = html`<body>
<table>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
</table>
</body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.selectAll("tr") // preselect table rows
.data(matrix) // join data: enter selection is 4 empty, update selection is 4 full, exit selection is 4 empty
.selectAll("td") // preselect table data
.data(d => d) // bind data
}
Insert cell
{// check _groups, _enter, _exit
const body = html`<body>
<table>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
</table>
</body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.selectAll("tr") // preselect table rows
.data(matrix) // join data: enter selection is 4 empty, update selection is 4 full, exit selection is 4 empty
.selectAll("td") // preselect table data for each table row
.data(d => d) // bind data
.enter()
}
Insert cell
{// check _groups, _enter, _exit
const body = html`<body>
<table>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
</table>
</body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.selectAll("tr") // preselect table rows
.data(matrix) // join data: enter selection is 4 empty, update selection is 4 full, exit selection is 4 empty
.selectAll("td") // preselect table data for each table row
.data(d => d) // bind data
.enter()
.append("td")
}
Insert cell
data_with_full_elements_view = {// check _groups, _enter, _exit
const body = html`<body>
<table>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
</table>
</body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

// return d3.select(body)
d3.select(body)
.selectAll("tr") // preselect table rows
.data(matrix) // join data: enter selection is 4 empty, update selection is 4 full, exit selection is 4 empty
.selectAll("td") // preselect table data
.data(d => d) // bind data
.enter() // get enter selection
.append("td") // create table data element for each node
.text(d => d);

return body
}
Insert cell
Insert cell
{// check _groups, _enter, _exit
const body = html`<body></body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.append("table")
.selectAll("tr") // at this moment we don't know how many tr should be created
}
Insert cell
{// check _groups, _enter, _exit
const body = html`<body></body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.append("table")
.selectAll("tr")
.data(matrix)
}
Insert cell
{// check _groups, _enter, _exit
const body = html`<body></body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.append("table")
.selectAll("tr")
.data(matrix)
.enter()
}
Insert cell
{// check _groups, _enter, _exit
const body = html`<body></body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.append("table")
.selectAll("tr")
.data(matrix)
.enter()
.append("tr")
}
Insert cell
{// check _groups, _enter, _exit
const body = html`<body></body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.append("table")
.selectAll("tr")
.data(matrix)
.enter()
.append("tr")
.selectAll("td")
// .data(d => d)
// .enter()
// .append("td")
}
Insert cell
{// check _groups, _enter, _exit
const body = html`<body></body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.append("table")
.selectAll("tr")
.data(matrix)
.enter()
.append("tr")
.selectAll("td")
.data(d => d) // enter, exit and data binded
// .enter()
// .append("td")
}
Insert cell
{// check _groups, _enter, _exit
const body = html`<body></body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.append("table")
.selectAll("tr")
.data(matrix)
.enter()
.append("tr")
.selectAll("td")
.data(d => d) // enter, exit and data binded
.enter()
// .append("td")
}
Insert cell
{// check _groups, _enter, _exit
const body = html`<body></body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.append("table")
.selectAll("tr")
.data(matrix)
.enter()
.append("tr")
.selectAll("td")
.data(d => d) // enter, exit and data binded
.enter()
.append("td")
}
Insert cell
{// check _groups, _enter, _exit
const body = html`<body></body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

d3.select(body)
.append("table")
.selectAll("tr")
.data(matrix)
.enter()
.append("tr")
.selectAll("td")
.data(d => d)
.enter()
.append("td")
.text(d => d)
return body
}
Insert cell
data_with_partial_elements = { // check _groups, _enter, _exit
const body = html`<body>
<table>
<tr></tr>
<tr></tr>
<tr></tr>
</table>
</body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.selectAll("tr")
.data(matrix)
}
Insert cell
Insert cell
{
let c = html`
<div id="Ford"></div>
<div id="Jarrah"></div>
<div id="Kwon"></div>
<div id="Locke"></div>
<div id="Reyes"></div>
<div id="Shephard"></div>
`
const data = [
{name: "Locke", number: 4},
{name: "Reyes", number: 8},
{name: "Ford", number: 15},
{name: "Jarrah", number: 16},
{name: "Shephard", number: 23},
{name: "Kwon", number: 42}
];

d3.select(c).selectAll("div")
.data(data) // match first datum (name: "Locke") with first element (id="Ford")
.text(d => d.number);
return c
}
Insert cell
{
// starting with elements without old data (or with empty data), to be filled by new data
let c = html`
<div id="Ford"></div>
<div id="Jarrah"></div>
<div id="Kwon"></div>
<div id="Locke"></div>
<div id="Reyes"></div>
<div id="Shephard"></div>
`
const data = [
{name: "Locke", number: 4},
{name: "Reyes", number: 8},
{name: "Ford", number: 15},
{name: "Jarrah", number: 16},
{name: "Shephard", number: 23},
{name: "Kwon", number: 42}
];

d3.select(c).selectAll("div")
.data(data, function(d,i,nodes) {
console.log("d: ", d); // d for elements are undefined (actually datum is hidden in this.id) ; d for data are each datum
// console.log("this:", this); // this for elements is each element; this for data is all elements grouped inside a span
// console.log("i: ", i); // idx for elements; idx for data
// console.log("nodes: ", nodes); // for elements, nodes are all elements in an array; for data, nodes are all data
return d ? d.name : this.id; }) // return datum key "Locke", return element key "Locke", match them
.text(d => d.number);
return c
}
Insert cell
{ // check _groups, _enter, _exit
const body = html`<body>
<table>
<tr></tr>
<tr></tr>
<tr></tr>
</table>
</body>`
const matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];

return d3.select(body)
.selectAll("tr")
.data(matrix, (d) => {
console.log("d: ", d); // partial, elements have one less than data
return d;
})
}
Insert cell
Insert cell
dataCircle = [[{"x": 50, "y":100}, {"x": 100, "y":100}], [{"x": 50, "y":100}, {"x": 150, "y":100}]]
Insert cell
{
// starting without elements and old data
// later adding new data which overlap with old data
const c = html`
<svg width=width height=330></svg>
`
const svg = d3.select(c)
let idx = 0;
let count = 0;
while (count<2) {
const t = svg.transition()
.duration(2500);

svg.selectAll("circle")
.data(dataCircle[idx], (d, i, nodes) => {
// console.log("d: ", d);
// first run: no elements, no d to run, escape; d for data is each datum of dataSrc[0]
// second run: d for elements, each datum of the existing elements, meaning dataSrc[0]; d for data, is each datum of dataScr[1]
// console.log("this: ", this); // all undefined, surprising
// console.log("i: ", i);
// console.log("nodes: ", nodes);
// first run: no elements, no nodes, escape; nodes for data is all data created
return d;})
.join(
enter => enter.append("circle")
.attr("fill", "green")
.attr("cx", (d) => d.x)
.attr("cy", (d) => d.y)
.attr("r", 0)
// .text(d => d)
.call(enter => enter.transition(t)
.attr("r", 10)),
update => update
.attr("fill", "blue")
.attr("opacity", 0)
.call(update => update.transition(t)
.attr("opacity", 0.5)),
exit => exit
.call(exit => exit.transition(t)
.attr("fill", "red")
.attr("r", 0)
.remove())
);

yield svg.node();
await Promises.tick(2500);
idx = (idx === 0) ? 1 : 0;
count++;
}
}
Insert cell
Insert cell
{
const body = html`<div></div>`
let div = d3.select(body)
.selectAll("div")
.data([4, 8, 15, 16, 23, 42])
.join("div") // use joint("div") to replace enter().append("div")
.text(d => d);
div = div.data([1, 2, 4, 8, 16, 32], (d, i, nodes) => {
console.log("d: ", d); // d for elements, are old datum each; d for data, are new datum each
// console.log("i: ", i); // idx for selection and then for data
// console.log("nodes: ", nodes); // nodes for elements, are all elements in an array; nodes for data, are all new data in an array
return d;
});
div
.join("div") // use joint("div") to replace enter().append("div")
.text(d => d);
// div.exit().remove(); // no longer needed
return body
}
Insert cell
{
// key function
// elements exist, have old data which is same length as new data
// new data overlap with old data
// pay attention to datum for elements and new data
// no undefined, there are overlapping and exit and enter selection
const body = html`<div></div>`
let div = d3.select(body)
.selectAll("div")
.data([4, 8, 15, 16, 23, 42])
.join("div") // use joint("div") to replace enter().append("div")
.text(d => d);
div = div.data([1, 2, 4, 8, 16, 32], (d, i, nodes) => {
console.log("d: ", d); // d for elements, are old datum each; d for data, are new datum each
// console.log("i: ", i); // idx for selection and then for data
// console.log("nodes: ", nodes); // nodes for elements, are all elements in an array; nodes for data, are all new data in an array
return d;
});
const t = div.transition()
.duration(5000);
div
// .join("div") // use joint("div") to replace enter().append("div")
.join(
enter => enter.append("div")
.text(d => d)
.attr("style", "color: green"),
update => update
.attr("style", "color: gray"),
exit => exit
.attr("style", "color: gray")
.call(exit => exit.transition(t)
.attr("style", "color: red")
.remove())
)

// div.exit().remove(); // no longer needed
return body
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
stylesheet
Insert cell
import { d3, stylesheet} from "@embracelife/tutorial-utilities"
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