134 lines
3.7 KiB
Plaintext
134 lines
3.7 KiB
Plaintext
<template>
|
|
<view class="chart-wrap" :style="{ height: heightPx }">
|
|
<EChartsView :option="chartOption" class="chart" />
|
|
</view>
|
|
</template>
|
|
|
|
<script lang="uts">
|
|
import EChartsView from '@/uni_modules/charts/EChartsView.vue'
|
|
|
|
export default {
|
|
components: {
|
|
EChartsView
|
|
},
|
|
props: {
|
|
xLabels: { type: Array, default: () => [] },
|
|
data: { type: Array, default: () => [] },
|
|
height: { type: Number, default: 300 }
|
|
},
|
|
data() {
|
|
return {
|
|
heightPx: '300px',
|
|
chartOption: {} as any
|
|
}
|
|
},
|
|
watch: {
|
|
xLabels: { handler() { this.updateOption() }, deep: true },
|
|
data: { handler() { this.updateOption() }, deep: true },
|
|
height: {
|
|
handler() {
|
|
this.heightPx = `${this.height}px`
|
|
}
|
|
}
|
|
},
|
|
mounted() {
|
|
this.heightPx = `${this.height}px`
|
|
setTimeout(() => {
|
|
this.updateOption()
|
|
}, 150)
|
|
},
|
|
methods: {
|
|
toPlainObject(obj: any): any {
|
|
if (obj == null) return null
|
|
if (typeof obj !== 'object') return obj
|
|
if (Array.isArray(obj)) {
|
|
return obj.map((item) => this.toPlainObject(item))
|
|
}
|
|
const plain: any = {}
|
|
for (const key in obj) {
|
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
const value = obj[key]
|
|
if (typeof value === 'function' || key.startsWith('_') || key === 'toJSON') {
|
|
continue
|
|
}
|
|
if (value != null && typeof value === 'object' && !Array.isArray(value)) {
|
|
let isSimple = true
|
|
for (const k in value) {
|
|
if (typeof value[k] === 'object' && value[k] !== null) {
|
|
isSimple = false
|
|
break
|
|
}
|
|
}
|
|
plain[key] = isSimple ? { ...value } : this.toPlainObject(value)
|
|
} else {
|
|
plain[key] = value
|
|
}
|
|
}
|
|
}
|
|
return plain
|
|
},
|
|
updateOption() {
|
|
if (!this.xLabels || !this.data || this.xLabels.length === 0 || this.data.length === 0) {
|
|
return
|
|
}
|
|
|
|
const x = (this.xLabels as Array<any>).map((s) => String(s))
|
|
const d = (this.data as Array<any>).map((v) => {
|
|
const n = Number(v)
|
|
return isFinite(n) ? n : 0
|
|
})
|
|
|
|
const option = {
|
|
grid: { left: 40, right: 20, top: 40, bottom: 40 },
|
|
tooltip: {
|
|
show: true,
|
|
trigger: 'axis',
|
|
backgroundColor: 'rgba(255, 255, 255, 0.9)',
|
|
textStyle: { color: '#666', fontSize: 12 },
|
|
confine: true
|
|
},
|
|
xAxis: {
|
|
type: 'category',
|
|
boundaryGap: false,
|
|
data: x,
|
|
axisLine: { lineStyle: { color: 'rgba(0,0,0,0.1)' } },
|
|
axisLabel: { color: 'rgba(0,0,0,0.45)', fontSize: 10, interval: 'auto' }
|
|
},
|
|
yAxis: {
|
|
type: 'value',
|
|
axisLine: { show: false },
|
|
splitLine: { lineStyle: { color: 'rgba(0,0,0,0.05)' } },
|
|
axisLabel: { color: 'rgba(0,0,0,0.45)', fontSize: 10 }
|
|
},
|
|
series: [{
|
|
name: '数据',
|
|
data: d,
|
|
type: 'line',
|
|
smooth: true,
|
|
showSymbol: false,
|
|
symbolSize: 0,
|
|
lineStyle: { width: 2, color: '#1890ff' },
|
|
areaStyle: {
|
|
color: {
|
|
type: 'linear',
|
|
x: 0, y: 0, x2: 0, y2: 1,
|
|
colorStops: [
|
|
{ offset: 0, color: 'rgba(24, 144, 255, 0.2)' },
|
|
{ offset: 1, color: 'rgba(24, 144, 255, 0.01)' }
|
|
]
|
|
}
|
|
}
|
|
}]
|
|
}
|
|
this.chartOption = this.toPlainObject(option)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.chart-wrap { width: 100%; position: relative; overflow: hidden; }
|
|
.chart { width: 100%; height: 100%; position: absolute; top: 0; left: 0; }
|
|
</style>
|
|
|