2024-04-18 17:01:10 +08:00
|
|
|
<!--
|
|
|
|
filename: DoubleRingChart.vue
|
|
|
|
author: liubin
|
|
|
|
date: 2024-04-17 11:01:55
|
|
|
|
description:
|
|
|
|
-->
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<div class="double-ring-chart">
|
|
|
|
<div ref="chart" class="double-ring-chart__container"></div>
|
|
|
|
<!-- :style="{ height: vHeight + 'vh' }" -->
|
|
|
|
<div class="double-ring-chart__legend">
|
|
|
|
<div v-for="item in legendItems" :key="item.label" class="legend-item">
|
|
|
|
<span class="legend-item__label">{{ item.label }}</span>
|
2024-04-28 10:59:05 +08:00
|
|
|
<span class="legend-item__value">{{ item.value | numberFilter }}</span>
|
2024-04-18 17:01:10 +08:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
import chartMixin from "@/mixins/chart.js";
|
|
|
|
import fullscreenMixin from "@/mixins/fullscreen.js";
|
2024-04-26 17:05:26 +08:00
|
|
|
import getOptions from "./double-ring-chart-options";
|
2024-04-18 17:01:10 +08:00
|
|
|
|
|
|
|
export default {
|
|
|
|
name: "DoubleRingChart",
|
|
|
|
mixins: [chartMixin, fullscreenMixin],
|
|
|
|
props: {
|
|
|
|
vHeight: {
|
|
|
|
type: Number,
|
|
|
|
default: 24,
|
|
|
|
},
|
2024-04-28 10:59:05 +08:00
|
|
|
factoryId: {
|
|
|
|
type: Number,
|
|
|
|
required: true,
|
|
|
|
},
|
2024-04-24 16:31:27 +08:00
|
|
|
period: {
|
|
|
|
type: String,
|
|
|
|
default: "日",
|
2024-04-18 17:01:10 +08:00
|
|
|
},
|
2024-04-26 17:05:26 +08:00
|
|
|
dataSource: {
|
|
|
|
type: String,
|
|
|
|
default: null,
|
|
|
|
},
|
2024-04-18 17:01:10 +08:00
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {};
|
|
|
|
},
|
2024-04-28 10:59:05 +08:00
|
|
|
filters: {
|
|
|
|
numberFilter(val) {
|
|
|
|
if (!isNaN(val)) {
|
|
|
|
return (+val).toLocaleString();
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
},
|
|
|
|
},
|
2024-04-24 16:31:27 +08:00
|
|
|
computed: {
|
2024-04-28 10:59:05 +08:00
|
|
|
dataSourceField() {
|
|
|
|
switch (this.dataSource) {
|
|
|
|
case "标准组件产出":
|
|
|
|
return "stdOutput";
|
|
|
|
case "芯片产出":
|
|
|
|
return "chipOutput";
|
|
|
|
case "BIPV产出":
|
|
|
|
return "bipvOutput";
|
|
|
|
}
|
|
|
|
},
|
|
|
|
valueTuple() {
|
|
|
|
// [previousValue, currentValue, sumValue?]
|
|
|
|
const getter = this.$store.getters.copilot.yield[this.dataSourceField];
|
|
|
|
if (this.period === "日" || this.period === "周") {
|
|
|
|
return [
|
|
|
|
getter.previous[this.factoryId],
|
|
|
|
getter.current[this.factoryId],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
return [
|
|
|
|
getter.previous[this.factoryId],
|
|
|
|
getter.current[this.factoryId],
|
|
|
|
getter.target[this.factoryId],
|
|
|
|
];
|
2024-04-24 16:31:27 +08:00
|
|
|
},
|
2024-04-28 10:59:05 +08:00
|
|
|
|
2024-04-26 17:05:26 +08:00
|
|
|
options() {
|
2024-04-28 10:59:05 +08:00
|
|
|
const year = new Date().getFullYear();
|
|
|
|
const month = new Date().getMonth() + 1;
|
|
|
|
const vt = this.valueTuple;
|
|
|
|
let titleValue =
|
|
|
|
vt[0] != null && vt[2] != null && vt[2] !== 0
|
|
|
|
? `${vt[1] / vt[2]}%`
|
|
|
|
: "0%",
|
|
|
|
subtitle =
|
|
|
|
this.period == "月" ? `${month}月累计产出` : `${year}年累计产出`;
|
2024-04-26 17:05:26 +08:00
|
|
|
|
|
|
|
return getOptions({
|
|
|
|
titleValue,
|
|
|
|
subtitle,
|
2024-04-28 10:59:05 +08:00
|
|
|
previousSum: this.valueTuple[0],
|
|
|
|
currentSum: this.valueTuple[1],
|
|
|
|
targetSum: this.valueTuple[2],
|
2024-04-26 17:05:26 +08:00
|
|
|
});
|
|
|
|
},
|
2024-04-28 10:59:05 +08:00
|
|
|
|
|
|
|
legendItems() {
|
|
|
|
return calculateItems(this.period, this.valueTuple);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
watch: {
|
|
|
|
legendItems() {
|
|
|
|
this.initOptions(this.options);
|
|
|
|
},
|
2024-04-24 16:31:27 +08:00
|
|
|
},
|
2024-04-18 17:01:10 +08:00
|
|
|
mounted() {
|
2024-04-26 17:05:26 +08:00
|
|
|
this.initOptions(this.options);
|
2024-04-18 17:01:10 +08:00
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
// fullscreen mixin 需要的回调
|
|
|
|
fullscreenCallback(isFullscreen) {
|
|
|
|
console.log("isFullscreen--->", isFullscreen);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
2024-04-24 16:31:27 +08:00
|
|
|
|
2024-04-28 10:59:05 +08:00
|
|
|
function calculateItems(period, valueTuple) {
|
2024-04-24 16:31:27 +08:00
|
|
|
let items = [];
|
|
|
|
const today = new Date().getDate();
|
|
|
|
const month = new Date().getMonth() + 1;
|
|
|
|
const year = new Date().getFullYear();
|
|
|
|
switch (period) {
|
|
|
|
case "日":
|
|
|
|
items = [
|
2024-04-28 10:59:05 +08:00
|
|
|
{ label: `${month}月${today}日累计`, value: valueTuple[1] },
|
|
|
|
{ label: `去年${month}月${today}日累计`, value: valueTuple[0] },
|
2024-04-24 16:31:27 +08:00
|
|
|
];
|
|
|
|
break;
|
|
|
|
case "周":
|
|
|
|
items = [
|
2024-04-28 10:59:05 +08:00
|
|
|
{ label: `本周累计`, value: valueTuple[1] },
|
|
|
|
{ label: `去年本周累计`, value: valueTuple[0] },
|
2024-04-24 16:31:27 +08:00
|
|
|
];
|
|
|
|
break;
|
|
|
|
case "月":
|
|
|
|
items = [
|
2024-04-28 10:59:05 +08:00
|
|
|
{ label: `${month}月累计`, value: valueTuple[1] },
|
|
|
|
{ label: `去年${month}月累计`, value: valueTuple[0] },
|
|
|
|
{ label: `${month}月目标`, value: valueTuple[2] },
|
2024-04-24 16:31:27 +08:00
|
|
|
];
|
|
|
|
break;
|
|
|
|
case "年":
|
|
|
|
items = [
|
2024-04-28 10:59:05 +08:00
|
|
|
{ label: `${year}年累计`, value: valueTuple[1] },
|
|
|
|
{ label: `${year - 1}年累计`, value: valueTuple[0] },
|
|
|
|
{ label: `${year}年目标`, value: valueTuple[2] },
|
2024-04-24 16:31:27 +08:00
|
|
|
];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return items;
|
|
|
|
}
|
2024-04-18 17:01:10 +08:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
.double-ring-chart {
|
|
|
|
height: 100%;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
}
|
|
|
|
|
|
|
|
.double-ring-chart__container {
|
|
|
|
flex: 1;
|
|
|
|
height: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.double-ring-chart__legend {
|
|
|
|
padding: 12px;
|
|
|
|
color: #fff;
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
|
|
|
gap: 32px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.legend-item {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
align-items: flex-start;
|
|
|
|
}
|
|
|
|
|
|
|
|
.legend-item__label {
|
|
|
|
position: relative;
|
|
|
|
}
|
|
|
|
|
|
|
|
.legend-item__label::before {
|
|
|
|
content: "";
|
|
|
|
position: absolute;
|
|
|
|
width: 12px;
|
|
|
|
height: 12px;
|
|
|
|
background: #ccc;
|
|
|
|
border-radius: 2px;
|
|
|
|
top: 6px;
|
|
|
|
left: -18px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.legend-item:nth-child(1) .legend-item__label::before {
|
2024-04-26 17:05:26 +08:00
|
|
|
background: #12fff5;
|
2024-04-18 17:01:10 +08:00
|
|
|
}
|
|
|
|
.legend-item:nth-child(1) .legend-item__value {
|
2024-04-26 17:05:26 +08:00
|
|
|
color: #12fff5;
|
2024-04-18 17:01:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
.legend-item:nth-child(2) .legend-item__label::before {
|
2024-04-26 17:05:26 +08:00
|
|
|
background: #0f65ff;
|
2024-04-18 17:01:10 +08:00
|
|
|
}
|
|
|
|
.legend-item:nth-child(2) .legend-item__value {
|
2024-04-26 17:05:26 +08:00
|
|
|
color: #0f65ff;
|
2024-04-18 17:01:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
.legend-item:nth-child(3) .legend-item__label::before {
|
|
|
|
background: #003982;
|
|
|
|
}
|
|
|
|
</style>
|