github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/pkg/utils/eventsFormatutils.go (about)

     1  /*
     2  Copyright 2023.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package utils
    18  
    19  import (
    20  	"math"
    21  	"strconv"
    22  	"strings"
    23  )
    24  
    25  // format the numbers to string
    26  func roundPrec(x float64, prec int) float64 {
    27  	if math.IsNaN(x) || math.IsInf(x, 0) {
    28  		return x
    29  	}
    30  
    31  	sign := 1.0
    32  	if x < 0 {
    33  		sign = -1
    34  		x *= -1
    35  	}
    36  
    37  	var rounder float64
    38  	pow := math.Pow(10, float64(prec))
    39  	intermed := x * pow
    40  	_, frac := math.Modf(intermed)
    41  
    42  	if frac >= 0.5 {
    43  		rounder = math.Ceil(intermed)
    44  	} else {
    45  		rounder = math.Floor(intermed)
    46  	}
    47  
    48  	return rounder / pow * sign
    49  }
    50  
    51  func numberFormat(number float64, decimals int, decPoint, thousandsSep string) string {
    52  	if math.IsNaN(number) || math.IsInf(number, 0) {
    53  		number = 0
    54  	}
    55  
    56  	var ret string
    57  	var negative bool
    58  
    59  	if number < 0 {
    60  		number *= -1
    61  		negative = true
    62  	}
    63  
    64  	d, fract := math.Modf(number)
    65  
    66  	if decimals <= 0 {
    67  		fract = 0
    68  	} else {
    69  		pow := math.Pow(10, float64(decimals))
    70  		fract = roundPrec(fract*pow, 0)
    71  	}
    72  
    73  	if thousandsSep == "" {
    74  		ret = strconv.FormatFloat(d, 'f', 0, 64)
    75  	} else if d >= 1 {
    76  		var x float64
    77  		for d >= 1 {
    78  			d, x = math.Modf(d / 1000)
    79  			x = x * 1000
    80  			ret = strconv.FormatFloat(x, 'f', 0, 64) + ret
    81  			if d >= 1 {
    82  				ret = thousandsSep + ret
    83  			}
    84  		}
    85  	} else {
    86  		ret = "0"
    87  	}
    88  
    89  	fracts := strconv.FormatFloat(fract, 'f', 0, 64)
    90  
    91  	// "0" pad left
    92  	for i := len(fracts); i < decimals; i++ {
    93  		fracts = "0" + fracts
    94  	}
    95  
    96  	ret += decPoint + fracts
    97  
    98  	if negative {
    99  		ret = "-" + ret
   100  	}
   101  	return ret
   102  }
   103  
   104  func roundInt(input float64) int {
   105  	var result float64
   106  
   107  	if input < 0 {
   108  		result = math.Ceil(input - 0.5)
   109  	} else {
   110  		result = math.Floor(input + 0.5)
   111  	}
   112  
   113  	// only interested in integer, ignore fractional
   114  	i, _ := math.Modf(result)
   115  
   116  	return int(i)
   117  }
   118  
   119  func formatNumber(input float64) string {
   120  	x := roundInt(input)
   121  	xFormatted := numberFormat(float64(x), 2, ".", ",")
   122  	return xFormatted
   123  }
   124  
   125  func NearestThousandFormat(num float64) string {
   126  
   127  	if math.Abs(num) < 1000 {
   128  		xNum := formatNumber(num)
   129  		xNumStr := xNum[:len(xNum)-3]
   130  		return string(xNumStr)
   131  	}
   132  
   133  	xNum := formatNumber(num)
   134  	// first, remove the .00 then convert to slice
   135  	xNumStr := xNum[:len(xNum)-3]
   136  	xNumCleaned := strings.Replace(xNumStr, ",", " ", -1)
   137  	xNumSlice := strings.Fields(xNumCleaned)
   138  	count := len(xNumSlice) - 2
   139  	unit := [4]string{" K", " Million", " Billion", " Trillion"}
   140  	xPart := unit[count]
   141  
   142  	afterDecimal := ""
   143  	if xNumSlice[1][0] != 0 {
   144  		afterDecimal = string(xNumSlice[1][0])
   145  	}
   146  	final := xNumSlice[0] + afterDecimal + xPart
   147  	return final
   148  }