Last active
April 15, 2022 12:17
-
-
Save fcamblor/bec1cc6131564696fb12824f6ad3a842 to your computer and use it in GitHub Desktop.
Helping script to adjust DevoxxFr schedule columns (rooms) width
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async function loadScript(url) { | |
var script = document.createElement('script'); | |
script.type = 'text/javascript'; | |
script.src = url; | |
document.head.appendChild(script); | |
return new Promise((resolve) => setTimeout(resolve, 1000)); | |
} | |
Promise.all([ | |
loadScript("https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js") | |
]).then(() => { refreshOptims(); setInterval(refreshOptims, 2000); }) | |
var $ = jQuery; | |
function refreshOptims() { | |
console.log(_); | |
let $tr = $(".agendaTable tr"); | |
let roomsRow = _.find($tr, tr => isRoomRow(tr)); | |
let $slottableRows = $tr.filter((idx, tr) => !isRoomRow(tr) && !isBreak(tr)); | |
let roomMap = createRoomMapFrom(roomsRow); | |
let stats = createStatsFrom($slottableRows, roomMap); | |
showOptims(stats); | |
console.log($tr.length); | |
} | |
function showOptims(stats) { | |
$(".max-cell-height").removeClass("max-cell-height"); | |
$(".warning-cell-height").removeClass("warning-cell-height"); | |
_.each(stats.overall, stat => { | |
if(stat.contentHeight === stat.maxRowContentHeight) { | |
$(stat.cell).addClass("max-cell-height"); | |
} else if(stat.isConsideredMax) { | |
$(stat.cell).addClass("warning-cell-height"); | |
} | |
}); | |
const roomErrorStats = Array.from($(".agendaTable .rooms").eq(0).find("td").map((roomIndex,td) => { | |
const roomErrors = sumOf($(".agendaTable tr").map((_, tr) => { | |
return $(tr).find("td").filter((cellColIndex, td) => { | |
return cellColIndex === roomIndex && $(td).hasClass("max-cell-height"); | |
}).length; | |
})); | |
return { room: $(td).find(".main-title").text(), errorsCount: roomErrors}; | |
})) | |
console.table(roomErrorStats.reduce((twolinesResultArray, roomErrors, index) => { | |
twolinesResultArray[0][String.fromCharCode(97+index)] = roomErrors.room; | |
twolinesResultArray[1][String.fromCharCode(97+index)] = `${roomErrors.errorsCount}${roomErrors.errorsCount===Math.max(...roomErrorStats.map(s => s.errorsCount))?' *':''}`; | |
return twolinesResultArray; | |
}, [{},{}])) | |
let MAX_TABLE_WIDTH = 1665; | |
let MAX_TABLE_HEIGHT = 1139; | |
let tableWidth = $(".single-content.single-content-page").width(); | |
let tableHeight = $(".single-content.single-content-page").height(); | |
console.log(`Total printable area width=${tableWidth} ${tableWidth > MAX_TABLE_WIDTH?'/!\\':''} ${MAX_TABLE_WIDTH - tableWidth}`); | |
console.log(`Total printable area height=${tableHeight} ${tableHeight > MAX_TABLE_HEIGHT?'/!\\':''} ${MAX_TABLE_HEIGHT - tableHeight}`); | |
} | |
function createStatsFrom($rows, roomMap) { | |
let stats = { | |
byRow: [], | |
byCol: [], | |
overall: [] | |
}; | |
_.each($rows, (row, rowIdx) => { | |
$(row).find("td").each((___, td) => { | |
var roomClassName = extractRoomClassNameFrom(td); | |
var colIdx = roomMap.byClassName[roomClassName].col; | |
var stat = { | |
row: rowIdx, | |
col: colIdx, | |
contentHeight: $(td).find(".content").height(), | |
rowSpan: Number($(td).attr('rowspan') || 1), | |
cell: td, | |
...guessKindFromCell(td) | |
}; | |
stats.byRow[rowIdx] = stats.byRow[rowIdx] || []; | |
stats.byCol[colIdx] = stats.byCol[colIdx] || []; | |
stats.byRow[rowIdx][colIdx] = stat; | |
stats.byCol[colIdx][rowIdx] = stat; | |
stats.overall.push(stat); | |
}); | |
}); | |
// Browsing every rows in order, for each, to identify max content height and ranking for every rows compared to this ranking | |
_.each(stats.byRow, cols => { | |
const candidateCols = _(cols) | |
.filter(col => col.slotKind === 'proposal' && col.rowSpan === 1) | |
.value(); | |
if(candidateCols.length) { | |
const contentHeights = _(candidateCols).map(stat => stat.contentHeight).uniq(false).sortBy().reverse().value(); | |
const heightRank = _(contentHeights).map((val, idx) => [val, idx]).zipObject().value(); | |
const max = contentHeights[0]; | |
_.each(candidateCols, stat => { | |
stat.maxRowContentHeight = max; | |
stat.rowContentHeightRank = heightRank[stat.contentHeight]; | |
stat.isConsideredMax = ((max - stat.contentHeight)/max) < 0.05; | |
}); | |
} | |
}); | |
return stats; | |
} | |
function guessKindFromCell(td) { | |
if($(td).hasClass("tba")) { | |
return { slotKind: "tba" }; | |
} else if($(td).hasClass("room-closed")){ | |
return { slotKind: "room-closed" }; | |
} else if($(td).hasClass("break")){ | |
return { slotKind: "break" }; | |
} else if($(td).hasClass("proposal")){ | |
return { slotKind: "proposal", proposalType: extractElClassNameMatching(td, 'proposal_type_is_') }; | |
} else { | |
return { slotKind: "unknown" }; | |
} | |
} | |
function createRoomMapFrom(roomsRow) { | |
var roomMap = { | |
byClassName: {}, | |
byColIndex: [] | |
}; | |
_.each($(roomsRow).find("td.room"), (roomCell, colIdx) => { | |
var roomClassName = extractRoomClassNameFrom(roomCell); | |
var entry = { col: colIdx, roomClassName }; | |
roomMap.byClassName[roomClassName] = entry; | |
roomMap.byColIndex[colIdx] = entry; | |
}); | |
return roomMap; | |
} | |
function extractElClassNameMatching(el, prefix) { | |
return [ ...el.classList ].find(className => className.substr(0, prefix.length) === prefix); | |
} | |
function extractRoomClassNameFrom(el) { | |
const roomEl = $(el).parents("table").find("tr.rooms").eq(0).children().eq($(el).index())[0] | |
return extractElClassNameMatching(roomEl, 'room_is_'); | |
} | |
function isRoomRow(tr) { | |
return $(tr).hasClass("rooms"); | |
} | |
function isBreak(tr) { | |
return $(tr).find("td:eq(0)").hasClass("break"); | |
} | |
function sumOf(numArr){ return Array.from(numArr).reduce((total, num) => num+total, 0); } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment