feat: 新增柱状图&折线图

This commit is contained in:
huanghao1412 2024-05-28 11:30:52 +08:00
parent d6756fc584
commit 2e80be90a3
4 changed files with 157 additions and 90 deletions

View File

@ -4,9 +4,37 @@
<CollapseItem <CollapseItem
v-for="(item, index) in seriesList" v-for="(item, index) in seriesList"
:key="index" :key="index"
:name="`${item.type == 'bar' ? '柱状图' : '折线图'}`" :name="`${item.type == 'bar' ? `柱状图-${index + 1}` : `折线图-${index + 1}`}`"
:expanded="true" :expanded="true"
> >
<template #header>
<n-space align="center" :wrap="false">
<n-button v-if="index !== 0" @click="handleDelete(index)" circle size="tiny">
<template #icon>
<n-icon><CloseIcon /></n-icon>
</template>
</n-button>
<n-dropdown v-if="index === seriesList.length - 1" trigger="hover" :options="options" @select="handleSelect">
<n-button circle size="tiny">
<template #icon>
<n-icon><AddIcon /></n-icon>
</template>
</n-button>
</n-dropdown>
</n-space>
</template>
<SettingItemBox name="类型">
<setting-item name="">
<n-select
:value="item.type"
:options="[
{ label: '柱状图', value: 'bar' },
{ label: '折线图', value: 'line' },
]"
:onUpdate:value="(v:string) => changeType(v, index)"
/>
</setting-item>
</SettingItemBox>
<SettingItemBox name="图形" v-if="item.type == 'bar'"> <SettingItemBox name="图形" v-if="item.type == 'bar'">
<SettingItem name="宽度"> <SettingItem name="宽度">
<n-input-number <n-input-number
@ -75,10 +103,14 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { PropType, computed } from 'vue' import { PropType, computed, ref, watch } from 'vue'
import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { lineConf } from '@/packages/chartConfiguration/echarts' import { lineConf } from '@/packages/chartConfiguration/echarts'
import { GlobalThemeJsonType } from '@/settings/chartThemes' import { GlobalThemeJsonType } from '@/settings/chartThemes'
import {barSeriesItem, lineSeriesItem} from './config'
import {cloneDeep} from "lodash";
import {icon} from "@/plugins";
const { CloseIcon, AddIcon } = icon.ionicons5
const props = defineProps({ const props = defineProps({
optionData: { optionData: {
@ -87,7 +119,32 @@ const props = defineProps({
} }
}) })
const options = ref([
{
label: '柱状图',
key: 'bar',
},
{
label: '折线图',
key: 'line'
},
])
const handleSelect = (key: string) => {
handleAdd(key === 'bar' ? cloneDeep(barSeriesItem) : cloneDeep(lineSeriesItem))
}
const seriesList = computed(() => { const seriesList = computed(() => {
return props.optionData.series return props.optionData.series
}) })
const handleAdd = (seriesItem: any) => {
props.optionData.series.push(cloneDeep(seriesItem))
}
const handleDelete = (i: number) => {
props.optionData.series.splice(i, 1)
}
const changeType = (type: string, i: number) => {
props.optionData.series[i] = type === 'bar' ? cloneDeep(barSeriesItem) : cloneDeep(lineSeriesItem)
}
</script> </script>

View File

@ -19,7 +19,7 @@ import { CanvasRenderer } from 'echarts/renderers'
import { BarChart, LineChart } from 'echarts/charts' import { BarChart, LineChart } from 'echarts/charts'
import config, { includes, barSeriesItem, lineSeriesItem } from './config' import config, { includes, barSeriesItem, lineSeriesItem } from './config'
import { mergeTheme } from '@/packages/public/chart' import { mergeTheme } from '@/packages/public/chart'
import { useChartDataFetch } from '@/hooks' import {useChartCommonData, useChartDataFetch} from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { isPreview } from '@/utils' import { isPreview } from '@/utils'
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
@ -49,25 +49,26 @@ const option = computed(() => {
return mergeTheme(props.chartConfig.option, props.themeSetting, includes) return mergeTheme(props.chartConfig.option, props.themeSetting, includes)
}) })
watch( // watch(
() => props.chartConfig.option.dataset, // () => props.chartConfig.option.dataset,
(newData, oldData) => { // (newData, oldData) => {
if (newData.dimensions.length !== oldData.dimensions.length) { // if (newData.dimensions.length !== oldData.dimensions.length) {
const seriesArr = [] // const seriesArr = []
for (let i = 0; i < newData.dimensions.length - 1; i++) { // for (let i = 0; i < newData.dimensions.length - 1; i++) {
seriesArr.push(barSeriesItem, lineSeriesItem) // seriesArr.push(barSeriesItem, lineSeriesItem)
} // }
replaceMergeArr.value = ['series'] // replaceMergeArr.value = ['series']
props.chartConfig.option.series = seriesArr // props.chartConfig.option.series = seriesArr
nextTick(() => { // nextTick(() => {
replaceMergeArr.value = [] // replaceMergeArr.value = []
}) // })
} // }
}, // },
{ // {
deep: false // deep: false
} // }
) // )
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore) // const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
const { vChartRef } = useChartCommonData(props.chartConfig, useChartEditStore)
</script> </script>

View File

@ -1,6 +1,6 @@
import { BarCommonConfig } from './BarCommon/index' import { BarCommonConfig } from './BarCommon/index'
import { BarCrossrangeConfig } from './BarCrossrange/index' import { BarCrossrangeConfig } from './BarCrossrange/index'
// import { CapsuleChartConfig } from './CapsuleChart/index' // import { CapsuleChartConfig } from './CapsuleChart/index'
// import { BarLineConfig } from './BarLine/index' import { BarLineConfig } from './BarLine/index'
export default [BarCommonConfig, BarCrossrangeConfig] export default [BarCommonConfig, BarCrossrangeConfig, BarLineConfig]

View File

@ -1,4 +1,4 @@
import { ref, provide, onMounted, onUnmounted } from 'vue' import { ref, provide, onMounted, onUnmounted, watch } from 'vue'
import { usePreviewFitScale, usePreviewScrollYScale, usePreviewScrollXScale, usePreviewFullScale } from '@/hooks/index' import { usePreviewFitScale, usePreviewScrollYScale, usePreviewScrollXScale, usePreviewFullScale } from '@/hooks/index'
import type { ChartEditStorageType } from '../index.d' import type { ChartEditStorageType } from '../index.d'
import { PreviewScaleEnum } from '@/enums/styleEnum' import { PreviewScaleEnum } from '@/enums/styleEnum'
@ -56,86 +56,95 @@ export const useScale = (localStorageInfo: ChartEditStorageType) => {
scaleRef.value = { ...scale } scaleRef.value = { ...scale }
} }
// 屏幕适配 let fn = () => {
onMounted(() => {
switch (localStorageInfo.editCanvasConfig.previewScaleType) { switch (localStorageInfo.editCanvasConfig.previewScaleType) {
case PreviewScaleEnum.FIT: case PreviewScaleEnum.FIT:
;(() => { ;(() => {
const { calcRate, windowResize, unWindowResize } = usePreviewFitScale( const { calcRate, windowResize, unWindowResize } = usePreviewFitScale(
width.value as number, width.value as number,
height.value as number, height.value as number,
previewRef.value, previewRef.value,
updateScaleRef updateScaleRef
) )
calcRate() calcRate()
windowResize() windowResize()
useAddWheelHandle(unWindowResize) useAddWheelHandle(unWindowResize)
onUnmounted(() => { onUnmounted(() => {
unWindowResize() unWindowResize()
}) })
})() })()
break break
case PreviewScaleEnum.SCROLL_Y: case PreviewScaleEnum.SCROLL_Y:
;(() => { ;(() => {
const { calcRate, windowResize, unWindowResize } = usePreviewScrollYScale( const { calcRate, windowResize, unWindowResize } = usePreviewScrollYScale(
width.value as number, width.value as number,
height.value as number, height.value as number,
previewRef.value, previewRef.value,
scale => { scale => {
const dom = entityRef.value const dom = entityRef.value
dom.style.width = `${width.value * scale.width}px` dom.style.width = `${width.value * scale.width}px`
dom.style.height = `${height.value * scale.height}px` dom.style.height = `${height.value * scale.height}px`
updateScaleRef(scale) updateScaleRef(scale)
} }
) )
calcRate() calcRate()
windowResize() windowResize()
useAddWheelHandle(unWindowResize) useAddWheelHandle(unWindowResize)
onUnmounted(() => { onUnmounted(() => {
unWindowResize() unWindowResize()
}) })
})() })()
break break
case PreviewScaleEnum.SCROLL_X: case PreviewScaleEnum.SCROLL_X:
;(() => { ;(() => {
const { calcRate, windowResize, unWindowResize } = usePreviewScrollXScale( const { calcRate, windowResize, unWindowResize } = usePreviewScrollXScale(
width.value as number, width.value as number,
height.value as number, height.value as number,
previewRef.value, previewRef.value,
scale => { scale => {
const dom = entityRef.value const dom = entityRef.value
dom.style.width = `${width.value * scale.width}px` dom.style.width = `${width.value * scale.width}px`
dom.style.height = `${height.value * scale.height}px` dom.style.height = `${height.value * scale.height}px`
updateScaleRef(scale) updateScaleRef(scale)
} }
) )
calcRate() calcRate()
windowResize() windowResize()
useAddWheelHandle(unWindowResize) useAddWheelHandle(unWindowResize)
onUnmounted(() => { onUnmounted(() => {
unWindowResize() unWindowResize()
}) })
})() })()
break break
case PreviewScaleEnum.FULL: case PreviewScaleEnum.FULL:
;(() => { ;(() => {
const { calcRate, windowResize, unWindowResize } = usePreviewFullScale( const { calcRate, windowResize, unWindowResize } = usePreviewFullScale(
width.value as number, width.value as number,
height.value as number, height.value as number,
previewRef.value, previewRef.value,
updateScaleRef updateScaleRef
) )
calcRate() calcRate()
windowResize() windowResize()
useAddWheelHandle(unWindowResize) useAddWheelHandle(unWindowResize)
onUnmounted(() => { onUnmounted(() => {
unWindowResize() unWindowResize()
}) })
})() })()
break break
} }
}
// 屏幕适配
onMounted(fn)
watch(() => localStorageInfo.editCanvasConfig, (v) => {
width.value = v.width
height.value = v.height
fn()
}, {
deep: true
}) })
return { return {