ui库和web端产品库合并版本(还需修复细节)
This commit is contained in:
183
ui/packages/tools/AiEchart.vue
Normal file
183
ui/packages/tools/AiEchart.vue
Normal file
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<section class="AiEchart">
|
||||
<div ref="AiEchart" class="chart" :style="{minWidth:grid.width,minHeight:grid.height}"/>
|
||||
<slot v-if="$slots.default"/>
|
||||
<render-component v-else-if="ops.render" :render="ops.render" :options="chartOptions" :data="data"/>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
export default {
|
||||
name: "AiEchart",
|
||||
props: {
|
||||
data: {default: () => []},
|
||||
ops: {default: () => ({})},
|
||||
type: {default: "line"},
|
||||
series: Object,
|
||||
theme: {
|
||||
default: '0'
|
||||
}
|
||||
},
|
||||
components: {
|
||||
renderComponent: {
|
||||
functional: true,
|
||||
props: {
|
||||
render: Function,
|
||||
options: {default: () => ({})},
|
||||
data: {default: () => []}
|
||||
},
|
||||
render(h, ins) {
|
||||
let {options = {}, data} = ins.props
|
||||
return ins.props.render(h, {...options, data})
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
chart: null,
|
||||
timer: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
colors () {
|
||||
if (this.theme === '0') {
|
||||
return ['#2896FF', '#09DBFE', '#61FDB9', '#FFBB69', '#8429FF', '#ea7ccc']
|
||||
}
|
||||
|
||||
return ['#D4380D', '#CF1322', '#D55800', '#FA8C16', '#FFC53D', '#FFA940', '#FFC53D', '#780000']
|
||||
},
|
||||
|
||||
chartOptions() {
|
||||
let {type, data, ops: options = {}} = this,
|
||||
style = this.series ? this.series : this.ops.daemon ? this.ops.daemon : {},
|
||||
colors = this.theme === '1' ? this.colors : (options.color || this.colors),
|
||||
legend = {textStyle: {color: '#fff', padding: [0, 0, 0, 8], fontSize: 14}},
|
||||
series = data?.[0] ? Array(Object.keys(data?.[0]).length - 1).fill(1)
|
||||
.map((e, i) => ({type, ...(typeof style == 'object' ? style : style(colors[i]))})) : []
|
||||
let ops = {
|
||||
tooltip: {},
|
||||
xAxis: {
|
||||
type: 'category', nameGap: 20, axisTick: false,
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
interval: 0,
|
||||
rotate: this.data.length > 10 ? 40 : 0
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: this.theme === '1' ? 'rgba(239, 163, 51, 0.8)' : 'rgba(255,255,255,.5)'
|
||||
}
|
||||
}
|
||||
},
|
||||
// 声明一个 Y 轴,数值轴。
|
||||
yAxis: {
|
||||
nameGap: 23, minInterval: 1,
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: this.theme === '1' ? 'rgba(255, 197, 52, 0.4)' : 'rgba(255, 255, 255, .2)',
|
||||
type: 'dashed'
|
||||
}
|
||||
},
|
||||
axisLabel: {color: '#fff'}
|
||||
},
|
||||
legend, series, ...options,
|
||||
color: colors,
|
||||
grid: {
|
||||
left: '0%',
|
||||
right: '0%',
|
||||
bottom: '0%',
|
||||
top: '40px',
|
||||
containLabel: true
|
||||
},
|
||||
}
|
||||
if (JSON.stringify(this.ops) != JSON.stringify(ops)) this.$emit("update:ops", ops)
|
||||
return ops
|
||||
},
|
||||
grid() {
|
||||
let {width, height} = this.chartOptions.grid || {}
|
||||
return {
|
||||
width: width ? width + 'px' : 'auto',
|
||||
height: height ? height + 'px' : 'auto'
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: {
|
||||
deep: true, handler(v, old) {
|
||||
let oldDims = Object.keys(old?.[0] || {})?.toString(),
|
||||
current = Object.keys(v?.[0] || {})?.toString()
|
||||
this.getChartData(oldDims != current)
|
||||
}
|
||||
},
|
||||
|
||||
theme () {
|
||||
this.refresh()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getChartData(render) {
|
||||
if (!render) {
|
||||
this.chart?.setOption({
|
||||
dataset: {
|
||||
source: this.data || []
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.chart?.setOption({
|
||||
...this.chartOptions,
|
||||
dataset: {
|
||||
source: this.data || []
|
||||
}
|
||||
}, true)
|
||||
}
|
||||
},
|
||||
initChart() {
|
||||
this.chart = echarts.init(this.$refs.AiEchart)
|
||||
this.chart.setOption(this.chartOptions || {})
|
||||
},
|
||||
watchResize() {
|
||||
this.timer && clearInterval(this.timer)
|
||||
this.timer = setInterval(() => {
|
||||
if (this.chart?.getHeight() != this.$refs.AiEchart?.clientHeight ||
|
||||
this.chart?.getWidth() != this.$refs.AiEchart?.clientWidth) {
|
||||
this.chart?.resize()
|
||||
}
|
||||
}, 1000)
|
||||
//5分钟后停止监听
|
||||
setTimeout(() => this.timer && clearInterval(this.timer), 5 * 60 * 1000)
|
||||
},
|
||||
refresh() {
|
||||
this.chart.setOption(this.chartOptions || {})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.watchResize()
|
||||
this.initChart()
|
||||
this.getChartData()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.timer && clearInterval(this.timer)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiEchart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
min-width: 100px;
|
||||
min-height: 0;
|
||||
position: relative;
|
||||
|
||||
.chart {
|
||||
height: 100%;
|
||||
min-height: 100px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user