aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Eilertsen <haraldei@anduin.net>2019-08-28 10:29:13 +0200
committerHarald Eilertsen <haraldei@anduin.net>2019-08-28 10:29:13 +0200
commitbc1218acd75b6d0594e568e07892f9f9bbb53d7a (patch)
tree4395a5b411abcc001742a8d0c7d0d841b123cb14
parent0e2dff9c9876a1cf9703fb53b5873cf8862ee8d1 (diff)
downloadramaskrik-social-bc1218acd75b6d0594e568e07892f9f9bbb53d7a.tar.gz
ramaskrik-social-bc1218acd75b6d0594e568e07892f9f9bbb53d7a.tar.bz2
ramaskrik-social-bc1218acd75b6d0594e568e07892f9f9bbb53d7a.zip
Use canvas for drawing the schedules.HEADmaster
-rw-r--r--public/app.css4
-rw-r--r--public/index.html5
-rw-r--r--public/js/app.js169
3 files changed, 170 insertions, 8 deletions
diff --git a/public/app.css b/public/app.css
index 28ffb34..752e9ac 100644
--- a/public/app.css
+++ b/public/app.css
@@ -8,3 +8,7 @@ body {
color: #ccc;
font-size: 10pt;
}
+
+canvas {
+ background-color: white;
+}
diff --git a/public/index.html b/public/index.html
index 6e6333f..22b9fc3 100644
--- a/public/index.html
+++ b/public/index.html
@@ -7,9 +7,6 @@
</head>
<body>
<h1>Ramaskrik 2019</h1>
- <div id="program">
- <table id="screening-table">
- </table>
- </div>
+ <div id="program"></div>
</body>
</html>
diff --git a/public/js/app.js b/public/js/app.js
index c6899a7..e219af4 100644
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -49,14 +49,174 @@ function log_film(film) {
+ ")")
}
+function date_f(d) {
+ let opts = { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' }
+ return new Intl.DateTimeFormat('nb-NO', opts).format(d)
+}
+
window.addEventListener("load", function() {
+ let screenings_by_date = new Map()
+
+ function _add(screening) {
+ let d = Date.parse(screening.date)
+ if (!screenings_by_date.has(d))
+ screenings_by_date.set(d, new Array())
+
+ let s = screenings_by_date.get(d)
+ s.push(screening)
+ };
+
+ function _end_time(screening) {
+ if (screening.end_time < screening.start_time) {
+ return screening.end_time
+ .split(':')
+ // Add 24 to the hour component of the time string
+ .map( (v, i) => i == 0 ? (parseInt(v) + 24).toString() : v)
+ .join(':')
+ }
+ else {
+ return screening.end_time
+ }
+ }
+
+ function _time_to_sec(t) {
+ let expl = t.split(':').map( v => parseInt(v) )
+ return expl[0] * 3600 + expl[1] * 60 + expl[2]
+ }
+
+ function _sec_to_time(v) {
+ let hour = Math.floor(v / 3600)
+ v = v % 3600
+ let min = Math.floor(v / 60)
+ let f = Intl.NumberFormat('nb-NO', { minimumIntegerDigits: 2 })
+ return [ f.format(hour), f.format(min) ].join(':')
+ }
+
+ 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) / 30)
+
+ c.font = '10px Helvetica'
+ c.lineWidth = 'thin'
+ c.strokeStyle = '#ccc'
+
+ for (let y = 0; y <= dur; y += 30) {
+ let ypos = y + margin;
+ c.beginPath()
+ c.moveTo(35, ypos)
+ c.lineTo(510, ypos)
+ c.stroke()
+ c.fillText(_sec_to_time(y * 30 + start + margin), 5, ypos + 3)
+ }
+ }
+
+ function draw_room_headers(c, rooms) {
+ let x = 0;
+ c.font = '15px sans-serif'
+
+ for (let r of [...rooms]) {
+ center_text(c, r, 50 + x, 15, 100)
+ x += 150
+ }
+ }
+
+ function draw_screenings(c, screenings, start_time, rooms) {
+ let r = [...rooms]
+
+ c.strokeStyle = '#000'
+
+ for (let s of screenings) {
+ let ystart = Math.ceil((_time_to_sec(s.start_time) - start_time) / 30) + margin;
+ let height = Math.ceil((_time_to_sec(_end_time(s)) - start_time ) / 30) + margin - ystart;
+ let ri = s.room.id - 1
+ let xstart = xmargin + ri * 150
+
+ c.fillStyle = '#ec9'
+ c.fillRect(xstart, ystart, 100, height)
+ c.strokeRect(xstart, ystart, 100, height)
+
+ c.fillStyle = '#000'
+ break_text(c, s.film.title, xstart + 5, ystart + 15, 90)
+ }
+ }
+
load_screenings(function() {
- console.log(this.response)
- this.response.forEach(function(screening) {
- console.log(screening.film.title + "@" + screening.room.name + ": " + screening.date)
- })
+ this.response.forEach(_add)
+
+ console.log("Screenings in " + screenings_by_date.size + " days: ")
+ for (let date of screenings_by_date.keys()) {
+ let date_str = date_f(date)
+ console.log(date_str)
+
+ let s = screenings_by_date.get(date)
+ let start_time = s
+ .map( el => _time_to_sec(el.start_time) )
+ .reduce( (acc, cur) => cur < acc ? cur : acc, _time_to_sec('23:59:59') )
+ let end_time = s
+ .map( el => _time_to_sec(_end_time(el)))
+ .reduce( (acc, cur) => cur > acc ? cur : acc, 0 )
+
+ console.log(" Start time: " + _sec_to_time(start_time))
+ console.log(" End time : " + _sec_to_time(end_time))
+
+ let dur = end_time - start_time
+ console.log(" Duration : " + _sec_to_time(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')
+ day.id = "program-" + date_str
+ day.innerHTML = '<h2>' + date_str + '</h2>'
+ + '<canvas id="canvas-' + date_str + '" height="' + canvas_height + '" width="350">'
+ + '</canvas>'
+ p.appendChild(day)
+
+ let canvas = document.getElementById('canvas-' + date_str)
+ let c = canvas.getContext('2d');
+ let rooms = new Set(s.map( el => el.room.name ))
+ draw_room_headers(c, rooms)
+ draw_timescale(c, start_time, end_time)
+ draw_screenings(c, s, start_time, rooms)
+ }
+
})
+ /*
fetch_rooms(function() {
let table = document.getElementById("screening-table")
let row = document.createElement("tr")
@@ -69,5 +229,6 @@ window.addEventListener("load", function() {
row.appendChild(item)
})
})
+ */
console.log("Holahey!")
})