Public
HTTP (deprecated)
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { svgServer } from "https://esm.town/v/fil/svgServer";
// Utilities
const gcd = (a, b) => {
while (b !== 0) {
[a, b] = [b, a % b];
}
return a;
};
const lcm = (a, b) => (a * b) / gcd(a, b);
const lcm3 = (a, b, c) => lcm(lcm(a, b), c);
// Constants
const date = new Date();
const CURRENT_MONTH = date.getMonth() + 1;
const CURRENT_DATE = date.getDate();
const CURRENT_YEAR = date.getFullYear() % 100;
const N = 2 * lcm3(CURRENT_MONTH, CURRENT_DATE, CURRENT_YEAR) + 1;
// Calculate exponential sum
function expSumData() {
let sum = { real: 0, imag: 0 };
const data = [{ real: 0, imag: 0 }];
for (let n = 1; n <= N; n++) {
const angle = 2 * Math.PI * (n / CURRENT_MONTH + (n * n) / CURRENT_DATE + (n * n * n) / CURRENT_YEAR);
sum.real += Math.cos(angle);
sum.imag += Math.sin(angle);
data.push({ real: sum.real, imag: sum.imag });
}
return data;
}
// Render exponential sum plot
export async function expSumPlot(req) {
const d3 = await import("npm:d3");
const document = await import("https://esm.sh/linkedom@0.15").then((l) => l.parseHTML("<a>").document);
const data = expSumData();
function render(data) {
const margin = { top: 20, right: 20, bottom: 20, left: 20 };
const width = 500 - margin.left - margin.right;
const height = 500 - margin.top - margin.bottom;
const svg = d3.select(document.body).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("viewBox", [0, 0, width + margin.left + margin.right, height + margin.top + margin.bottom])
.attr("style", "max-width: 100%; height: auto;");
const g = svg.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
const xExtent = d3.extent(data, d => d.real);
const yExtent = d3.extent(data, d => d.imag);
const xScale = d3.scaleLinear()
.domain([Math.min(xExtent[0], -1), Math.max(xExtent[1], 1)])
.range([0, width]);
const yScale = d3.scaleLinear()
.domain([Math.min(yExtent[0], -1), Math.max(yExtent[1], 1)])
.range([height, 0]);
const line = d3.line()
.x(d => xScale(d.real))
.y(d => yScale(d.imag));
g.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "#4775de")
.attr("stroke-width", 1.5)
.attr("d", line);
return svg.node();
}
return svgServer(req, render(data).outerHTML);
}