I am trying to create a table using D3.js and a JSON file.
The data itself consists of 6 columns: code, name, unit, value, target and norm. The table should only show three of them (name, target and value). I would like to use the values of the columns [code] and [norm] to identify the "id" and the "class".
The base code that I use is stated below. This code works fine to create the table itself - except for the "id" and "class" identification:
var data = [{"code": 100,"name": "A","unit": 12,"value": 0.6,"target": 0.75,"norm": "alert"}, {"code": 106,"name": "B","unit": 12,"value": 0.6,"target": 0.75,"norm": "danger"}, {"code": 112,"name": "C","unit": 12,"value": 0.9,"target": 0.75,"norm": "ok"}];var columns = ['name', 'target', 'value'];var table1 = d3.select('#table').append('table');var thead = table1.append('thead');var tbody = table1.append('tbody');// append the header rowthead.append('tr').selectAll('th').data(["Name", "Target", "Value"]).enter().append('th').text(function(column) {return column;});// create a row for each object in the datavar rows = tbody.selectAll('tr').data(data).enter().append('tr');// create a cell in each row for each columnvar cells = rows.selectAll('td').data(function(row) {return columns.map(function(column) {return {column: column,value: row[column]};});}).enter().append('td').html(function(d) {return d.value;});});
My desired table output is stated below where the JSON-values of [code] is used to identify the "id", [norm] is used for the "class". I can't seem to use data-elements 'at cell-level' that are not used to fill the table (td) value. How can I achieve this?
<div id="table"><table><thead><tr><th>Name</th><th>Target</th><th>Value</th></tr></thead><tbody><tr><td id="100" class="alert">A</td><td>0.75</td><td>0.6</td></tr><tr><td id="106" class="danger">B</td><td>0.75</td><td>0.6</td></tr><tr><td id="112" class="ok">C</td><td>0.75</td><td>0.9</td></tr></tbody></table></div>
Best Answer
In the columns mapping for the td
s, you can add a couple more keys as id
and class
:
i.e.
var columns = ['name', 'target', 'value'], column_id = 'code', column_class = 'norm';.... ....return columns.map(function(column) {return {column: column,value: row[column],id: row[column_id],class: row[column_class]};});
And add it to the td
s as follows:
.attr('id', function(d) { return d.column === 'name' ? d.id : null; }).attr('class', function(d) { return d.column === 'name' ? d.class : null; })
Here's a snippet combining all of the above:
var data = [{"code": 100,"name": "A","unit": 12,"value": 0.6,"target": 0.75,"norm": "alert"}, {"code": 106,"name": "B","unit": 12,"value": 0.6,"target": 0.75,"norm": "danger"}, {"code": 112,"name": "C","unit": 12,"value": 0.9,"target": 0.75,"norm": "ok"}];var columns = ['name', 'target', 'value'], column_id = 'code', column_class = 'norm';var table1 = d3.select('#table').append('table');var thead = table1.append('thead');var tbody = table1.append('tbody');// append the header rowthead.append('tr').selectAll('th').data(["Name", "Target", "Value"]).enter().append('th').text(function(column) {return column;});// create a row for each object in the datavar rows = tbody.selectAll('tr').data(data).enter().append('tr');// create a cell in each row for each columnvar cells = rows.selectAll('td').data(function(row) {return columns.map(function(column) {return {column: column,value: row[column],id: row[column_id],class: row[column_class]};});}).enter().append('td').attr('id', function(d) { return d.column === 'name' ? d.id : null; }).attr('class', function(d) { return d.column === 'name' ? d.class : null; }).html(function(d) {return d.value;});
<script src="https://d3js.org/d3.v4.min.js"></script><div id="table"></div>
Hope this helps. :)