Добрый день всем. Совсем забыл об этой теме.... Получилось что-то вроде:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href=".\node_modules\bootstrap\dist\css\bootstrap.css">
<title>Document</title>
</head>
<body>
<table class="table table-bordered border-primary"></table>
<script src="node_modules/moment/min/moment.min.js"></script>
<script src="test.js"></script>
</body>
</html>
JS
const workers = {
"welders": [
{
"name": "Vadim Sergeevich",
"dateStart": "2022-01-14",
"dateEnd": "2022-03-14"
},
{
"name": "Sergey Vladimirovich",
"dateStart": "2022-01-01",
"dateEnd": "2022-02-04"
},
{
"name": "Viktoriya",
"dateStart": "2022-03-02",
"dateEnd": "2022-04-02"
},
],
"installers": [
{
"name": "Vladimir Petrovich",
"dateStart": "2022-02-14",
"dateEnd": "2022-04-14"
},
{
"name": "Petr Georgievich",
"dateStart": "2022-02-02",
"dateEnd": "2022-04-02"
},
],
"storekeeper": [
{
"name": "Vladimir Petrovich",
"dateStart": "2022-02-14",
"dateEnd": "2022-04-14"
},
{
"name": "Petr Georgievich",
"dateStart": "2022-02-02",
"dateEnd": "2022-04-02"
},
],
};
// получаем макс и мин даты
let newMaxDate;
let newMinDate;
const maxMinDate = () => {
let dateArr = [];
for (work in workers) {
workers[work].forEach(elem => {
let ds = new Date(elem.dateStart);
let de = new Date(elem.dateEnd);
dateArr.push(ds, de);
});
};
newMaxDate = new Date(Math.max.apply(null, dateArr));
newMinDate = new Date(Math.min.apply(null, dateArr));
};
maxMinDate();
// получаем диапазон дат между макс и мин датами
let dateArr = [];
let dateArrAll = [];
const rangeDate = () => {
let minDate = moment(newMinDate);
let maxDate = moment(newMaxDate);
while (minDate <= maxDate) {
dateArr.push(minDate.format('DD'));
dateArrAll.push(minDate.format('YYYY-MM-DD'))
minDate.add(1, 'days');
};
};
rangeDate();
// получаем диапазон месяцев между макс и мин датами
let monthArr = [];
const rangeMonth = () => {
let minDate = moment(newMinDate);
let maxDate = moment(newMaxDate);
while (maxDate > minDate || maxDate.format('M') === minDate.format('M')) {
monthArr.push(minDate.format());
minDate.add(1, 'month');
};
};
rangeMonth();
// получаем первые элементы для шапки
let head = []
const header = () => {
for (key in workers) {
workers[key].forEach(elem => {
head.push((Object.keys(elem)));
})
};
};
header();
let headFirst = head[0];
// выводим таблицу
const getTable = () =>{
const table = document.querySelector(".table");
for(key in workers){
let thead = document.createElement("thead");
let tr = document.createElement("tr");
let th = document.createElement("th");
let fragment = document.createDocumentFragment();
th.innerText = key;
th.style.textAlign = "center";
th.colSpan = 3;
fragment.appendChild(th);
monthArr.forEach(elem => {
let th = document.createElement("th");
th.style.textAlign = "center";
let colspan = moment(elem).daysInMonth();
th.colSpan = colspan;
th.innerText = moment(elem).format('MMMM');
fragment.appendChild(th);
})
tr.appendChild(fragment);
thead.appendChild(tr);
let tr2 = document.createElement("tr");
headFirst.forEach(elem => {
let th2 = document.createElement("th");
th2.style.textAlign = "center";
th2.innerText = elem;
fragment.appendChild(th2);
})
dateArr.forEach(elem => {
let th3 = document.createElement("th");
th3.innerText = elem;
fragment.appendChild(th3);
})
tr2.appendChild(fragment);
thead.appendChild(tr2);
table.appendChild(thead);
let numArrAll =[];
let tbody = document.createElement("tbody");
workers[key].forEach(elem => {
let tr = document.createElement("tr");
Object.values(elem).forEach(txt => {
let td = document.createElement("td");
td.style.whiteSpace = "nowrap";
td.innerText = txt;
fragment.appendChild(td);
tr.appendChild(fragment);
})
let ds = elem.dateStart;
let de = elem.dateEnd;
let numArr =[];
dateArrAll.forEach(cell => {
let td = document.createElement("td");
td.style.textAlign = "center";
if(cell >= ds && cell <= de){
td.style.backgroundColor = "#e6e5e3";
td.innerText = 1;
numArr.push(1);
fragment.appendChild(td);
tr.appendChild(fragment);
}else{
td.innerText = '';
numArr.push(0);
fragment.appendChild(td);
tr.appendChild(fragment);
}
})
tbody.appendChild(tr);
numArrAll.push(numArr);
})
// ПРОВЕРИТь
// let tr3 = document.createElement("tr");
// let thQ = document.createElement("th");
// thQ.innerText = "Quantity";
// thQ.colSpan = 3;
// thQ.style.textAlign = "right";
// fragment.appendChild(thQ);
// tr3.appendChild(fragment);
// tbody.appendChild(tr3);
// let col;
// let row;
// let summ = numArrAll[0].slice();
// for(row =1; row < numArrAll.length; row++){
// for(col = 0; col < summ.length; col++){
// let th = document.createElement("th");
// th.innerText = summ[col] +=numArrAll[row][col];
// fragment.appendChild(th);
// tr3.appendChild(fragment);
// };
// };
table.appendChild(tbody);
let tr4 = document.createElement("tr");
tr4.style.height = "30px";
tr4.appendChild(fragment);
tbody.appendChild(tr4);
};
};
getTable();
Для более менее корректного отображения подключил bootstrap. Для работы с датами использовал moment.js. Спасибо всем за советы. Очень помогли. Получилось в принципе то что и хотел, но не доработал вывод поля "Quantity", которое отображает общую численность сотрудников определенной должности на каждую дату (комментарий ПРОВЕРИТЬ). Может конечно написано и не совсем красиво, но какой-никакой результат.