UNPKG

mdsjs

Version:

MDS and PCA projections in JavaScript

175 lines (158 loc) 5.13 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta http-equiv="x-ua-compatible" content="ie=edge" /> <!-- Google tag (gtag.js) --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-4DHJEMESJD" ></script> <script> window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'G-4DHJEMESJD'); </script> <!-- Google tag end --> <title>mds - js</title> <link rel="canonical" href="https://mdsjs.josuakrause.com/" /> <link rel="stylesheet" href="./index.css" /> </head> <body style="margin: 20px auto; width: 800px"> <p style="float: right"> <canvas id="canvas" width="400" height="400" style="width: 400px; height: 400px" ></canvas> </p> <p> <button id="recompute">recompute</button> <button id="switch">switch</button> <button id="source">source</button> </p> <p>Computing: <span id="mode"></span></p> Input: <pre id="matrix" style="height: 200px; overflow: auto"></pre> Output: <pre id="output" style="height: 200px; overflow: auto"></pre> <pre id="sourceview"></pre> <script type="module" id="jsmain" defer> import mdsjs from './mdsjs.js'; mdsjs.DEBUG = true; function start() { if (mds) { computeMDS(); } else { computePCA(); } updateSource(); } document.getElementById('recompute').addEventListener('click', start); let mds = true; function chg() { mds = !mds; start(); } document.getElementById('switch').addEventListener('click', chg); let showSource = false; function toggleSource() { showSource = !showSource; updateSource(); } document .getElementById('source') .addEventListener('click', toggleSource); function updateSource() { const elem = document.getElementById('sourceview'); if (showSource) { elem.innerText = mds ? computeMDS : computePCA; } else { elem.innerText = ''; } } function computeMDS() { const a = mdsjs.convertToMatrix( [ [0, 2, 2, 4, 6, 6, 4, 6, 6], [2, 0, 2, 2, 3, 4, 2, 3, 4], [2, 2, 0, 4, 4, 6, 4, 4, 6], [4, 2, 4, 0, 1, 1, 4, 6, 6], [6, 3, 4, 1, 0, 1, 2, 3, 4], [6, 4, 6, 1, 1, 0, 4, 4, 6], [4, 2, 4, 4, 2, 4, 0, 1, 1], [6, 3, 4, 6, 3, 4, 1, 0, 1], [6, 4, 6, 6, 4, 6, 1, 1, 0], ], true, ); mdsjs.landmarkMDSAsync(a, 2, (points) => { const ctx = document.getElementById('canvas').getContext('2d'); ctx.clearRect(0, 0, 400, 400); ctx.beginPath(); ctx.rect(0, 0, 400, 400); ctx.stroke(); points.rowsIter((row) => { const x = row[0] * 50 + 200; const y = row[1] * 50 + 200; ctx.fillRect(x - 2, y - 2, 4, 4); }); document.getElementById('mode').innerText = 'mds'; document.getElementById('output').innerText = '' + points; document.getElementById('matrix').innerText = '' + a; }); } function computePCA() { const /** @type {number[][]} */ posArr = []; const /** @type {number} */ xspread = 180; const /** @type {number} */ yspread = 150; for (let ix = 0; ix < 1000; ix += 1) { const rnd = Math.random() * 2 * Math.PI; posArr.push([Math.cos(rnd) * xspread, Math.sin(rnd) * yspread]); } const pos = mdsjs.convertToMatrix(posArr); mdsjs.pcaAsync(pos, (pca) => { const points = pos.mul(pca); const ctx = document.getElementById('canvas').getContext('2d'); ctx.clearRect(0, 0, 400, 400); ctx.beginPath(); ctx.rect(0, 0, 400, 400); ctx.stroke(); ctx.save(); ctx.fillStyle = 'blue'; pos.rowsIter((row) => { const x = row[0] + 200; const y = row[1] + 200; ctx.fillRect(x - 2, y - 2, 4, 4); }); ctx.restore(); ctx.save(); ctx.fillStyle = 'red'; points.rowsIter((row) => { const x = row[0] + 200; const y = row[1] + 200; ctx.fillRect(x - 2, y - 2, 4, 4); }); ctx.restore(); document.getElementById('mode').innerText = 'pca'; document.getElementById('output').innerText = `${pca}\n${points}`; document.getElementById('matrix').innerText = `${pos}`; }); } start(); </script> <footer> <div class="footer-style"> © jk 2023 <a href="https://github.com/JosuaKrause/mdsjs" target="_blank"> [source] </a> </div> </footer> </body> </html>