BangleApps/apps/coin_info/lib.js

116 lines
3.0 KiB
JavaScript

/**
* Formats a number string with common prefixes like K, M, B, T.
* For negative numbers, it returns "Negative".
* For numbers between 0 and 1, it rounds up to two decimal places.
*
* @param {string} input - The input string containing numerals.
* @returns {string} The formatted string.
*/
exports.formatPriceString = function(input) {
// Ensure input is a number
let number = typeof input === 'string' ? parseFloat(input) : input;
// Check if input is not a number
if (isNaN(number)) {
return 'Invalid input';
}
// Handle negative numbers
if (number < 0) {
return 'Negative';
}
// Handle zero
if (number === 0) {
return 'Zero';
}
// Handle numbers between 0 and 1
if (number < 1) {
return Math.ceil(number * 100) / 100;
}
// Define suffixes
const suffixes = ['', 'K', 'M', 'B', 'T'];
// Determine the suffix index
let suffixIndex = 0;
while (number >= 1000 && suffixIndex < suffixes.length - 1) {
number /= 1000;
suffixIndex++;
}
// Format the number with three decimal places after the comma
const formattedNumber = number.toFixed(3) + suffixes[suffixIndex];
return formattedNumber;
}
exports.findMinMax = function(values) {
var min = values[0];
var max = values[0];
for (var i = 1; i < values.length; i++) {
if (values[i] < min) min = values[i];
if (values[i] > max) max = values[i];
}
return { min: min, max: max };
}
exports.myLog10 = function(value) {
return Math.log(value) / Math.LN10;
}
exports.calculateOptimalYAxisSpacing = function(data) {
// Check if data is empty
if (data.length === 0) {
return { min: 0, max: 1, interval: 1 };
}
// Find the minimum and maximum values in the data
const bounds = exports.findMinMax(data);
let minY = bounds.min;
let maxY = bounds.max;
// Calculate the range of the data
let range = maxY - minY;
// If all values are the same, set a small range to avoid division by zero
if (range === 0) {
range = 1;
}
// Determine the number of ticks (e.g., 5 to 10 ticks)
let numTicks = 7; // You can adjust this value based on your preference
// Calculate the interval
let interval = range / (numTicks - 1);
// Round the interval to a nice number (e.g., 1, 2, 5, 10)
let roundedInterval = Math.pow(10, Math.floor(exports.myLog10(interval)));
if (interval / roundedInterval > 5) {
roundedInterval *= 5;
} else if (interval / roundedInterval > 2) {
roundedInterval *= 2;
}
// Adjust min and max to ensure they are on the rounded interval
let adjustedMin = Math.floor(minY / roundedInterval) * roundedInterval;
let adjustedMax = Math.ceil(maxY / roundedInterval) * roundedInterval;
let first = data[0];
let last = data[data.length - 1];
return {
min: adjustedMin,
max: adjustedMax,
interval: roundedInterval,
first: first,
last: last,
rawMin: minY,
rawMax: maxY
};
}