/* Social program for Ramaskrik. Copyright (C) 2019 Harald Eilertsen This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ function load_screenings(data_done) { let req = new XMLHttpRequest() req.addEventListener("load", data_done) req.open("GET", "ramaskrik-2019.json") req.responseType = "json" req.send() } function pad(num) { return num > 9 ? num.toString() : "0" + num } function time_f(t) { return pad(t.getHours()) + ":" + pad(t.getMinutes()) } function date_f(d) { let opts = { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' } return new Intl.DateTimeFormat('nb-NO', opts).format(d) } function isodate(d) { return d.getFullYear() + "-" + pad(d.getMonth() + 1) + "-" + pad(d.getDate()) } window.addEventListener("load", function() { let screenings_by_date = new Map() function _add(screening) { let d = new Date(screening.date || screening.start_time) let key = isodate(d) if (!screenings_by_date.has(key)) screenings_by_date.set(key, new Array()) let s = screenings_by_date.get(key) s.push(screening) }; function break_text(c, text, x, y, width) { let len = c.measureText(text).width if (len < width) { c.fillText(text, x, y) return } let expl = text.split(' ') let space = c.measureText(' ').width let llen = 0 let lpos = 0 for (let frag of expl) { flen = c.measureText(frag).width llen += flen if (llen >= width) { llen = 0 lpos = 0 y += 15 } c.fillText(frag, x + lpos, y) lpos += flen + space } } function center_text(c, text, x, y, width) { let len = c.measureText(text).width let xpos = Math.ceil((width - len) / 2) c.fillText(text, x + xpos, y) } let margin = 30; let xmargin = 50; function draw_timescale(c, start, end) { let dur = Math.ceil((end - start) / 100) c.font = '10px sans-serif' c.lineWidth = 'thin' c.strokeStyle = '#ccc' let canvas = c.canvas for (let y = 0; y <= dur; y += 30) { let ypos = y + margin; c.beginPath() c.moveTo(35, ypos) c.lineTo(canvas.width, ypos) c.stroke() let label = time_f(new Date(start.valueOf() + y * 30000 + margin)) c.fillText(label, 5, ypos + 3) } } function draw_room_headers(c, rooms) { let x = 0; c.font = 'bold 15px sans-serif' for (let r of [...rooms]) { center_text(c, r, xmargin + x, 15, 100) x += 150 } } function draw_screenings(c, screenings, start_time, rooms) { let r = [...rooms] c.strokeStyle = '#cfc' for (let s of screenings) { let stt = new Date(s.start_time) let ett = new Date(s.end_time) let ystart = Math.ceil((stt - start_time) / 30000) + margin; let height = Math.ceil((ett - start_time ) / 30000) + margin - ystart; let ri = r.findIndex(el => el == s.room.name) let xstart = xmargin + ri * 150 c.fillStyle = '#cc8' c.fillRect(xstart, ystart, 100, height) c.strokeRect(xstart, ystart, 100, height) c.fillStyle = '#000' c.font = '10px sans-serif' c.fillText(time_f(stt) + " - " + time_f(ett), xstart + 5, ystart + 10) c.font = '12px sans-serif' break_text(c, s.film.title, xstart + 5, ystart + 25, 85) } } load_screenings(function() { let ts = Date.now() this.response.forEach(_add) console.log("Screenings in " + screenings_by_date.size + " days: ") for (let date of screenings_by_date.keys()) { console.log(date) let s = screenings_by_date.get(date) let start_time = new Date(s .map( el => el.start_time ) .sort() .shift()) let end_time = new Date(s .map( el => el.end_time ) .sort() .pop()) console.log(" Start time: " + start_time) console.log(" End time : " + end_time) let dur = (end_time - start_time) / 1000 console.log(" Duration : " + dur) // Each line in the canvas equals half a minute let canvas_height = Math.ceil(dur / 30) + 60 let p = document.querySelector('#program') let day = document.createElement('section') let rooms = new Set(s.map( el => el.room.name )) let width = xmargin + 150 * rooms.size let dateobj = new Date(date) console.log("dateobj: " + dateobj) day.id = "program-" + isodate(dateobj) day.innerHTML = '

' + date_f(dateobj) + '

' + '' + '' p.appendChild(day) let canvas = document.getElementById('canvas-' + isodate(dateobj)) let c = canvas.getContext('2d'); c.fillStyle = '#233' c.fillRect(0, 0, width, canvas_height); c.fillStyle = '#fff' draw_room_headers(c, rooms) draw_timescale(c, start_time, end_time) draw_screenings(c, s, start_time, rooms) } console.log("Total elapsed time: " + (Date.now() - ts) + "ms.") }) })