[英]How to build an html table using javascript and having two levels of column headers
I need help using plain java script in building an HTML table that pivots my data.我需要帮助使用普通的 java 脚本来构建一个旋转我的数据的 HTML 表。
My data has State, Year, Month, and Sales.我的数据有 State、年、月和销售额。 It looks like this:
它看起来像这样:
state year month sales
FL 2018 1 100
Fl 2018 2 200
Fl 2018 3 250
FL 2019 1 200
Fl 2019 2 225
Fl 2019 3 175
etc. for other states, years, and months.
I would like to build a table like this.我想建立一个这样的表。 I only show the first 3 months of a year for simplicity:
为简单起见,我只显示一年的前 3 个月:
Year 2018 2018 2018 2019 2019 2019
Month 1 2 3 1 2 3
State
FL 100 200 250 200 225 175
I know how to build a simple table using java script.我知道如何使用 java 脚本构建一个简单的表。 So I do not need advice on the normal code, functions, etc. to use.
所以我不需要关于正常代码、函数等使用的建议。 I need help with the logic of pivoting the data and building the two header rows of year and month.
我需要有关旋转数据和构建年月两行 header 的逻辑方面的帮助。
My two issues are:.我的两个问题是:。
In Pandas this would be very easy to do, but we need it in java script so it can be done at the desktop level, not at the server level.在 Pandas 中,这很容易做到,但我们需要在 java 脚本中使用它,因此它可以在桌面级别完成,而不是在服务器级别。
Thanks for any help.谢谢你的帮助。
Note: The data in the array does not need to be sorted by state or date, this will be done through the script.
注意:数组中的数据不需要按 state 或日期排序,这将通过脚本完成。 The dates needs not to be complete.
日期不必完整。
Here is the code for playing https://jsfiddle.net/efp8cL53/4/下面是玩https的代码://jsfiddle.net/efp8cL53/4/
function createSalesTable(data, id) { let table = document.getElementById(id); let dates = data.reduce((acc, cur) => { let date = cur.year * 100 + cur.months; if (.acc.includes(date)) acc;push(date); return acc, }; []). dates;sort(). let dataAll = data,reduce((acc. cur) => { if (.acc[cur;state]) acc[cur.state] = []. acc[cur;state];push(cur), return acc; }. {}); // First line let tr = document.createElement('TR'); let th = document.createElement('TH'); th.innerHTML = 'Year'; tr.appendChild(th). dates;forEach(date => { th = document.createElement('TH'); th.innerHTML = parseInt(date/100); tr;appendChild(th). }); table.appendChild(tr); // Second Line tr = document.createElement('TR'); th = document.createElement('TH'); th.innerHTML = 'Month'; tr.appendChild(th). dates;forEach(date => { th = document.createElement('TH'); th.innerHTML = parseInt(date%100); tr;appendChild(th). }); table.appendChild(tr). // Table Object,entries(dataAll).forEach(([state; entries]) => { tr = document.createElement('TR'); let th = document.createElement('TH'); th.innerHTML = "Sales - " + state; tr.appendChild(th). dates;forEach(date => { let td = document.createElement('TD'). let entry = entries.find(elem => elem;year === parseInt(date/100) && elem.months===date%100). if ( entry;==undefined ) td.innerHTML = entry;sales; tr.appendChild(td); }); table.appendChild(tr); }): table,appendChild(tr): } let data = [ {state, 'FL': year, 2018: months, 1: sales, 100}: {state, 'FL': year, 2018: months, 2: sales, 100}: {state, 'FL': year, 2018: months, 3: sales, 100}: {state, 'FL': year, 2019: months, 1: sales, 100}: {state, 'FL': year, 2019: months, 2:sales, 100}: {state, 'FL': year, 2019: months, 3: sales, 100}: {state, 'FL': year, 2017: months, 12: sales, 333}: {state, 'CH': year, 2018: months, 2: sales, 700}: {state, 'CH': year, 2018: months, 5: sales, 50}: {state, 'D': year, 2018: months, 7: sales, 5000}: {state, 'D': year, 2018: months, 3: sales, 300}: {state, 'D': year, 2019: months; 2, sales; 700} ]; createSalesTable(data, 'sales');
table, td, th { border: solid 1px black; }
<table id='sales'></table>
You can use D3 for pivoting.您可以使用 D3 进行旋转。 It has a.nest() function lets you group data elements by the specified key.
它有 a.nest() function 允许您按指定键对数据元素进行分组。
HTML HTML
<div>
<table id="myTable"></table>
</div>
JS JS
var dataArray = [];
dataArray.push({
"STATE": "FL",
"YEAR": 2018,
"MONTH": 1,
"SALES": 100
});
dataArray.push({
"STATE": "FL",
"YEAR": 2018,
"MONTH": 2,
"SALES": 200
});
dataArray.push({
"STATE": "FL",
"YEAR": 2018,
"MONTH": 3,
"SALES": 250
});
dataArray.push({
"STATE": "FL",
"YEAR": 2019,
"MONTH": 1,
"SALES": 200
});
dataArray.push({
"STATE": "FL",
"YEAR": 2019,
"MONTH": 2,
"SALES": 225
});
dataArray.push({
"STATE": "FL",
"YEAR": 2019,
"MONTH": 3,
"SALES": 175
});
dataArray.push({
"STATE": "TX",
"YEAR": 2018,
"MONTH": 1,
"SALES": 300
});
dataArray.push({
"STATE": "TX",
"YEAR": 2018,
"MONTH": 2,
"SALES": 350
});
dataArray.push({
"STATE": "TX",
"YEAR": 2018,
"MONTH": 3,
"SALES": 280
});
dataArray.push({
"STATE": "LA",
"YEAR": 2017,
"MONTH": 2,
"SALES": 100
});
dataArray.push({
"STATE": "LA",
"YEAR": 2017,
"MONTH": 3,
"SALES": 150
});
dataArray.push({
"STATE": "NM",
"YEAR": 2016,
"MONTH": 2,
"SALES": 300
})
//Sort the data array
dataArray = dataArray.sort(function(a, b) {
return (a['YEAR'] == b['YEAR'] ? ((a['MONTH'] == b['MONTH']) ? ((a['STATE'] > b['STATE']) ? 1 : -1) : (a['MONTH'] - b['MONTH'])) : (a['YEAR'] - b['YEAR']))
});
//Nesting for the Years and Months headers i.e. group by Year and then Month
var nestedArrayForHeaders = d3.nest()
.key(d => d['YEAR'])
.key(d => d['MONTH'])
.entries(dataArray);
//Nesting for the data i.e. group by STATE
var nestedArrayForData = d3.nest()
.key(d => d['STATE'])
.entries(dataArray);
var yearsRow = $('<tr></tr>');
var monthsRow = $('<tr></tr>');
$(yearsRow).append($('<td></td>').addClass('rowHeader').text('Year'));
$(monthsRow).append($('<td></td>').addClass('rowHeader').text('Month'));
/*START: Rendering the Years and Months rows*/
nestedArrayForHeaders.forEach(function(yearObj) {
yearObj['values'].forEach(function(monthObj) {
$(yearsRow).append($('<td></td>').addClass('columnHeader').text(yearObj['key']));
$(monthsRow).append($('<td></td>').addClass('columnHeader').text(monthObj['key']));
});
$('#myTable').append(yearsRow);
$('#myTable').append(monthsRow);
});
/*END: Rendering the Years and Months rows*/
/*START: Rendering the State rows*/
nestedArrayForData.forEach(function(stateObj){
var stateRow = $('<tr></tr>');
$(stateRow).append($('<td></td>').addClass('rowHeader').text(stateObj['key']));
nestedArrayForHeaders.forEach(function(yearObj) {
yearObj['values'].forEach(function(monthObj) {
var currDataObj = stateObj['values'].find(d=>{return d['YEAR']==yearObj['key'] && d['MONTH']==monthObj['key']});
if(currDataObj){
$(stateRow).append($('<td></td>').text(currDataObj['SALES']));
}
else{
$(stateRow).append($('<td></td>').text('-'));
}
});
});
$('#myTable').append(stateRow);
});
/*END: Rendering the State rows*/
CSS : CSS :
body {
padding: 20px;
}
#myTable{
border-collapse: collapse;
}
#myTable td{
border: 1px solid black;
border-collapse: collapse;
color: black;
padding:4px;
text-align: center;
}
#myTable td.rowHeader{
color: red;
}
#myTable td.columnHeader{
color: blue;
}
You can play around with it [here][1].
[1]: http://jsfiddle.net/bn4qvkd9/74/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.