Files
yudao-dev/src/views/home/components/KFAPMiddleBar.vue
‘937886381’ dfa4ff3f54 修改
2025-11-14 17:04:22 +08:00

328 lines
9.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="coreBar" style="height: 100%;">
<div class="barTop">
<!-- 标题单独左对齐 -->
<!-- <div class="title">销售指标趋势</div> -->
<!-- 关键新增右侧容器包裹图例和按钮组实现整体靠右 -->
<div class="right-container">
<div class="legend">
<span class="legend-item">
<span class="legend-icon square yield"></span>
利润
</span>
<span class="legend-item">
<span class="legend-icon square target"></span>
营业收入
</span>
<!-- 给第三个第四个图例项加 close-item -->
<span class="legend-item close-item">
<span class="legend-icon square achieved"></span>
<!-- 达标 -->
</span>
<span class="legend-item close-item">
<span class="legend-icon square unachieved"></span>
成本
</span>
</div>
<!-- <div class="button-group">
<div style="letter-spacing: 8px" class="item-button" :class="{ active: activeButton === 0 }"
@click="activeButton = 0">
销量
</div>
<div style="letter-spacing: 8px" class="item-button" :class="{ active: activeButton === 1 }"
@click="activeButton = 1">
毛利率
</div>
</div> -->
</div>
</div>
<div class="lineBottom" style="height: 100%; width: 100%">
<coreLineChart :chart-data="{
series: chartSeries,
allPlaceNames: chartData.allPlaceNames
}" style="height: 100%; width: 100%" />
</div>
</div>
</template>
<script>
import coreLineChart from './operatingLineBar.vue';
import * as echarts from 'echarts';
export default {
name: "Container",
components: { coreLineChart },
props: ['chartData' ],
data() {
return {
};
},
computed: {
// 原有计算属性allPlaceNames、profitProportionData 等)保持不变
// 新增:定义图表 series 配置
chartSeries() {
const { allPlaceNames, incomeValueData, profitListData, costValueData, costCompletedData } = this.chartData
// 处理空数据默认值
const incomeData = incomeValueData || Array(allPlaceNames.length).fill(0);
const profitData = profitListData || Array(allPlaceNames.length).fill(0);
const costData = costValueData || Array(allPlaceNames.length).fill(0);
return [
// 2. 营业收入:柱状图
{
name: '营业收入',
type: 'bar',
yAxisIndex: 0,
barWidth: 18,
itemStyle: {
// 移除多余的 normal 层级,直接配置 color 渐变
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(130, 204, 255, 1)' },
{ offset: 1, color: '#2889FF' }
]
},
borderRadius: [4, 4, 0, 0],
borderWidth: 0
},
// itemStyle: {
// color: '#2889FF',
// borderRadius: [4, 4, 0, 0]
// },
data: incomeData
},
// 3. 成本:柱状图(动态颜色)
{
name: '成本',
type: 'bar',
stack: 'total', // 堆叠分组名(与利润保持一致)
yAxisIndex: 0,
barWidth: 18,
itemStyle: {
// 根据 safeFlag 动态返回不同的渐变色
color: (params) => {
const dataIndex = params.dataIndex;
const currentFlag = costCompletedData[dataIndex] || 0; // 默认为0不达标
// 达标时的渐变(绿色系)
if (currentFlag === 1) {
return {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(174, 239, 224, 1)' }, // 浅绿
{ offset: 1, color: 'rgba(118, 218, 190, 1)' } // 深绿
]
};
}
// 不达标时的渐变(橙色系)
else {
return {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(253, 209, 129, 1)' }, // 浅橙
{ offset: 1, color: 'rgba(249, 164, 74, 1)' } // 深橙
]
};
}
},
borderRadius: [4, 4, 0, 0],
borderWidth: 0
},
data: costData
},
{
name: '利润',
type: 'bar',
yAxisIndex: 0,
// lineStyle: {
// color: 'rgba(40, 138, 255, .5)',
// width: 2
// },
stack: 'total', // 堆叠分组名(与利润保持一致)
barWidth: 18,
itemStyle: {
// 移除多余的 normal 层级,直接配置 color 渐变
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(130, 204, 255, 1)' },
{ offset: 1, color: '#288aff' }
]
},
borderRadius: [4, 4, 0, 0],
borderWidth: 0
},
// itemStyle: {
// color: '#288aff',
// borderRadius: [4, 4, 0, 0]
// },
data: profitData,
},
];
}
},
methods: {},
};
</script>
<style scoped lang="scss">
.coreBar {
display: flex;
flex-direction: column;
width: 100%;
padding: 12px;
.barTop {
display: flex;
justify-content: flex-end; // 标题左、右侧容器右,整体两端对齐
align-items: center; // 垂直居中,避免上下错位
gap: 16px; // 标题与右侧容器的最小间距,防止拥挤
width: 100%; // 确保占满父容器,实现两端对齐
.title {
height: 18px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 18px;
color: #000000;
line-height: 18px;
letter-spacing: 1px;
text-align: left;
font-style: normal;
// 标题固定在左侧,不挤压右侧空间
white-space: nowrap;
}
// 1. 右侧容器:包裹图例和按钮组,整体靠右
.right-container {
display: flex;
align-items: center; // 图例和按钮组垂直居中
gap: 24px; // 图例与按钮组的间距,避免贴紧
margin-right: 46px; // 右侧整体留边,与原按钮组边距一致
}
// 2. 图例:在右侧容器内横向排列
.legend {
display: flex;
gap: 16px; // 图例项之间间距,避免重叠
align-items: center;
// 移除原margin-left避免位置偏移
margin: 0;
}
.legend-item {
display: flex;
align-items: center;
gap: 8px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 14px;
color: rgba(0, 0, 0, 0.8);
text-align: left;
font-style: normal;
white-space: nowrap; // 防止图例文字换行
}
.legend-icon {
display: inline-block;
}
.legend-icon.line {
width: 12px;
height: 2px;
position: relative;
&::before {
position: absolute;
content: "";
top: -2px;
left: 3px;
width: 6px;
border-radius: 50%;
height: 6px;
background-color: rgba(40, 138, 255, 1);
}
}
.legend-icon.square {
width: 8px;
height: 8px;
}
// 图例颜色
.yield {
background: rgba(40, 138, 255, 1);
}
.target {
background: #2889FF;
}
.achieved {
background: rgba(40, 203, 151, 1);
}
.unachieved {
background: rgba(255, 132, 0, 1);
}
.legend-item.close-item+.legend-item.close-item {
margin-left: -8px; // 负margin抵消默认gap数值可根据需求调整
// 若原gap是16px想让两者间距变为8px设置 margin-left: -8px 即可
}
// 3. 按钮组:在右侧容器内,保留原有样式
.button-group {
display: flex;
position: relative;
gap: 2px;
width: 283px;
align-items: center;
height: 24px;
background: #ecf4fe;
border-radius: 12px;
// 移除原margin-right由右侧容器统一控制
margin: 0;
.item-button {
cursor: pointer;
width: 142px;
height: 24px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 12px;
color: #0b58ff;
line-height: 24px;
text-align: center;
font-style: normal;
letter-spacing: 8px; // 确保文字间距生效
padding-left: 8px; // 抵消letter-spacing导致的文字左偏
}
.item-button.active {
width: 142px;
height: 24px;
background: #3071ff;
border-radius: 12px;
color: #ffffff;
font-weight: 500;
}
}
}
}
</style>