diff --git a/static/chart.mjs b/static/chart.mjs index 8be0718..b4faca2 100644 --- a/static/chart.mjs +++ b/static/chart.mjs @@ -14,7 +14,7 @@ class HistoryChart { * @param {string} strokeStyle strokeStyle to draw in * @param {Duration} duration Time to display history for */ - constructor(canvas, strokeStyle, duration) { + constructor(canvas, strokeStyle="black", duration=20*Second) { this.canvas = canvas this.ctx = canvas.getContext("2d") this.duration = duration @@ -29,8 +29,10 @@ class HistoryChart { this.ctx.translate(0, -canvas.height) this.ctx.strokeStyle = strokeStyle + this.ctx.fillStyle = strokeStyle this.ctx.lineWdith = 2 + this.running=true this.draw() } @@ -42,8 +44,8 @@ class HistoryChart { * This also cleans up the event list, * purging anything that is too old to be displayed. * - * @param when Time the event happened - * @param value Value for the event + * @param {Number} when Time the event happened + * @param {Number} value Value for the event */ Add(when, value) { let now = Date.now() @@ -54,8 +56,10 @@ class HistoryChart { while ((this.data.length > 1) && (this.data[1][0] < earliest)) { this.data.shift() } + } - console.log(this.data) + Stop() { + this.running = false } draw() { @@ -64,43 +68,29 @@ class HistoryChart { let xScale = this.canvas.width / this.duration let yScale = this.canvas.height * 0.95 let y = 0 + let x = 0 this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height) - this.ctx.moveTo(0, 0) - this.ctx.beginPath() for (let point of this.data) { - let x = (point[0] - earliest) * xScale - this.ctx.lineTo(x, y) - y = point[1] * yScale - this.ctx.lineTo(x, y) - } - this.ctx.lineTo(this.canvas.width, y) - this.ctx.stroke() + let x2 = (point[0] - earliest) * xScale + let y2 = point[1] * yScale - requestAnimationFrame(() => this.draw()) + if (y > 0) { + this.ctx.fillRect(x, 0, x2-x, y) + } + + x=x2 + y=y2 + } + if (y > 0) { + this.ctx.fillRect(x, 0, this.canvas.width, y) + } + + if (this.running) { + requestAnimationFrame(() => this.draw()) + } } } export {HistoryChart} - - -// XXX: remove after testing -let chart - -function init() { - let canvas = document.querySelector("#chart") - chart = new HistoryChart(canvas, "red", 20 * Second) - setInterval(update, 500 * Millisecond) -} - -function update() { - let now = Date.now() - chart.Add(now, Math.sin(now/Second)/2 + 0.5) -} - -if (document.readyState === "loading") { - document.addEventListener("DOMContentLoaded", init) -} else { - init() -} \ No newline at end of file diff --git a/static/index.html b/static/index.html index d50b532..f751869 100644 --- a/static/index.html +++ b/static/index.html @@ -27,9 +27,6 @@
@@ -54,10 +51,10 @@ Fortunes (crazy slow)+ +
E . | -I .. | -S ... | -H .... | -4 ....- | -
V ...- | -3 ...-- | -|||
U ..- | -F ..-. | -|||
- | 2 ..--- | -|||
A .- | -R .-. | -L .-.. | -||
- | ||||
W .-- | -P .--. | -|||
J .--- | -1 .---- | -|||
T - | -N -. | -D -.. | -B -... | -6 -.... | -
X -..- | -||||
K -.- | -C -.-. | -|||
Y -.-- | -||||
M -- | -G --. | -Z --.. | -7 --... | -|
Q --.- | -||||
O --- | -- | 8 ---.. | -||
- | 9 ----. | -
- This is a CW repeater, - named after Alfred Vail, - who may or may not have invented what's called "Morse code", - but clearly had some role in it. -
- -- Just like a radio repeater, - anybody can connect and start transmitting stuff, - and this will broadcast it to everyone connected. -
-- I needed a place to practice CW with actual human beings, - and I wanted it to be as close as possible to what I'd experience on a radio. - I also didn't have a lot of money to spend on equipment, but I did have a computer, phone, and gamepad. - Nothing else like this exists on the Internet, as far as I can tell. -
- -- It means this repeater doesn't repeat anything: - nothing you key in will be sent anywhere. - These are to help people practice and learn, - without worrying about anyone else hearing them fumble around. -
- -- This is the "drop tone", and will be accompanied by an error. -
-- This means the packet arrived so late, it can't be played in time. - In technical terms: the timestamp of the packet plus the receive delay - is less than the current time. - It can't be scheduled to play, because we can't go back in time. -
-- This could be happening for three reasons: -
-- Vail attempts to correct for clock differences, - but making sure your computer has correct time, - down to the millisecond, - can help with reliability. -
- -- Neale Pickett kd7oqi -
-- The Internet isn't exactly like radio waves: - it still goes at near the speed of light, - but there are multiple hops between endpoints, - which buffer up transmissions, and multiplex them onto a single uplink connection. - These repeaters (routers) - are also allowed to just drop things if they need to. - It's the responsibility of the communicating parties - to work out whether something needs to be retransmitted. - Because of this, - there's no telling how long it will take for a transmission to get to a destination. -
-- Each Vail transmission (packet) consists of: -
-- The repeater does nothing but broadcast everything it gets - to every connected Vail client, - including the one that sent the packet. - When your client gets back the exact same thing it sent, - it compares the current time to the time in the packet. - This is the round-trip time: - the time it takes for a packet to get from your computer to the repeater and back. -
-- When the client gets a packet it didn't send, - it adds the receive delay to the timestamp, - and schedules to play the tones and silences in the packet - at that time. -
-- By adding the maximum round-trip time to the longest recent transmission - (the length of a dah, hopefully), - your client can make a guess about how much time needs to be added to a received timestamp, - in order to have it play back in the future at the time it comes in. - This is just a guess. - If you're communicating with somebody with a higher round-trip time than you have, - you'll need to raise your receive delay to account for it. -
-