I am fairly new to d3, so I consider this a newbie question, b/c I still could not wrap my head around data joins. I am trying to add rows to a grid layout. Each row is represented as an object with several slots and the rows are stored in an array.
In my .join
I want to add several elements to the selection (content determined by the slots of the object, here simply the .text
). I have difficulties to specify the .selectAll
call before the .data
call. I understand why this strange behaviour is occuring (basically) it tries to match the data to all divs in the selection (which are all cells).
How would I need to change m code, that each click on the button simply adds a new row?
Bonus question: as you cna see the cells are all mixed up. How would I add the data by row and not by column?
const data = [
{cell1: '1/1', cell2: '1/2', cell3: '1/3', id: 1},
{cell1: '2/1', cell2: '2/2', cell3: '2/3', id: 2}
];
function update(data) {
d3.select('#grid')
.selectAll('div')
.data(data, (d) => d.id)
.join((enter) => {
enter.append('div')
.classed('cell1', true)
.text((d) => d.cell1);
enter.append('div')
.classed('cell2', true)
.text((d) => d.cell2)
enter.append('div')
.classed('cell3', true)
.text((d) => d.cell3);
})
}
update(data)
function addRow() {
const n = data.length + 1;
const newRow = {cell1: n + '/1', cell2: n + '/2', cell3: n + '/3', id: n};
data.push(newRow);
update(data);
}
#grid {
display: inline-grid;
grid-template-columns: repeat(3, 200px);
}
#grid > div:nth-of-type(3n+2) {
background-color: orange;
}
#grid > div:nth-of-type(3n+1) {
background-color: purple;
}
#grid > div:nth-of-type(3n+0) {
background-color: forestgreen;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
<div id="grid">
</div>
<button id="add" onclick="addRow()">Add Row</button>
Ok first problem solved. I must not call .selectAll
with 'div'
as this will select all divs in the selection and then the join tries to match n rows with n x 3
divs-
Easy remedy is to select only the first div (for instance) via .selectAll('.cell1')
. This guarantees that there is always a match between rows in the data and rows in the grid (given that each row contains a single cell1
classed div.
Only problem remaining is that the order is all messed up, but I will ask a new question for that.