This commit is contained in:
‘937886381’
2025-11-12 16:56:14 +08:00
commit 1ea62af1d6
1135 changed files with 109385 additions and 0 deletions

View File

@@ -0,0 +1,273 @@
<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 line 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, profitProportionData, costValueData, costCompletedData } = this.chartData
// 处理空数据默认值
const incomeData = incomeValueData || Array(allPlaceNames.length).fill(0);
const profitData = profitProportionData || Array(allPlaceNames.length).fill(0);
const costData = costValueData || Array(allPlaceNames.length).fill(0);
return [
// 1. 利润占比:折线图
{
name: '利润',
type: 'line',
yAxisIndex: 1,
lineStyle: {
color: 'rgba(40, 138, 255, .5)',
width: 2
},
itemStyle: {
color: 'rgba(40, 138, 255, 1)',
borderColor: 'rgba(40, 138, 255, 1)',
borderWidth: 2,
radius: 4
},
areaStyle: {
opacity: 0.2,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(40, 138, 255, .9)' },
{ offset: 1, color: 'rgba(255, 132, 0, 0)' }
])
},
data: profitData,
symbol: 'circle',
symbolSize: 6
},
// 2. 营业收入:柱状图
{
name: '营业收入',
type: 'bar',
yAxisIndex: 0,
barWidth: 18,
itemStyle: {
color: '#2889FF',
borderRadius: [4, 4, 0, 0]
},
data: incomeData
},
// 3. 成本:柱状图(动态颜色)
{
name: '成本',
type: 'bar',
yAxisIndex: 0,
barWidth: 18,
itemStyle: {
color: (params) => {
const completed = costCompletedData?.[params.dataIndex] ?? 0;
return completed === 1 ? 'rgba(255, 132, 0, 1)' : 'rgba(40, 203, 151, 1)';
},
borderRadius: [4, 4, 0, 0]
},
data: costData
}
];
}
},
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>