diff --git a/docs/content/components/usage-bar.mdx b/docs/content/components/usage-bar.mdx
index f0bb3675..bac48f5b 100644
--- a/docs/content/components/usage-bar.mdx
+++ b/docs/content/components/usage-bar.mdx
@@ -19,6 +19,8 @@ date: 2019-06-06
```
+
+
diff --git a/src/components/UsageBar/index.tsx b/src/components/UsageBar/index.tsx
index 4d77c2e2..4635c93f 100644
--- a/src/components/UsageBar/index.tsx
+++ b/src/components/UsageBar/index.tsx
@@ -36,6 +36,7 @@ const UsageBar: React.FC = props => {
hideRight,
showZeroMax,
withUnavailable,
+ formatType,
} = props;
const hasNow = props.hasOwnProperty('now');
const hasPercent = props.hasOwnProperty('percent');
@@ -44,8 +45,8 @@ const UsageBar: React.FC = props => {
const errorPercent = props.unavailableData && max && props.unavailableData / max;
let nowValue: number | string | undefined = now;
let maxValue: number | string | undefined = max;
- let nowSuffix = '';
- let maxSuffix = '';
+ let nowSuffix: any = '';
+ let maxSuffix: any = '';
let left;
let right;
let bsStyle;
@@ -57,14 +58,19 @@ const UsageBar: React.FC = props => {
nowSuffix = maxSuffix = '%';
}
- if (isByte) {
+ if (isByte || formatType) {
// hasPercent 表明左边数据设置完成(百分比形式),不需要再调整
+ let byteOptions: object = { splitUnit: true };
+ if (formatType) {
+ byteOptions = { splitUnit: true, formatType };
+ }
+
if (!hasPercent && now) {
- const nowArr: any = xbytes(now, { splitUnit: true });
+ const nowArr: any = xbytes(now, byteOptions);
nowValue = nowArr[0];
nowSuffix = nowArr[1];
}
- const maxArr: any = max && xbytes(max, { splitUnit: true });
+ const maxArr: any = max && xbytes(max, byteOptions);
maxValue = maxArr[0];
maxSuffix = maxArr[1];
} else if (isBulk) {
@@ -155,6 +161,10 @@ UsageBar.propTypes = {
* 数字以字节(B, KB, MB, GB...)为单位展示
**/
isByte: PropTypes.bool,
+ /**
+ * 格式化输出,可选[decimal|binary]
+ **/
+ formatType: PropTypes.string,
/**
* 数字以数量(万, 亿, 兆, 京...)为单位展示
**/
diff --git a/src/interface.tsx b/src/interface.tsx
index 1a8f500b..8f3f857b 100644
--- a/src/interface.tsx
+++ b/src/interface.tsx
@@ -90,6 +90,7 @@ export interface UsageBarProps {
hideRight?: boolean;
showZeroMax?: boolean;
withUnavailable?: boolean;
+ formatType?: string;
}
export interface LoaderProps {
diff --git a/src/utils/bulk.ts b/src/utils/bulk.ts
index 17c68883..00171dd4 100644
--- a/src/utils/bulk.ts
+++ b/src/utils/bulk.ts
@@ -40,7 +40,7 @@ export default function bulk(value: number, options: OPTIONS, locale?: LocaleTyp
i++;
}
unit = BULK[i - 1][1];
- let resultValue: any = value / (BULK[i - 1][0] as number);
+ let resultValue: number = value / +BULK[i - 1][0];
if (parseInt(String(resultValue), 10) !== resultValue) {
resultValue = Number(resultValue.toFixed(2));
}
diff --git a/src/utils/xbytes.ts b/src/utils/xbytes.ts
index 4eb82c00..2d21d155 100644
--- a/src/utils/xbytes.ts
+++ b/src/utils/xbytes.ts
@@ -1,17 +1,22 @@
interface OPTIONS {
- unitSeparator?: boolean
- decimalPlaces?: number
- fixedDecimals?: boolean
- toUnit?: string
- withoutFloat?: boolean
- splitUnit?: boolean
- thousandsSeparator?: string
+ formatType?: string;
+ unitSeparator?: boolean;
+ decimalPlaces?: number;
+ fixedDecimals?: boolean;
+ toUnit?: string;
+ withoutFloat?: boolean;
+ splitUnit?: boolean;
+ thousandsSeparator?: string;
+}
+
+type Map = {
+ [key: string] : number;
}
const formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g;
const formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/;
-const map = {
+const basicMap = {
b: 1,
kb: 1 << 10,
mb: 1 << 20,
@@ -22,19 +27,55 @@ const map = {
zb: (1 << 30) * Math.pow(1024, 4),
};
+const binaryMap= {
+ b: 1,
+ kib: 1 << 10,
+ mib: 1 << 20,
+ gib: 1 << 30,
+ tib: (1 << 30) * 1024,
+ pib: (1 << 30) * Math.pow(1024, 2),
+ eib: (1 << 30) * Math.pow(1024, 3),
+ zib: (1 << 30) * Math.pow(1024, 4),
+};
+
+const decimal = 1000;
+const decimalMap = {
+ b: 1,
+ kb: Math.pow(decimal, 1),
+ mb: Math.pow(decimal, 2),
+ gb: Math.pow(decimal, 3),
+ tb: Math.pow(decimal, 4),
+ pb: Math.pow(decimal, 5),
+ eb: Math.pow(decimal, 6),
+ zb: Math.pow(decimal, 7),
+};
+
const numberIsFinite = Number.isFinite || (v => typeof v === 'number' && isFinite(v));
// 原正则 https://www.npmjs.com/package/bytes (存在bug:当传入 '1.2345678901234568e+29GB'字符串进行转换时,结果为 1)
// const parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb|pb|eb|zb)$/i;
// 2018-12-19 兼容科学计数法: 1.2345678901234568e+29
-const parseRegExp = /^((-|\+)?(\d+(?:\.\d*[Ee+-]*\d+)?)) *(kb|mb|gb|tb|pb|eb|zb)$/i;
+const basicParseRegExp = /^((-|\+)?(\d+(?:\.\d*[Ee+-]*\d+)?)) *(kb|mb|gb|tb|pb|eb|zb)$/i;
+const decimalParseRegExp = basicParseRegExp;
+const binaryParseRegExp = /^((-|\+)?(\d+(?:\.\d*[Ee+-]*\d+)?)) *(kib|mib|gib|tib|pib|eib|zib)$/i;
function format(value: number, options: OPTIONS) {
if (!numberIsFinite(value)) {
return null;
}
+ let map: Map = basicMap;
+ if (options && options.formatType) {
+ if (options.formatType === 'decimal') {
+ map = decimalMap;
+ }
+
+ if (options.formatType === 'binary') {
+ map = binaryMap;
+ }
+ }
+
const mag = Math.abs(value);
const thousandsSeparator =
options && options.thousandsSeparator ? options.thousandsSeparator : '';
@@ -82,10 +123,10 @@ function format(value: number, options: OPTIONS) {
if (!isNaN(Number(str))) str = Number(str);
return [str, unit.toUpperCase()];
}
- return str + unitSeparator + unit.toUpperCase();
+ return str + unitSeparator + unit.toUpperCase().replace('I','i');
}
-function parse(val: string) {
+function parse(val: string, options: OPTIONS) {
if (typeof val === 'number' && !isNaN(val)) {
return val;
}
@@ -94,6 +135,21 @@ function parse(val: string) {
return null;
}
+ let parseRegExp = basicParseRegExp;
+ let map: Map = basicMap;
+
+ if (options && options.formatType) {
+ if (options.formatType === 'decimal') {
+ map = decimalMap;
+ parseRegExp = decimalParseRegExp;
+ }
+
+ if (options.formatType === 'binary') {
+ map = binaryMap;
+ parseRegExp = binaryParseRegExp;
+ }
+ }
+
const results = parseRegExp.exec(val);
let floatValue;
let unit = 'b';
@@ -111,7 +167,7 @@ function parse(val: string) {
export default function xbytes(value: number | string, options: OPTIONS) {
if (typeof value === 'string') {
- return parse(value);
+ return parse(value, options);
}
if (typeof value === 'number') {