|
|
@@ -70,19 +70,19 @@ export default {
|
|
|
totalFaults() {
|
|
|
return this.activeFaults.reduce((sum, item) => sum + Number(item.value), 0);
|
|
|
},
|
|
|
- // 饼图实际渲染的数据
|
|
|
+ // 饼图实际渲染的数据:正常段(若有)+ 活跃故障段,按真实比例分布
|
|
|
pieData() {
|
|
|
- if (this.activeFaults.length > 0) {
|
|
|
- return this.activeFaults;
|
|
|
- }
|
|
|
- // 无故障时,用正常项的颜色画整圆
|
|
|
+ const normal = this.chartData.filter(item => item.name.indexOf('正常') !== -1 && Number(item.value) > 0);
|
|
|
+ const segments = [...normal, ...this.activeFaults];
|
|
|
+ if (segments.length > 0) return segments;
|
|
|
+ // 兜底:数据里既无正常也无故障,用正常项颜色画整圆
|
|
|
const normalItem = this.chartData.find(item => item.name.indexOf('正常') !== -1);
|
|
|
- return [{ name: '正常', value: 1, color: normalItem ? normalItem.color : '#A0E551' }];
|
|
|
+ return [{ name: '正常', value: 1, color: normalItem ? normalItem.color : '#5EC8FF' }];
|
|
|
},
|
|
|
- // 右侧面板:有故障显示故障项,无故障只显示正常项
|
|
|
+ // 右侧面板:始终把"正常"放在第一行(若数据里有),其后跟随活跃故障项
|
|
|
panelData() {
|
|
|
- if (this.activeFaults.length > 0) return this.activeFaults;
|
|
|
- return this.chartData.filter(item => item.name.indexOf('正常') !== -1);
|
|
|
+ const normal = this.chartData.filter(item => item.name.indexOf('正常') !== -1);
|
|
|
+ return [...normal, ...this.activeFaults];
|
|
|
}
|
|
|
},
|
|
|
watch: {
|
|
|
@@ -103,14 +103,30 @@ export default {
|
|
|
if (!segments || !segments.length) return;
|
|
|
|
|
|
const data = this.pieData;
|
|
|
- const total = data.reduce((sum, item) => sum + Number(item.value), 0) || 1;
|
|
|
- let currentOffset = 0;
|
|
|
+ const totalValue = data.reduce((sum, item) => sum + Number(item.value), 0) || 1;
|
|
|
+ const lengths = data.map(item => this.circumference * (Number(item.value) / totalValue));
|
|
|
|
|
|
+ // 故障段保底弧长:避免数量极小(如 1/980)时圆环上几乎看不到
|
|
|
+ // 仅当存在"正常"段可被扣减时启用,从正常段里把多出的弧长扣掉,保持总和不变
|
|
|
+ const normalIdx = data.findIndex(item => item.name.indexOf('正常') !== -1);
|
|
|
+ if (normalIdx >= 0) {
|
|
|
+ const minLen = this.circumference * (10 / 360); // 每段至少 10°
|
|
|
+ let extra = 0;
|
|
|
+ for (let i = 0; i < data.length; i++) {
|
|
|
+ if (i === normalIdx) continue;
|
|
|
+ if (lengths[i] > 0 && lengths[i] < minLen) {
|
|
|
+ extra += (minLen - lengths[i]);
|
|
|
+ lengths[i] = minLen;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lengths[normalIdx] = Math.max(0, lengths[normalIdx] - extra);
|
|
|
+ }
|
|
|
+
|
|
|
+ let currentOffset = 0;
|
|
|
data.forEach((item, index) => {
|
|
|
const segment = segments[index];
|
|
|
if (!segment) return;
|
|
|
- const percent = item.value / total;
|
|
|
- const strokeLength = this.circumference * percent;
|
|
|
+ const strokeLength = lengths[index];
|
|
|
|
|
|
segment.style.stroke = item.color;
|
|
|
segment.style.strokeDasharray = `${strokeLength} ${this.circumference - strokeLength}`;
|