159 lines
4.4 KiB
JavaScript
159 lines
4.4 KiB
JavaScript
import { defineComponent, h } from 'vue';
|
|
import { NBaseIcon } from "../../_internal/index.mjs";
|
|
import { ErrorIcon, InfoIcon, SuccessIcon, WarningIcon } from "../../_internal/icons/index.mjs";
|
|
const iconMap = {
|
|
success: h(SuccessIcon, null),
|
|
error: h(ErrorIcon, null),
|
|
warning: h(WarningIcon, null),
|
|
info: h(InfoIcon, null)
|
|
};
|
|
export default defineComponent({
|
|
name: 'ProgressCircle',
|
|
props: {
|
|
clsPrefix: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
status: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
strokeWidth: {
|
|
type: Number,
|
|
required: true
|
|
},
|
|
fillColor: String,
|
|
railColor: String,
|
|
railStyle: [String, Object],
|
|
percentage: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
offsetDegree: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
showIndicator: {
|
|
type: Boolean,
|
|
required: true
|
|
},
|
|
indicatorTextColor: String,
|
|
unit: String,
|
|
viewBoxWidth: {
|
|
type: Number,
|
|
required: true
|
|
},
|
|
gapDegree: {
|
|
type: Number,
|
|
required: true
|
|
},
|
|
gapOffsetDegree: {
|
|
type: Number,
|
|
default: 0
|
|
}
|
|
},
|
|
setup(props, {
|
|
slots
|
|
}) {
|
|
function getPathStyles(percent, offsetDegree, strokeColor) {
|
|
const {
|
|
gapDegree,
|
|
viewBoxWidth,
|
|
strokeWidth
|
|
} = props;
|
|
const radius = 50;
|
|
const beginPositionX = 0;
|
|
const beginPositionY = radius;
|
|
const endPositionX = 0;
|
|
const endPositionY = 2 * radius;
|
|
const centerX = 50 + strokeWidth / 2;
|
|
const pathString = `M ${centerX},${centerX} m ${beginPositionX},${beginPositionY}
|
|
a ${radius},${radius} 0 1 1 ${endPositionX},${-endPositionY}
|
|
a ${radius},${radius} 0 1 1 ${-endPositionX},${endPositionY}`;
|
|
const len = Math.PI * 2 * radius;
|
|
const pathStyle = {
|
|
stroke: strokeColor,
|
|
strokeDasharray: `${percent / 100 * (len - gapDegree)}px ${viewBoxWidth * 8}px`,
|
|
strokeDashoffset: `-${gapDegree / 2}px`,
|
|
transformOrigin: offsetDegree ? 'center' : undefined,
|
|
transform: offsetDegree ? `rotate(${offsetDegree}deg)` : undefined
|
|
};
|
|
return {
|
|
pathString,
|
|
pathStyle
|
|
};
|
|
}
|
|
return () => {
|
|
const {
|
|
fillColor,
|
|
railColor,
|
|
strokeWidth,
|
|
offsetDegree,
|
|
status,
|
|
percentage,
|
|
showIndicator,
|
|
indicatorTextColor,
|
|
unit,
|
|
gapOffsetDegree,
|
|
clsPrefix
|
|
} = props;
|
|
const {
|
|
pathString: railPathString,
|
|
pathStyle: railPathStyle
|
|
} = getPathStyles(100, 0, railColor);
|
|
const {
|
|
pathString: fillPathString,
|
|
pathStyle: fillPathStyle
|
|
} = getPathStyles(percentage, offsetDegree, fillColor);
|
|
const viewBoxSize = 100 + strokeWidth;
|
|
return h("div", {
|
|
class: `${clsPrefix}-progress-content`,
|
|
role: "none"
|
|
}, h("div", {
|
|
class: `${clsPrefix}-progress-graph`,
|
|
"aria-hidden": true
|
|
}, h("div", {
|
|
class: `${clsPrefix}-progress-graph-circle`,
|
|
style: {
|
|
transform: gapOffsetDegree ? `rotate(${gapOffsetDegree}deg)` : undefined
|
|
}
|
|
}, h("svg", {
|
|
viewBox: `0 0 ${viewBoxSize} ${viewBoxSize}`
|
|
}, h("g", null, h("path", {
|
|
class: `${clsPrefix}-progress-graph-circle-rail`,
|
|
d: railPathString,
|
|
"stroke-width": strokeWidth,
|
|
"stroke-linecap": "round",
|
|
fill: "none",
|
|
style: railPathStyle
|
|
})), h("g", null, h("path", {
|
|
class: [`${clsPrefix}-progress-graph-circle-fill`, percentage === 0 && `${clsPrefix}-progress-graph-circle-fill--empty`],
|
|
d: fillPathString,
|
|
"stroke-width": strokeWidth,
|
|
"stroke-linecap": "round",
|
|
fill: "none",
|
|
style: fillPathStyle
|
|
}))))), showIndicator ? h("div", null, slots.default ? h("div", {
|
|
class: `${clsPrefix}-progress-custom-content`,
|
|
role: "none"
|
|
}, slots.default()) : status !== 'default' ? h("div", {
|
|
class: `${clsPrefix}-progress-icon`,
|
|
"aria-hidden": true
|
|
}, h(NBaseIcon, {
|
|
clsPrefix: clsPrefix
|
|
}, {
|
|
default: () => iconMap[status]
|
|
})) : h("div", {
|
|
class: `${clsPrefix}-progress-text`,
|
|
style: {
|
|
color: indicatorTextColor
|
|
},
|
|
role: "none"
|
|
}, h("span", {
|
|
class: `${clsPrefix}-progress-text__percentage`
|
|
}, percentage), h("span", {
|
|
class: `${clsPrefix}-progress-text__unit`
|
|
}, unit))) : null);
|
|
};
|
|
}
|
|
}); |