The description of the selection.data function includes an example with multiple groups (link) where a two-dimensional array is turned into an HTML table.
My solution was to embed this information in the data provided to d3js
data = [[1,2,3],[4,5,6],[7,8,9]]
flattened_data = data.reduce((acc, v, i) => {
v.forEach((d, j) => {
data_item = { i, j, d };
acc.push(data_item);
});
return acc;
}, []);
Then you can access i, j and d from the data arg of the function
td.text(function(d) {
// Can access i, j and original data here
return "Row: " + d.j;
});