|
|
@@ -41,7 +41,18 @@
|
|
|
</view>
|
|
|
<view class="info-card">
|
|
|
<view class="chart-container">
|
|
|
- <tui-xechars ref="chartRef" style="width: 100%;" @initFinished="onInitFinished"></tui-xechars>
|
|
|
+ <tui-xechars ref="chartRef" style="width: 315rpx; height: 300rpx;" @initFinished="onInitFinished"></tui-xechars>
|
|
|
+ <view class="chart-legend">
|
|
|
+ <view v-for="(item, index) in chartLegendData" :key="index" class="legend-item">
|
|
|
+ <view class="legend-left">
|
|
|
+ <view class="legend-color" :style="{ backgroundColor: item.color }"></view>
|
|
|
+ <text class="legend-name">{{ item.name }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="legend-right">
|
|
|
+ <text class="legend-value">{{ formatHours(item.value) }}小时</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -135,45 +146,17 @@
|
|
|
// 保存图表实例
|
|
|
const chartInstance = ref<TuiCharts | null>(null)
|
|
|
|
|
|
- // 图表配置
|
|
|
- const chartOption = ref({
|
|
|
- tooltip: {
|
|
|
- trigger: 'item'
|
|
|
- },
|
|
|
- legend: {
|
|
|
- orient: 'horizontal',
|
|
|
- bottom: 10
|
|
|
- },
|
|
|
- series: [
|
|
|
- {
|
|
|
- type: 'pie',
|
|
|
- radius: ['40%', '70%'],
|
|
|
- avoidLabelOverlap: false,
|
|
|
- itemStyle: {
|
|
|
- borderRadius: 10,
|
|
|
- borderColor: '#fff',
|
|
|
- borderWidth: 2
|
|
|
- },
|
|
|
- label: {
|
|
|
- show: true,
|
|
|
- position: 'center'
|
|
|
- },
|
|
|
- emphasis: {
|
|
|
- label: {
|
|
|
- show: true,
|
|
|
- fontSize: 18,
|
|
|
- fontWeight: 'bold'
|
|
|
- }
|
|
|
- },
|
|
|
- labelLine: {
|
|
|
- show: true
|
|
|
- },
|
|
|
- data: [] as UTSJSONObject[],
|
|
|
- textOffset: 150
|
|
|
- } as UTSJSONObject
|
|
|
- ] as UTSJSONObject[]
|
|
|
- } as UTSJSONObject)
|
|
|
-
|
|
|
+ // 图例数据类型
|
|
|
+ type ChartLegendItem = {
|
|
|
+ name: string
|
|
|
+ value: number
|
|
|
+ color: string
|
|
|
+ }
|
|
|
+ const chartLegendData = ref<ChartLegendItem[]>([])
|
|
|
+
|
|
|
+ // 颜色配置
|
|
|
+ const chartColors = ['#5B9BF3', '#4DD4C0', '#FF9966', '#FF6B96', '#9B7FE8', '#FFD700', '#8A2BE2']
|
|
|
+
|
|
|
// 格式化小时数
|
|
|
const formatHours = (hourValue: number | null): string => {
|
|
|
if (hourValue == null) return '0.0'
|
|
|
@@ -197,13 +180,12 @@
|
|
|
charts.chartsMap.clear()
|
|
|
}
|
|
|
|
|
|
- // 创建饼图配置
|
|
|
+ // 创建饼图配置 - 使用环形图配置以匹配 flow-chart 组件
|
|
|
const pieOption = {
|
|
|
- type: 'pie',
|
|
|
- dataLabel: true,
|
|
|
+ type: 'ring',
|
|
|
+ dataLabel: false,
|
|
|
legend: {
|
|
|
- show: true,
|
|
|
- position: 'bottom'
|
|
|
+ show: false
|
|
|
},
|
|
|
series: chartData.value.map((item: UTSJSONObject, index: number) => {
|
|
|
return {
|
|
|
@@ -211,26 +193,28 @@
|
|
|
legendText: item.get('name'),
|
|
|
data: [{
|
|
|
name: item.get('name'),
|
|
|
- labelText: `${formatHours(item.get('value') as number)}小时`,
|
|
|
- labelShow: true,
|
|
|
value: item.get('value')
|
|
|
- }]
|
|
|
+ }],
|
|
|
+ color: chartColors[index % chartColors.length]
|
|
|
}
|
|
|
}),
|
|
|
extra: {
|
|
|
- pie: {
|
|
|
+ ring: {
|
|
|
+ type: 'ring',
|
|
|
+ width: 8,
|
|
|
activeOpacity: 0.5,
|
|
|
activeRadius: 0,
|
|
|
offsetAngle: 0,
|
|
|
labelWidth: 15,
|
|
|
- ringWidth: 30,
|
|
|
- // 添加 customRadius 来控制饼图大小
|
|
|
- customRadius: 80,
|
|
|
+ ringWidth: 8,
|
|
|
+ customRadius: 60,
|
|
|
border: false,
|
|
|
borderWidth: 0,
|
|
|
borderColor: '#FFFFFF',
|
|
|
centerColor: '#FFFFFF',
|
|
|
- linearType: 'custom'
|
|
|
+ linearType: 'custom',
|
|
|
+ // 添加背景色以匹配 flow-chart 组件
|
|
|
+ backgroundColor: '#C4D7E9'
|
|
|
}
|
|
|
}
|
|
|
} as UTSJSONObject
|
|
|
@@ -251,89 +235,86 @@
|
|
|
// 准备图表数据
|
|
|
const prepareChartData = (data: orderInfo): void => {
|
|
|
const chartItems = [] as UTSJSONObject[]
|
|
|
+ const legendItems = [] as ChartLegendItem[]
|
|
|
|
|
|
// 添加各项工时数据
|
|
|
- if (data.issueHour != null && data.issueHour >= 0) {
|
|
|
+ if (data.issueHour != null) {
|
|
|
const item = {
|
|
|
name: '下发时长',
|
|
|
value: data.issueHour
|
|
|
} as UTSJSONObject
|
|
|
chartItems.push(item)
|
|
|
+ legendItems.push({
|
|
|
+ name: '下发时长',
|
|
|
+ value: data.issueHour,
|
|
|
+ color: chartColors[legendItems.length % chartColors.length]
|
|
|
+ } as ChartLegendItem)
|
|
|
}
|
|
|
|
|
|
- if (data.acceptHour != null && data.acceptHour >= 0) {
|
|
|
+ if (data.acceptHour != null) {
|
|
|
const item = {name: '接单时长', value: data.acceptHour} as UTSJSONObject
|
|
|
chartItems.push(item)
|
|
|
+ legendItems.push({
|
|
|
+ name: '接单时长',
|
|
|
+ value: data.acceptHour,
|
|
|
+ color: chartColors[legendItems.length % chartColors.length]
|
|
|
+ } as ChartLegendItem)
|
|
|
}
|
|
|
|
|
|
- if (data.prepareHour != null && data.prepareHour >= 0) {
|
|
|
+ if (data.prepareHour != null) {
|
|
|
const item = {name: '准备时长', value: data.prepareHour} as UTSJSONObject
|
|
|
chartItems.push(item)
|
|
|
+ legendItems.push({
|
|
|
+ name: '准备时长',
|
|
|
+ value: data.prepareHour,
|
|
|
+ color: chartColors[legendItems.length % chartColors.length]
|
|
|
+ } as ChartLegendItem)
|
|
|
}
|
|
|
|
|
|
- if (data.workHour != null && data.workHour >= 0) {
|
|
|
+ if (data.workHour != null) {
|
|
|
const item = {name: '作业时长', value: data.workHour} as UTSJSONObject
|
|
|
chartItems.push(item)
|
|
|
+ legendItems.push({
|
|
|
+ name: '作业时长',
|
|
|
+ value: data.workHour,
|
|
|
+ color: chartColors[legendItems.length % chartColors.length]
|
|
|
+ } as ChartLegendItem)
|
|
|
}
|
|
|
|
|
|
- if (data.restartHour != null && data.restartHour >= 0) {
|
|
|
+ if (data.restartHour != null) {
|
|
|
const item = {name: '复运时长', value: data.restartHour} as UTSJSONObject
|
|
|
chartItems.push(item)
|
|
|
+ legendItems.push({
|
|
|
+ name: '复运时长',
|
|
|
+ value: data.restartHour,
|
|
|
+ color: chartColors[legendItems.length % chartColors.length]
|
|
|
+ } as ChartLegendItem)
|
|
|
}
|
|
|
|
|
|
- if (data.handleHour != null && data.handleHour >= 0) {
|
|
|
+ if (data.handleHour != null) {
|
|
|
const item = {name: '处理时长', value: data.handleHour} as UTSJSONObject
|
|
|
chartItems.push(item)
|
|
|
+ legendItems.push({
|
|
|
+ name: '处理时长',
|
|
|
+ value: data.handleHour,
|
|
|
+ color: chartColors[legendItems.length % chartColors.length]
|
|
|
+ } as ChartLegendItem)
|
|
|
}
|
|
|
|
|
|
- if (data.suspendHour != null && data.suspendHour >= 0) {
|
|
|
+ if (data.suspendHour != null) {
|
|
|
const item = {name: '挂起时长', value: data.suspendHour} as UTSJSONObject
|
|
|
chartItems.push(item)
|
|
|
+ legendItems.push({
|
|
|
+ name: '挂起时长',
|
|
|
+ value: data.suspendHour,
|
|
|
+ color: chartColors[legendItems.length % chartColors.length]
|
|
|
+ } as ChartLegendItem)
|
|
|
}
|
|
|
|
|
|
chartData.value = chartItems
|
|
|
+ chartLegendData.value = legendItems
|
|
|
console.log('更新chartData:', chartItems)
|
|
|
-
|
|
|
- // 更新图表配置
|
|
|
- const newOption = {
|
|
|
- tooltip: {
|
|
|
- trigger: 'item'
|
|
|
- },
|
|
|
- legend: {
|
|
|
- orient: 'horizontal',
|
|
|
- bottom: 10
|
|
|
- },
|
|
|
- series: [
|
|
|
- {
|
|
|
- type: 'pie',
|
|
|
- radius: ['40%', '70%'],
|
|
|
- avoidLabelOverlap: false,
|
|
|
- itemStyle: {
|
|
|
- borderRadius: 10,
|
|
|
- borderColor: '#fff',
|
|
|
- borderWidth: 2
|
|
|
- },
|
|
|
- label: {
|
|
|
- show: false,
|
|
|
- position: 'center'
|
|
|
- },
|
|
|
- emphasis: {
|
|
|
- label: {
|
|
|
- show: true,
|
|
|
- fontSize: 18,
|
|
|
- fontWeight: 'bold'
|
|
|
- }
|
|
|
- },
|
|
|
- labelLine: {
|
|
|
- show: false
|
|
|
- },
|
|
|
- data: chartItems,
|
|
|
- textOffset: 150
|
|
|
- }
|
|
|
- ]
|
|
|
- }
|
|
|
- // 使用深拷贝确保响应式更新
|
|
|
- chartOption.value = JSON.parse(JSON.stringify(newOption)) as UTSJSONObject
|
|
|
+ console.log('更新chartLegendData:', legendItems)
|
|
|
|
|
|
// 如果图表已经初始化,则直接绘制
|
|
|
if (chartInstance.value != null && chartItems.length > 0) {
|
|
|
@@ -521,8 +502,56 @@
|
|
|
}
|
|
|
|
|
|
.chart-container {
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
margin: 20rpx 0;
|
|
|
}
|
|
|
+
|
|
|
+ .chart-legend {
|
|
|
+ flex: 1;
|
|
|
+ padding-left: 20rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .legend-item {
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .legend-left {
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .legend-right {
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .legend-color {
|
|
|
+ width: 24rpx;
|
|
|
+ height: 24rpx;
|
|
|
+ border-radius: 4rpx;
|
|
|
+ margin-right: 12rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .legend-name {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #333333;
|
|
|
+ margin-right: 8rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .legend-value {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #666666;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
|
|
|
.no-data {
|
|
|
text-align: center;
|