136 lines
3.1 KiB
TypeScript
136 lines
3.1 KiB
TypeScript
// @ts-check
|
|
//
|
|
import { css, DJElement, h, html, qs } from "./util";
|
|
|
|
class HalfLifeGraph extends DJElement {
|
|
static styles = css`
|
|
.container {
|
|
margin: auto;
|
|
text-align: center;
|
|
}
|
|
|
|
canvas {
|
|
border: solid 1px black;
|
|
}
|
|
`;
|
|
|
|
static template = html`
|
|
<div class="container">
|
|
<div>
|
|
<canvas />
|
|
</div>
|
|
<label for="my-input">Test Input</label>
|
|
<input type="range" />
|
|
</div>
|
|
`;
|
|
|
|
/** @type number */
|
|
height = 480;
|
|
|
|
/** @type number */
|
|
width = 640;
|
|
|
|
/** @type HTMLInputElement */
|
|
input1;
|
|
|
|
/** @type number */
|
|
input1Value;
|
|
|
|
/** @type Function */
|
|
renderCb;
|
|
|
|
constructor() {
|
|
super();
|
|
const canvas = /** @type HTMLCanvasElement */ (qs("canvas", this.root));
|
|
this.input1 = /** @type HTMLInputElement */ (qs("input", this.root));
|
|
canvas.width = this.width;
|
|
canvas.height = this.height;
|
|
const context = canvas.getContext("2d");
|
|
if (!context) {
|
|
throw new Error("No context available");
|
|
}
|
|
this.renderCb = () => {
|
|
window.requestAnimationFrame(() => this.renderFrame(context));
|
|
};
|
|
this.input1.addEventListener("input", (e) => {
|
|
this.input1Value = /** @type HTMLInputElement */ (e.target).valueAsNumber;
|
|
this.renderCb();
|
|
});
|
|
this.renderCb();
|
|
}
|
|
|
|
/**
|
|
* @param {CanvasRenderingContext2D} ctx
|
|
*/
|
|
renderFrame(ctx) {
|
|
this.drawAxes(ctx);
|
|
this.drawGrid(ctx);
|
|
this.drawCurve(ctx);
|
|
}
|
|
|
|
/**
|
|
* @param {CanvasRenderingContext2D} ctx
|
|
*/
|
|
drawAxes(ctx) {
|
|
const startY = 0;
|
|
const endY = 10;
|
|
const startX = 0;
|
|
const endX = 10;
|
|
ctx.beginPath();
|
|
ctx.moveTo(startX, this.height - startY);
|
|
ctx.lineTo(startX, this.height - endY);
|
|
ctx.stroke();
|
|
ctx.beginPath();
|
|
ctx.moveTo(startX, this.height - startY);
|
|
ctx.lineTo(endX, this.height - startY);
|
|
ctx.stroke();
|
|
}
|
|
|
|
/**
|
|
* @param {CanvasRenderingContext2D} ctx
|
|
*/
|
|
drawGrid(ctx) {
|
|
/**
|
|
const step = this.width / V0D
|
|
for (let i = 0; i < thing; i++) {
|
|
ctx.beginPath();
|
|
ctx.moveTo(i, );
|
|
ctx.lineTo(i);
|
|
}
|
|
*/
|
|
}
|
|
|
|
/**
|
|
* @param {CanvasRenderingContext2D} ctx
|
|
*/
|
|
drawCurve(ctx) {
|
|
// A = A_0 * (1/2) ^ t / h
|
|
// h = half life
|
|
// t = point in time
|
|
// A_0 = initial
|
|
// A = current concentration
|
|
|
|
// TODO
|
|
// https://pharmacy.ufl.edu/files/2013/01/5127-28-equations.pdf
|
|
|
|
/**
|
|
* @param {number} x
|
|
*/
|
|
function y(x) {
|
|
return x ** 2;
|
|
}
|
|
|
|
const xEnd = 2;
|
|
const yEnd = 2;
|
|
const samples = 100;
|
|
const step = this.width / samples;
|
|
ctx.beginPath();
|
|
ctx.moveTo(0, this.height);
|
|
for (let i = 0; i < this.width; i += step) {
|
|
ctx.lineTo(i, this.height - y(i / this.width * xEnd) * this.height / yEnd);
|
|
}
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
customElements.define("half-life-graph", HalfLifeGraph);
|