feat: 初始化图表整体流程

This commit is contained in:
奔跑的面条
2024-12-15 12:48:36 +08:00
parent 0972ea0e28
commit 6106a8fc5c
21 changed files with 381 additions and 28 deletions
+41 -16
View File
@@ -133,13 +133,17 @@ const emit = defineEmits([
const props = defineProps({
option: {
type: Object as PropType<ISpec>,
type: Object as PropType<
ISpec & {
dataset: any
}
>,
required: true
},
initOptions: {
type: Object as PropType<
IInitOption & {
deepWatch?: boolean
deepWatch?: boolean | number
}
>,
required: false,
@@ -150,27 +154,53 @@ const props = defineProps({
const vChartRef = ref()
let chart: IVChart
// 排除 data 监听
watch(
() => props.option,
(chartProps: ISpec) => {
() => ({
...props.option,
data: undefined
}),
() => {
nextTick(() => {
createOrUpdateChart(props.option)
})
},
{
deep: props.initOptions?.deepWatch || true,
immediate: true
}
)
// 单独渲染,非深度监听,处理性能问题
watch(
() => props.option.dataset,
() => {
if (vChartRef.value) {
nextTick(() => {
createOrUpdateChart(chartProps)
createOrUpdateChart(props.option)
})
}
},
{
deep: props.initOptions.deepWatch || false
deep: false,
immediate: false
}
)
// 更新
const createOrUpdateChart = (chartProps: ISpec) => {
const createOrUpdateChart = (
chartProps: ISpec & {
dataset: any
}
) => {
if (vChartRef.value && !chart) {
chart = new VChart(chartProps, {
dom: vChartRef.value,
...props.initOptions
})
chart = new VChart(
{ ...chartProps, data: chartProps.dataset },
{
dom: vChartRef.value,
...props.initOptions
}
)
chart.renderSync()
return true
} else if (chart) {
@@ -194,11 +224,6 @@ const eventHandlers = (eventData: MouseEvent, eventName: string) => {
if (event.includes(eventName)) emit(eventName as any, eventData)
}
// 挂载
onMounted(() => {
createOrUpdateChart(props.option)
})
// 卸载
onBeforeUnmount(() => {
if (chart) {
@@ -0,0 +1,45 @@
<template>
<!-- todo 补充常用配置项 -->
<div v-if="optionData.legends">
<div v-for="(legendItem, index) in optionData.legends" :key="index">
<collapse-item name="图例">
<template #header>
<n-switch v-model:value="legendItem.visible" size="small"></n-switch>
</template>
<setting-item-box name="布局">
<setting-item name="位置">
<n-select v-model:value="legendItem.orient" size="small" :options="legendsConfig.orient" />
</setting-item>
<setting-item name="对齐方式">
<n-select v-model:value="legendItem.position" size="small" :options="legendsConfig.position" />
</setting-item>
</setting-item-box>
<setting-item-box name="项配置">
<setting-item name="标题位置">
<n-select v-model:value="legendItem.item.align" size="small" :options="legendsConfig.align" />
</setting-item>
<setting-item name="颜色">
<n-color-picker size="small" v-model:value="legendItem.item.label.style.fill"></n-color-picker>
</setting-item>
<setting-item name="大小">
<n-input-number v-model:value="legendItem.item.label.style.fontSize" :min="1" size="small"></n-input-number>
</setting-item>
</setting-item-box>
</collapse-item>
</div>
</div>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { legendsConfig } from '@/packages/chartConfiguration/vcharts/index'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>
@@ -0,0 +1,18 @@
<template>
<!-- 图例 -->
<Legends :optionData="optionData"></Legends>
</template>
<script setup lang="ts">
import { PropType, computed } from 'vue'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
import Legends from './Legends.vue'
const props = defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>
@@ -0,0 +1,3 @@
import VChartGlobalSetting from './VChartGlobalSetting.vue'
export { VChartGlobalSetting }