feat: 引入 ECharts 统一图表并完善员工画像标签分页
后端优化员工行为画像服务和辅助函数,完善系统设置模型和 配置持久化,前端引入 ECharts 替换所有图表组件实现统一 渲染,新增员工画像标签分页器和数字员工工作记录组件,优 化工作台响应式布局和登录页过渡动画,完善预算中心和数字 员工页面样式细节。
This commit is contained in:
79
web/src/composables/useEcharts.js
Normal file
79
web/src/composables/useEcharts.js
Normal file
@@ -0,0 +1,79 @@
|
||||
import { nextTick, onBeforeUnmount, onMounted, watch } from 'vue'
|
||||
import { init } from 'echarts/core'
|
||||
|
||||
export function useEcharts(chartElement, chartOptions) {
|
||||
let chartInstance = null
|
||||
let resizeObserver = null
|
||||
let renderFrame = 0
|
||||
|
||||
function renderChart() {
|
||||
if (!chartElement.value) {
|
||||
return
|
||||
}
|
||||
if (!chartInstance) {
|
||||
chartInstance = init(chartElement.value, null, { renderer: 'canvas' })
|
||||
chartInstance.resize()
|
||||
}
|
||||
chartInstance.setOption(chartOptions.value, true)
|
||||
}
|
||||
|
||||
function handleResize() {
|
||||
chartInstance?.resize()
|
||||
}
|
||||
|
||||
function scheduleRender() {
|
||||
if (typeof window === 'undefined') {
|
||||
renderChart()
|
||||
return
|
||||
}
|
||||
if (renderFrame) {
|
||||
window.cancelAnimationFrame(renderFrame)
|
||||
}
|
||||
renderFrame = window.requestAnimationFrame(() => {
|
||||
renderFrame = 0
|
||||
renderChart()
|
||||
})
|
||||
}
|
||||
|
||||
function bindResize() {
|
||||
if (!chartElement.value) {
|
||||
return
|
||||
}
|
||||
if (typeof ResizeObserver !== 'undefined') {
|
||||
resizeObserver = new ResizeObserver(handleResize)
|
||||
resizeObserver.observe(chartElement.value)
|
||||
}
|
||||
window.addEventListener('resize', handleResize)
|
||||
}
|
||||
|
||||
function unbindResize() {
|
||||
resizeObserver?.disconnect()
|
||||
resizeObserver = null
|
||||
window.removeEventListener('resize', handleResize)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
renderChart()
|
||||
bindResize()
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
unbindResize()
|
||||
if (renderFrame && typeof window !== 'undefined') {
|
||||
window.cancelAnimationFrame(renderFrame)
|
||||
renderFrame = 0
|
||||
}
|
||||
if (chartInstance) {
|
||||
chartInstance.dispose()
|
||||
chartInstance = null
|
||||
}
|
||||
})
|
||||
|
||||
watch(chartOptions, () => {
|
||||
nextTick(scheduleRender)
|
||||
}, { deep: true })
|
||||
|
||||
return {
|
||||
renderChart
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user