Files
smart_storage_app/components/charts/index.vue
2025-06-30 10:21:25 +08:00

213 lines
4.3 KiB
Vue

<template>
<l-echart :ref="id"></l-echart>
</template>
<script>
export default {
name: "Echarts",
props: {
id: {
type: String,
default: "chart",
},
width: {
type: String,
default: "100%",
},
height: {
type: String,
default: "100%",
},
options: {
type: Object,
default: () => ({}),
},
gradient: {
type: Array,
default: () => [],
},
labelFormatter: {
type: Boolean,
default: () => false,
},
direction: {
type: Array,
default: () => [],
},
dataList: {
type: Array,
default: () => [],
},
},
data() {
return {};
},
watch: {
options: {
handler(value) {
const self = this
const copy_options = Object.assign({}, value);
if (this.gradient.length > 0 && value.series) {
copy_options.series.map((item, index) => {
if (this.gradient.length > index * 2 + 1) {
item.areaStyle = {
normal: {
// 右,下,左,上
color: this.$echarts.graphic.LinearGradient(
this.direction[0],
this.direction[1],
this.direction[2],
this.direction[3],
[{
offset: 0,
color: this.gradient[index * 2],
},
{
offset: 1,
color: this.gradient[index * 2 + 1],
},
],
false
),
},
};
}
return item;
});
}
if (value.series) {
setTimeout(() => {
if (this.labelFormatter && copy_options?.series) {
this.dataList.map((item,index) => {
const middleIndexList = this.findMiddleIndex(item.list)
copy_options.series[index].label = {
show: true,
formatter(params) {
const isInclude = middleIndexList.findIndex(i => i === params.dataIndex)
if (isInclude === -1) {
return ''
} else {
return params.data
}
}
}
})
}
this.$refs[this.id].init(this.$echarts, (chart) => {
chart.setOption(copy_options);
});
}, 100)
}
},
// deep:true
},
},
mounted() {
this.initChart();
},
methods: {
initChart() {
const self = this
// 初始化echart
const copy_value = Object.assign({}, this.options);
if (this.gradient.length > 0 && this.options.series) {
copy_value.series.map((item, index) => {
if (this.gradient.length > index * 2 + 1) {
item.areaStyle = {
normal: {
// 右,下,左,上
color: this.$echarts.graphic.LinearGradient(
this.direction[0],
this.direction[1],
this.direction[2],
this.direction[3],
[{
offset: 0,
color: this.gradient[index * 2],
},
{
offset: 1,
color: this.gradient[index * 2 + 1],
},
],
false
),
},
};
}
return item;
});
}
if (this.options.series) {
setTimeout(() => {
if (this.labelFormatter && copy_value?.series) {
this.dataList.map((item,index) => {
const middleIndexList = this.findMiddleIndex(item.list)
copy_value.series[index].label = {
show: true,
formatter(params) {
const isInclude = middleIndexList.findIndex(i => i === params.dataIndex)
if (isInclude === -1) {
return ''
} else {
if (isInclude > 0) {
return ''
}
return params.data
}
}
}
})
}
// chart.clear()
this.$refs[this.id].init(this.$echarts, (chart) => {
chart.setOption(copy_value);
});
}, 100)
// this.$nextTick(()=>{
// })
}
},
findMiddleIndex(arr) {
let firstIndex = -1 // 第一个不为null的
let prev = -1
const result = []
for (let i = 0; i < arr.length; i++) {
if (arr[i] !== null) {
if (firstIndex === -1) {
firstIndex = i
}
if (i !== arr.length - 1) {
if (arr[i + 1] === null) {
prev = i
result.push((prev + firstIndex) / 2)
firstIndex = -1
}
} else if (i === arr.length - 1) {
prev = i
result.push((prev + firstIndex) / 2)
firstIndex = -1
}
}
}
return result
},
},
};
</script>
<style lang="scss" scoped>
.echarts {
width: 100%;
height: 100%;
}
</style>