diff --git a/static/chart.html b/static/chart.html
index 46a962f..29dc459 100644
--- a/static/chart.html
+++ b/static/chart.html
@@ -2,67 +2,7 @@
Chart-O-Matic
-
+
The Amazing Chart-O-Matic
diff --git a/static/chart.mjs b/static/chart.mjs
new file mode 100644
index 0000000..2fbfc8a
--- /dev/null
+++ b/static/chart.mjs
@@ -0,0 +1,105 @@
+/** @typedef {Number} Duration */
+ const Millisecond = 1
+ const Second = 1000 * Millisecond
+
+ /**
+ * A chart of historical values.
+ *
+ * Curently this assumes all values are between 0 and 1,
+ * since that's all I need.
+ */
+class HistoryChart {
+ /**
+ * @param {Element} canvas Canvas element to draw on
+ * @param {string} strokeStyle strokeStyle to draw in
+ * @param {Duration} duration Time to display history for
+ */
+ constructor(canvas, strokeStyle, duration) {
+ this.canvas = canvas
+ this.ctx = canvas.getContext("2d")
+ this.duration = duration
+
+ this.data = []
+ this.max = 1
+ this.min = 0
+
+ // One canvas pixel = 20ms
+ canvas.width = duration / (20 * Millisecond)
+
+ // Set origin to lower-left corner
+ this.ctx.scale(1, -1)
+ this.ctx.translate(0, -canvas.height)
+
+ this.ctx.strokeStyle = strokeStyle
+ this.ctx.lineWdith = 2
+
+ this.draw()
+ }
+
+ /**
+ * Add an event point at a given time.
+ *
+ * These must always be added in time order.
+ *
+ * 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
+ */
+ Add(when, value) {
+ let now = Date.now()
+ let earliest = now - this.duration
+
+ this.data.push([when, value])
+ while (this.data[0][0] < earliest) {
+ this.data.shift()
+ }
+
+ console.log(this.data)
+ }
+
+ draw() {
+ let now = Date.now()
+ let earliest = now - this.duration
+ let xScale = this.canvas.width / this.duration
+ let y = 0
+
+ this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
+
+ this.ctx.moveTo(0, y)
+ this.ctx.beginPath()
+ for (let point of this.data) {
+ let x = (point[0] - earliest) * xScale
+ this.ctx.lineTo(x, y)
+ y = point[1] * this.canvas.height
+ this.ctx.lineTo(x, y)
+ }
+ this.ctx.stroke()
+
+ 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