Skip to content
This repository has been archived by the owner on Nov 14, 2023. It is now read-only.

Commit

Permalink
feat: Add format usage bar. (#107)
Browse files Browse the repository at this point in the history
* feat: Add format usage bar.

* update
  • Loading branch information
shenghou authored Apr 1, 2020
1 parent cbba423 commit ab69028
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 18 deletions.
2 changes: 2 additions & 0 deletions docs/content/components/usage-bar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ date: 2019-06-06
```
<div>
<UsageBar now={900000} max={7000000} isByte />
<UsageBar percent={900000/7000000} max={7000000} formatType="decimal" />
<UsageBar percent={900000/7000000} max={7000000} formatType="binary" />
<UsageBar percent={900000/7000000} max={7000000} isByte />
<UsageBar now={900000} max={7000000} isByte withPercent />
<UsageBar now={900000} max={7000000} isByte withPercent hideNow/>
Expand Down
20 changes: 15 additions & 5 deletions src/components/UsageBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const UsageBar: React.FC<UsageBarProps> = props => {
hideRight,
showZeroMax,
withUnavailable,
formatType,
} = props;
const hasNow = props.hasOwnProperty('now');
const hasPercent = props.hasOwnProperty('percent');
Expand All @@ -45,8 +46,8 @@ const UsageBar: React.FC<UsageBarProps> = 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;
Expand All @@ -58,14 +59,19 @@ const UsageBar: React.FC<UsageBarProps> = 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) {
Expand Down Expand Up @@ -156,6 +162,10 @@ UsageBar.propTypes = {
* 数字以字节(B, KB, MB, GB...)为单位展示
**/
isByte: PropTypes.bool,
/**
* 格式化输出,可选[decimal|binary]
**/
formatType: PropTypes.string,
/**
* 数字以数量(万, 亿, 兆, 京...)为单位展示
**/
Expand Down
1 change: 1 addition & 0 deletions src/interface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export interface UsageBarProps {
hideRight?: boolean;
showZeroMax?: boolean;
withUnavailable?: boolean;
formatType?: string;
}

export interface LoaderProps {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/bulk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
80 changes: 68 additions & 12 deletions src/utils/xbytes.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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 : '';
Expand Down Expand Up @@ -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;
}
Expand All @@ -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';
Expand All @@ -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') {
Expand Down

0 comments on commit ab69028

Please sign in to comment.