feat(工作台): 调整优化工作台饼图
This commit is contained in:
parent
efa4a1f319
commit
8dc9e2b022
|
@ -243,8 +243,8 @@ export const commonRatePieOptions = {
|
|||
title: {
|
||||
show: true,
|
||||
text: '',
|
||||
left: 26,
|
||||
top: '20%',
|
||||
left: 40,
|
||||
top: '26%',
|
||||
textStyle: {
|
||||
fontSize: 12,
|
||||
fontWeight: 'normal',
|
||||
|
@ -276,16 +276,14 @@ export const commonRatePieOptions = {
|
|||
name: '',
|
||||
type: 'pie',
|
||||
color: [],
|
||||
padAngle: 2,
|
||||
radius: ['85%', '100%'],
|
||||
center: [30, '50%'],
|
||||
radius: ['65%', '80%'],
|
||||
center: [44, '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center',
|
||||
},
|
||||
emphasis: {
|
||||
scale: false, // 禁用放大效果
|
||||
label: {
|
||||
show: false,
|
||||
fontSize: 40,
|
||||
|
|
|
@ -173,7 +173,7 @@
|
|||
const coverTitleConfig = computed(() => {
|
||||
return {
|
||||
name: t('workbench.homePage.apiCoverage'),
|
||||
color: ['#EDEDF1', '#00C261'],
|
||||
color: ['#D4D4D8', '#00C261'],
|
||||
tooltipText:
|
||||
props.item.key === WorkCardEnum.API_CASE_COUNT
|
||||
? t('workbench.homePage.apiCaseCountCoverRateTooltip')
|
||||
|
@ -185,12 +185,12 @@
|
|||
return props.item.key === WorkCardEnum.API_CASE_COUNT
|
||||
? {
|
||||
name: t('workbench.homePage.caseExecutionRate'),
|
||||
color: ['#EDEDF1', '#00C261'],
|
||||
color: ['#D4D4D8', '#00C261'],
|
||||
tooltipText: t('workbench.homePage.apiCaseCountExecuteRateTooltip'),
|
||||
}
|
||||
: {
|
||||
name: t('workbench.homePage.sceneExecutionRate'),
|
||||
color: ['#EDEDF1', '#00C261'],
|
||||
color: ['#D4D4D8', '#00C261'],
|
||||
tooltipText: t('workbench.homePage.scenarioCaseCountExecuteRateTooltip'),
|
||||
};
|
||||
});
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
<PassRatePie
|
||||
:tooltip-text="tabItem.tooltip"
|
||||
:options="tabItem.options"
|
||||
:size="60"
|
||||
:loading="tabItem.value === 'cover' ? loading : undefined"
|
||||
:has-permission="hasPermission"
|
||||
:value-list="tabItem.valueList"
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
<PassRatePie
|
||||
:options="tabItem.options"
|
||||
:tooltip-text="tabItem.tooltip"
|
||||
:size="60"
|
||||
:value-list="tabItem.valueList"
|
||||
:has-permission="hasPermission"
|
||||
/>
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
<PassRatePie
|
||||
:options="options"
|
||||
tooltip-text="workbench.homePage.caseReviewCoverRateTooltip"
|
||||
:size="60"
|
||||
:value-list="coverValueList"
|
||||
:has-permission="hasPermission"
|
||||
/>
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
:has-permission="hasPermission"
|
||||
:tooltip-text="tooltip"
|
||||
:options="legacyOptions"
|
||||
:size="60"
|
||||
:value-list="legacyValueList"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<div class="flex w-full flex-col gap-4">
|
||||
<div
|
||||
v-for="(ele, i) of currentData"
|
||||
:key="`ele.status-${i}`"
|
||||
:key="`${ele.status}-${i}`"
|
||||
class="grid flex-1 grid-cols-3 gap-4"
|
||||
@mouseover="handleMouseOver(ele.status)"
|
||||
@mouseout="handleMouseOut(ele.status)"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
>
|
||||
<div class="tooltip-rate h-[50px] w-[50px]"></div>
|
||||
</a-tooltip>
|
||||
<MsChart :height="`${props.size}px`" :width="`${props.size}px`" :options="props.options" />
|
||||
<MsChart height="92px" width="92px" :options="props.options" />
|
||||
</div>
|
||||
<div class="pass-rate-title flex-1">
|
||||
<div v-for="item of props.valueList" :key="item.label" class="flex-1">
|
||||
|
@ -30,7 +30,6 @@
|
|||
|
||||
const props = defineProps<{
|
||||
options: Record<string, any>;
|
||||
size: number;
|
||||
tooltipText?: string;
|
||||
hasPermission: boolean;
|
||||
loading?: boolean;
|
||||
|
@ -43,8 +42,9 @@
|
|||
|
||||
<style scoped lang="less">
|
||||
.pass-rate-content {
|
||||
padding: 16px;
|
||||
padding: 0 16px;
|
||||
width: 100%;
|
||||
height: 92px;
|
||||
border-radius: 6px;
|
||||
background: var(--color-text-n9);
|
||||
@apply flex items-center;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<a-spin class="w-full" :loading="props.loading">
|
||||
<div class="rate-content relative">
|
||||
<div class="rate-content relative flex flex-col items-center">
|
||||
<div class="relative flex h-full w-full items-center justify-center">
|
||||
<a-tooltip
|
||||
v-if="props.rateConfig.tooltipText"
|
||||
|
@ -10,7 +10,38 @@
|
|||
>
|
||||
<div class="tooltip-rate-tooltip"></div>
|
||||
</a-tooltip>
|
||||
<MsChart :options="options" width="146px" />
|
||||
<MsChart ref="chartRef" :options="options" width="100px" height="100px" />
|
||||
</div>
|
||||
<div class="flex w-full items-center justify-center">
|
||||
<div class="flex w-[80%] flex-col gap-[8px]">
|
||||
<template v-if="props.hasPermission">
|
||||
<div
|
||||
v-for="(ele, i) of legend"
|
||||
:key="`${ele.name}-${i}`"
|
||||
class="flex justify-between"
|
||||
@mouseover="handleMouseOver(ele.name)"
|
||||
@mouseout="handleMouseOut(ele.name)"
|
||||
>
|
||||
<div class="flex items-center text-left text-[var(--color-text-3)]">
|
||||
<div
|
||||
:style="{
|
||||
background: ele.selected ? `${ele.color}` : '#D4D4D8',
|
||||
}"
|
||||
class="mr-[8px] h-[8px] w-[8px] cursor-pointer rounded-lg"
|
||||
@click="toggleLegend(ele.name, i)"
|
||||
>
|
||||
</div>
|
||||
{{ ele.name }}
|
||||
</div>
|
||||
<div class="text-[16px] text-[rgb(var(--primary-5))]">{{ addCommasToNumber(ele.value) }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else class="mt-[16px] flex h-full flex-1 items-center justify-center">
|
||||
<div class="rounded bg-[var(--color-text-n9)] px-[16px] py-[4px] text-[var(--color-text-4)]">
|
||||
{{ t('workbench.homePage.notHasResPermission') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
|
@ -43,7 +74,7 @@
|
|||
show: true,
|
||||
text: '',
|
||||
left: 'center',
|
||||
top: 32,
|
||||
top: 30,
|
||||
textStyle: {
|
||||
fontSize: 12,
|
||||
fontWeight: 'normal',
|
||||
|
@ -65,7 +96,9 @@
|
|||
tooltip: {
|
||||
show: true,
|
||||
},
|
||||
color: [],
|
||||
legend: {
|
||||
show: false,
|
||||
orient: 'vertical',
|
||||
itemWidth: 8, // 图例标记的宽度
|
||||
itemHeight: 8, // 图例标记的高度
|
||||
|
@ -102,8 +135,8 @@
|
|||
series: {
|
||||
name: '',
|
||||
type: 'pie',
|
||||
radius: ['50%', '58%'],
|
||||
center: ['50%', '32%'],
|
||||
radius: ['75%', '90%'],
|
||||
center: ['50%', '50%'],
|
||||
color: [],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
|
@ -122,31 +155,52 @@
|
|||
},
|
||||
data: [],
|
||||
},
|
||||
graphic: {
|
||||
type: 'text',
|
||||
left: 'center',
|
||||
bottom: 10,
|
||||
style: {
|
||||
text: t('workbench.homePage.notHasResPermission'),
|
||||
fontSize: 14,
|
||||
fill: '#959598',
|
||||
backgroundColor: '#F9F9FE',
|
||||
padding: [6, 16, 6, 16],
|
||||
borderRadius: 4,
|
||||
},
|
||||
invisible: false,
|
||||
},
|
||||
// graphic: {
|
||||
// type: 'text',
|
||||
// left: 'center',
|
||||
// bottom: 10,
|
||||
// style: {
|
||||
// text: t('workbench.homePage.notHasResPermission'),
|
||||
// fontSize: 14,
|
||||
// fill: '#959598',
|
||||
// backgroundColor: '#F9F9FE',
|
||||
// padding: [6, 16, 6, 16],
|
||||
// borderRadius: 4,
|
||||
// },
|
||||
// invisible: false,
|
||||
// },
|
||||
});
|
||||
|
||||
const legend = ref<{ name: string; value: number; color: string; selected: boolean }[]>([]);
|
||||
|
||||
function initOptions() {
|
||||
const { name, color } = props.rateConfig;
|
||||
options.value.series.data = [...props.data.slice(1)].map((e) => {
|
||||
const temData = [...props.data.slice(1)];
|
||||
const hasDataLength = temData.filter((e) => Number(e.value) > 0).length;
|
||||
|
||||
const pieBorderWidth = hasDataLength === 1 ? 0 : 1;
|
||||
|
||||
options.value.series.data =
|
||||
hasDataLength > 0
|
||||
? temData.map((e) => {
|
||||
return {
|
||||
...e,
|
||||
tooltip: {
|
||||
...toolTipConfig,
|
||||
show: !!props.hasPermission,
|
||||
},
|
||||
itemStyle: {
|
||||
borderWidth: pieBorderWidth,
|
||||
borderColor: '#ffffff',
|
||||
},
|
||||
};
|
||||
})
|
||||
: [];
|
||||
legend.value = [...props.data.slice(1)].map((e, i) => {
|
||||
return {
|
||||
...e,
|
||||
tooltip: {
|
||||
...toolTipConfig,
|
||||
show: !!props.hasPermission,
|
||||
},
|
||||
selected: true,
|
||||
color: color[i],
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -162,13 +216,48 @@
|
|||
options.value.title.subtext = `-%`;
|
||||
}
|
||||
|
||||
options.value.graphic.invisible = !!props.hasPermission;
|
||||
options.value.tooltip.show = !!props.hasPermission;
|
||||
options.value.title.text = name;
|
||||
|
||||
options.value.series.color = color;
|
||||
}
|
||||
|
||||
const chartRef = ref<InstanceType<typeof MsChart>>();
|
||||
function toggleLegend(name: string, index: number) {
|
||||
const chart = chartRef.value?.chartRef;
|
||||
if (chart) {
|
||||
chart.dispatchAction({
|
||||
type: 'legendToggleSelect',
|
||||
name,
|
||||
});
|
||||
|
||||
if (legend.value) {
|
||||
legend.value[index].selected = !legend.value[index].selected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 悬浮放大交互效果
|
||||
function handleMouseOver(name: string) {
|
||||
const chart = chartRef.value?.chartRef;
|
||||
if (chart) {
|
||||
chart.dispatchAction({
|
||||
type: 'highlight',
|
||||
name,
|
||||
});
|
||||
}
|
||||
}
|
||||
// 移除放大交互效果
|
||||
function handleMouseOut(name: string) {
|
||||
const chart = chartRef.value?.chartRef;
|
||||
if (chart) {
|
||||
chart.dispatchAction({
|
||||
type: 'downplay',
|
||||
name,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
(val) => {
|
||||
|
@ -191,15 +280,12 @@
|
|||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.rate-content {
|
||||
height: 158px;
|
||||
}
|
||||
.tooltip-rate-tooltip {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
top: 20px;
|
||||
z-index: 9;
|
||||
width: 78px;
|
||||
height: 78px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
:options="relatedOptions"
|
||||
:has-permission="hasPermission"
|
||||
tooltip-text="workbench.homePage.associateCaseCoverRateTooltip"
|
||||
:size="60"
|
||||
:value-list="coverRateValueList"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -24,12 +24,7 @@
|
|||
<div class="mt-[16px]">
|
||||
<div class="flex gap-[16px]">
|
||||
<div v-for="tabItem of testPlanTabList" :key="tabItem.label" class="flex-1">
|
||||
<PassRatePie
|
||||
:has-permission="hasPermission"
|
||||
:options="tabItem.options"
|
||||
:size="60"
|
||||
:value-list="tabItem.valueList"
|
||||
/>
|
||||
<PassRatePie :has-permission="hasPermission" :options="tabItem.options" :value-list="tabItem.valueList" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-[16px] h-[148px]">
|
||||
|
|
|
@ -364,15 +364,25 @@ export function handlePieData(
|
|||
) {
|
||||
const options: Record<string, any> = getPieCharOptions(key);
|
||||
const lastStatusPercentList = statusPercentList ?? [];
|
||||
options.series.data = lastStatusPercentList.map((item) => ({
|
||||
name: item.status,
|
||||
value: item.count,
|
||||
tooltip: {
|
||||
...toolTipConfig,
|
||||
position: 'right',
|
||||
show: !!hasPermission,
|
||||
},
|
||||
}));
|
||||
const hasDataLength = lastStatusPercentList.filter((e) => Number(e.count) > 0).length;
|
||||
const pieBorderWidth = hasDataLength === 1 ? 0 : 2;
|
||||
|
||||
options.series.data =
|
||||
hasDataLength > 0
|
||||
? lastStatusPercentList.map((item) => ({
|
||||
name: item.status,
|
||||
value: item.count,
|
||||
tooltip: {
|
||||
...toolTipConfig,
|
||||
position: 'right',
|
||||
show: !!hasPermission,
|
||||
},
|
||||
itemStyle: {
|
||||
borderWidth: pieBorderWidth,
|
||||
borderColor: '#ffffff',
|
||||
},
|
||||
}))
|
||||
: [];
|
||||
|
||||
// 计算总数和图例格式
|
||||
const tempObject: Record<string, any> = {};
|
||||
|
@ -407,13 +417,20 @@ export function handleUpdateTabPie(
|
|||
const countList = list || [];
|
||||
let lastCountList: { value: number | string; label: string; name: string }[] = [];
|
||||
if (hasPermission) {
|
||||
const pieBorderWidth = countList.slice(1).filter((e) => Number(e.count) > 0).length === 1 ? 0 : 1;
|
||||
|
||||
lastCountList = countList.slice(1).map((item) => {
|
||||
return {
|
||||
value: item.count,
|
||||
label: item.name,
|
||||
name: item.name,
|
||||
itemStyle: {
|
||||
borderWidth: pieBorderWidth,
|
||||
borderColor: '#ffffff',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
options.series.data = lastCountList.every((e) => e.value === 0) ? [] : lastCountList;
|
||||
|
||||
options.title.text = countList[0].name ?? '';
|
||||
|
|
Loading…
Reference in New Issue