Update
This commit is contained in:
35
Server/app/svelte/public/js/libraries/cssTools.js
Normal file
35
Server/app/svelte/public/js/libraries/cssTools.js
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
export default class CssTools {
|
||||
|
||||
static applyCSS(element,id,outerclass,classlisthint) {
|
||||
// Return if no CSS to apply
|
||||
if (classlisthint==null || (outerclass==null && id==null)) {
|
||||
return
|
||||
}
|
||||
|
||||
let outerClassNames = outerclass.split(" ").map(x => "."+x)
|
||||
let outerCssSelectors = [...outerClassNames,"#"+id]
|
||||
|
||||
let styleSheets = document.styleSheets
|
||||
let l = styleSheets.length
|
||||
for (let i=0; i<l; i++) {
|
||||
let sheet = styleSheets[i]
|
||||
let name = sheet.href.split("/").at(-1).split(".")[0]
|
||||
if (name===classlisthint) {
|
||||
for (let outerCss of outerCssSelectors) {
|
||||
for (let rule of sheet.cssRules) {
|
||||
if (rule.selectorText==outerCss) {
|
||||
let styleRule = rule.style
|
||||
let vals = Object.values(styleRule)
|
||||
for (let val of vals) {
|
||||
element.style[val] = styleRule[val]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
146
Server/app/svelte/public/js/libraries/mathTools.js
Normal file
146
Server/app/svelte/public/js/libraries/mathTools.js
Normal file
@@ -0,0 +1,146 @@
|
||||
|
||||
// Broadcast array on array
|
||||
export function bAr(fun,ar1,ar2) {
|
||||
var result = new Array(ar1.length)
|
||||
for (var i = 0;i<ar1.length;i++) {
|
||||
result[i] = fun(ar1[i],ar2[i])
|
||||
}
|
||||
return(result)
|
||||
}
|
||||
|
||||
// Broadcast array on a number
|
||||
export function b(fun,ar1,val) {
|
||||
var result = new Array(ar1.length)
|
||||
for (var i = 0;i<ar1.length;i++) {
|
||||
result[i] = fun(ar1[i],val)
|
||||
}
|
||||
return(result)
|
||||
}
|
||||
|
||||
// Broadcast array on a function
|
||||
export function bFun(fun,ar1) {
|
||||
var result = new Array(ar1.length)
|
||||
for (var i = 0;i<ar1.length;i++) {
|
||||
result[i] = fun(ar1[i])
|
||||
}
|
||||
return(result)
|
||||
}
|
||||
|
||||
export function multiply(num1, num2) {
|
||||
let result = num1 * num2;
|
||||
return result;
|
||||
}
|
||||
|
||||
export function sum(ar) {
|
||||
return ar.reduce((a, b) => a + b, 0)
|
||||
}
|
||||
|
||||
export function prod(ar) {
|
||||
return ar.reduce((a, b) => a * b, 1)
|
||||
}
|
||||
|
||||
export function mean(ar) {
|
||||
return ar.reduce((a, b) => a + b, 0)/ar.length
|
||||
}
|
||||
|
||||
export function median(values){
|
||||
if(values.length ===0) throw new Error("No inputs");
|
||||
|
||||
values.sort(function(a,b){
|
||||
return a-b;
|
||||
});
|
||||
|
||||
var half = Math.floor(values.length / 2);
|
||||
|
||||
if (values.length % 2)
|
||||
return values[half];
|
||||
|
||||
return (values[half - 1] + values[half]) / 2.0;
|
||||
}
|
||||
|
||||
export function range(start,end, step = start<end ? 1 : -1) {
|
||||
var arr = []
|
||||
if (step>0) {
|
||||
for (var i = start; i <= end; i += step) {
|
||||
arr.push(i)
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (var i = start; i >= end; i += step) {
|
||||
arr.push(i)
|
||||
}
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
export function numericallyIntegrate(f, a, b, dx) {
|
||||
|
||||
// calculate the number of trapezoids
|
||||
let n = (b - a) / dx
|
||||
|
||||
// define the variable for area
|
||||
let Area = 0
|
||||
|
||||
//loop to calculate the area of each trapezoid and sum.
|
||||
for (let i = 1; i <= n; i++) {
|
||||
//the x locations of the left and right side of each trapezpoid
|
||||
let x0 = a + (i-1)*dx
|
||||
let x1 = a + i*dx
|
||||
|
||||
// the area of each trapezoid
|
||||
let Ai = dx * (f(x0) + f(x1))/ 2.
|
||||
|
||||
// cumulatively sum the areas
|
||||
Area = Area + Ai
|
||||
|
||||
}
|
||||
return Area
|
||||
}
|
||||
|
||||
const randomNormals = () => {
|
||||
let u1 = 0, u2 = 0;
|
||||
//Convert [0,1) to (0,1)
|
||||
while (u1 === 0) u1 = Math.random();
|
||||
while (u2 === 0) u2 = Math.random();
|
||||
const R = Math.sqrt(-2.0 * Math.log(u1));
|
||||
const Θ = 2.0 * Math.PI * u2;
|
||||
return [R * Math.cos(Θ), R * Math.sin(Θ)];
|
||||
};
|
||||
|
||||
export function randomSkewNormal(ξ, ω, α = 0) {
|
||||
const [u0, v] = randomNormals();
|
||||
if (α === 0) {
|
||||
return ξ + ω * u0;
|
||||
}
|
||||
const 𝛿 = α / Math.sqrt(1 + α * α);
|
||||
const u1 = 𝛿 * u0 + Math.sqrt(1 - 𝛿 * 𝛿) * v;
|
||||
const z = u0 >= 0 ? u1 : -u1;
|
||||
return ξ + ω * z;
|
||||
};
|
||||
|
||||
export function percentile(arr, p) {
|
||||
arr.sort(function(a,b){
|
||||
return a-b;
|
||||
});
|
||||
if (arr.length === 0) return 0;
|
||||
if (typeof p !== 'number') throw new TypeError('p must be a number');
|
||||
if (p <= 0) return arr[0];
|
||||
if (p >= 1) return arr[arr.length - 1];
|
||||
|
||||
var index = (arr.length - 1) * p,
|
||||
lower = Math.floor(index),
|
||||
upper = lower + 1,
|
||||
weight = index % 1;
|
||||
|
||||
if (upper >= arr.length) return arr[lower];
|
||||
return arr[lower] * (1 - weight) + arr[upper] * weight;
|
||||
}
|
||||
|
||||
export function smooth(ar,window) {
|
||||
let windowHalf = window/2
|
||||
let windowHalf1 = Math.floor(windowHalf)
|
||||
let windowHalf2 = Math.ceil(windowHalf)
|
||||
for (let i=windowHalf1;i<ar.length-windowHalf2;i++) {
|
||||
ar[i] = mean(ar.slice(i-windowHalf1,i+windowHalf2))
|
||||
}
|
||||
}
|
112
Server/app/svelte/public/js/libraries/miscTools.js
Normal file
112
Server/app/svelte/public/js/libraries/miscTools.js
Normal file
@@ -0,0 +1,112 @@
|
||||
|
||||
export function isObject(v) {
|
||||
return typeof v === 'object' && !Array.isArray(v) && v !== null
|
||||
}
|
||||
|
||||
// Prevents excessive function calling
|
||||
export function debounce(func, timeout){
|
||||
let timer;
|
||||
return (...args) => {
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(() => { func.apply(this, args); }, timeout)
|
||||
}
|
||||
}
|
||||
|
||||
export function svgFromObject(object) {
|
||||
var objectDoc = object.contentDocument;
|
||||
var svgItem = objectDoc.querySelector("path");
|
||||
return svgItem
|
||||
}
|
||||
|
||||
export function rem2px(rem) {
|
||||
let fontSizeString = window.getComputedStyle(document.getElementsByTagName("html")[0]).getPropertyValue('font-size')
|
||||
let fontSize = parseFloat(fontSizeString.substring(0,fontSizeString.length-2))
|
||||
return fontSize * rem
|
||||
}
|
||||
|
||||
export function px2rem(px) {
|
||||
let fontSizeString = window.getComputedStyle(document.getElementsByTagName("html")[0]).getPropertyValue('font-size')
|
||||
let fontSize = parseFloat(fontSizeString.substring(0,fontSizeString.length-2))
|
||||
return px / fontSize
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses canvas.measureText to compute and return the width of the given text of given font in pixels.
|
||||
*
|
||||
* @param {String} text The text to be rendered.
|
||||
* @param {String} font The css font descriptor that text is to be rendered with (e.g. "bold 14px verdana").
|
||||
*
|
||||
* @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393
|
||||
*/
|
||||
|
||||
export function getTextWidth(text, font) {
|
||||
// re-use canvas object for better performance
|
||||
const canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
|
||||
const context = canvas.getContext("2d");
|
||||
context.font = font;
|
||||
const metrics = context.measureText(text);
|
||||
return metrics.width;
|
||||
}
|
||||
|
||||
function getCssStyle(element, prop) {
|
||||
return window.getComputedStyle(element, null).getPropertyValue(prop);
|
||||
}
|
||||
|
||||
export function getCanvasFont(el = document.body) {
|
||||
const fontWeight = getCssStyle(el, 'font-weight') || 'normal';
|
||||
const fontSize = getCssStyle(el, 'font-size') || '16px';
|
||||
const fontFamily = getCssStyle(el, 'font-family') || 'Times New Roman';
|
||||
|
||||
return `${fontWeight} ${fontSize} ${fontFamily}`;
|
||||
}
|
||||
|
||||
export function validateAge(event,input,callback) {
|
||||
event.returnValue = false
|
||||
var key
|
||||
if (event.type === 'paste') {
|
||||
key = event.clipboardData.getData('text/plain');
|
||||
}
|
||||
else {
|
||||
// Handle key press
|
||||
key = event.keyCode || event.which;
|
||||
key = String.fromCharCode(key);
|
||||
}
|
||||
let keys = ["0","1","2","3","4","5","6","7","8","9"]
|
||||
if (key in keys) {
|
||||
var val = parseFloat(input.value)
|
||||
if (val>120) {
|
||||
input.value = 120
|
||||
}
|
||||
else {
|
||||
input.value = val
|
||||
}
|
||||
if (callback!=undefined) {
|
||||
callback(input.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function validatePosNumber(event,input,callback,max) {
|
||||
event.returnValue = false
|
||||
var key
|
||||
if (event.type === 'paste') {
|
||||
key = event.clipboardData.getData('text/plain');
|
||||
}
|
||||
else {
|
||||
// Handle key press
|
||||
key = event.data;
|
||||
}
|
||||
let keys = ["0","1","2","3","4","5","6","7","8","9"]
|
||||
if (key in keys) {
|
||||
var val = parseFloat(input.value)
|
||||
if (val>max) {
|
||||
input.value = max
|
||||
}
|
||||
if (callback!=undefined) {
|
||||
callback(input.value)
|
||||
}
|
||||
}
|
||||
else {
|
||||
callback(input.value)
|
||||
}
|
||||
}
|
64
Server/app/svelte/public/js/libraries/serverTools.js
Normal file
64
Server/app/svelte/public/js/libraries/serverTools.js
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
// Get data from server
|
||||
export function getData(path,callback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.overrideMimeType("application/json");
|
||||
xhr.open('GET', path, true);
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4 && xhr.status == "200") {
|
||||
if (callback !== undefined) {
|
||||
callback(xhr.responseText);
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
// Parse JSON from given path into a given variable under a given key
|
||||
export function getJSON(variable,key,path) {
|
||||
getData(path,function(response) {
|
||||
// Parse JSON string into object
|
||||
variable[key] = JSON.parse(response);
|
||||
});
|
||||
}
|
||||
|
||||
export function sendData(route,data,callback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", route, true)
|
||||
xhr.setRequestHeader('Content-Type', 'application/json')
|
||||
xhr.onreadystatechange = function() {
|
||||
if(xhr.readyState === XMLHttpRequest.DONE) {
|
||||
var status = xhr.status;
|
||||
if (status === 0 || (status >= 200 && status < 400)) {
|
||||
// The request has been completed successfully
|
||||
if (callback !== undefined) {
|
||||
callback(xhr.responseText)
|
||||
}
|
||||
} else {
|
||||
// Oh no! There has been an error with the request!
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send(JSON.stringify(data))
|
||||
}
|
||||
|
||||
export function sendText(route,data,callback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", route, true)
|
||||
xhr.setRequestHeader('Content-Type', 'text/plain')
|
||||
xhr.onreadystatechange = function() {
|
||||
if(xhr.readyState === XMLHttpRequest.DONE) {
|
||||
var status = xhr.status;
|
||||
if (status === 0 || (status >= 200 && status < 400)) {
|
||||
// The request has been completed successfully
|
||||
if (callback !== undefined) {
|
||||
callback(xhr.responseText)
|
||||
}
|
||||
} else {
|
||||
// Oh no! There has been an error with the request!
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send(data)
|
||||
}
|
||||
|
Reference in New Issue
Block a user