mirror of
https://gitee.com/dromara/go-view.git
synced 2025-06-30 08:39:15 +08:00
feat: 增加表格和雷达图
This commit is contained in:
parent
97a3d24939
commit
54a4cafefd
@ -29,6 +29,7 @@ type ChartEditStoreType = typeof useChartEditStore
|
|||||||
export const useChartCommonData = (
|
export const useChartCommonData = (
|
||||||
targetComponent: CreateComponentType,
|
targetComponent: CreateComponentType,
|
||||||
useChartEditStore: ChartEditStoreType,
|
useChartEditStore: ChartEditStoreType,
|
||||||
|
updateCallback?: (...args: any) => any
|
||||||
) => {
|
) => {
|
||||||
const vChartRef = ref<typeof VChart | null>(null)
|
const vChartRef = ref<typeof VChart | null>(null)
|
||||||
let fetchInterval: any = 0
|
let fetchInterval: any = 0
|
||||||
@ -139,17 +140,29 @@ export const useChartCommonData = (
|
|||||||
// 多值的
|
// 多值的
|
||||||
if(isMultiple) {
|
if(isMultiple) {
|
||||||
if(Object.prototype.toString.call(data) === '[object Array]') {
|
if(Object.prototype.toString.call(data) === '[object Array]') {
|
||||||
if(data.length && data[0].dimensions && data[0].source) echartsUpdateHandle(data[0])
|
if(data.length && data[0].dimensions && data[0].source) {
|
||||||
|
echartsUpdateHandle(data[0])
|
||||||
|
// 更新回调函数
|
||||||
|
if (updateCallback) updateCallback(data)
|
||||||
|
}
|
||||||
else throw Error()
|
else throw Error()
|
||||||
}
|
}
|
||||||
else if(Object.prototype.toString.call(data) === '[object Object]'){
|
else if(Object.prototype.toString.call(data) === '[object Object]'){
|
||||||
if(data.dimensions && data.source) echartsUpdateHandle(data)
|
if(data.dimensions && data.source) {
|
||||||
|
echartsUpdateHandle(data)
|
||||||
|
// 更新回调函数
|
||||||
|
if (updateCallback) updateCallback(data)
|
||||||
|
}
|
||||||
else throw Error()
|
else throw Error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 单值的
|
// 单值的
|
||||||
else {
|
else {
|
||||||
if(data) echartsUpdateHandle(data)
|
if(data) {
|
||||||
|
echartsUpdateHandle(data)
|
||||||
|
// 更新回调函数
|
||||||
|
if (updateCallback) updateCallback(data)
|
||||||
|
}
|
||||||
else throw Error()
|
else throw Error()
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -12,14 +12,25 @@ export const RadarShapeEnumList = [
|
|||||||
{ label: '圆形', value: 'circle' }
|
{ label: '圆形', value: 'circle' }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
interface maxMapType {
|
||||||
|
[k: string]: {
|
||||||
|
max: number,
|
||||||
|
min: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const option = {
|
export const option = {
|
||||||
|
maxMap: {} as maxMapType,
|
||||||
tooltip: {
|
tooltip: {
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
data: dataJson.seriesData.map(i => i.name)
|
data: []
|
||||||
|
},
|
||||||
|
dataset: {
|
||||||
|
dimensions: [],
|
||||||
|
source: []
|
||||||
},
|
},
|
||||||
dataset: { ...dataJson },
|
|
||||||
radar: {
|
radar: {
|
||||||
shape: 'polygon',
|
shape: 'polygon',
|
||||||
radius: ['0%', '60%'],
|
radius: ['0%', '60%'],
|
||||||
@ -28,8 +39,8 @@ export const option = {
|
|||||||
splitLine: { show: true },
|
splitLine: { show: true },
|
||||||
axisName: { show: true, color: '#eee', fontSize: 12 },
|
axisName: { show: true, color: '#eee', fontSize: 12 },
|
||||||
axisLine: { show: true },
|
axisLine: { show: true },
|
||||||
axisTick: { show: true },
|
axisTick: { show: false },
|
||||||
indicator: dataJson.radarIndicator
|
indicator: []
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
@ -38,7 +49,7 @@ export const option = {
|
|||||||
areaStyle: {
|
areaStyle: {
|
||||||
opacity: 0.1
|
opacity: 0.1
|
||||||
},
|
},
|
||||||
data: dataJson.seriesData
|
data: []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -94,12 +94,21 @@
|
|||||||
></n-input-number>
|
></n-input-number>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
</SettingItemBox>
|
</SettingItemBox>
|
||||||
|
|
||||||
|
<SettingItemBox :name="item.key" v-for="(item, i) in maxList" :key="i">
|
||||||
|
<SettingItem name="最小值">
|
||||||
|
<n-input-number :value="item.min" @update:value="v => handleUpdate(item.key, 'min', v)" size="small" :min="0"/>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem name="最大值">
|
||||||
|
<n-input-number :value="item.max" @update:value="v => handleUpdate(item.key, 'max', v)" size="small" :min="0"/>
|
||||||
|
</SettingItem>
|
||||||
|
</SettingItemBox>
|
||||||
</CollapseItem>
|
</CollapseItem>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { PropType, computed, reactive } from 'vue'
|
import { PropType, computed, reactive, ref } from 'vue'
|
||||||
import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||||
import { option, RadarShapeEnumList } from './config'
|
import { option, RadarShapeEnumList } from './config'
|
||||||
import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
|
import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
|
||||||
@ -142,4 +151,22 @@ const updateCenter1 = (value: number) => {
|
|||||||
const sliderFormatTooltip = (v: number) => {
|
const sliderFormatTooltip = (v: number) => {
|
||||||
return `${v}%`
|
return `${v}%`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let maxList = computed(() => {
|
||||||
|
let arr = props.optionData.dataset.source.map(_ => {
|
||||||
|
let nameKey = props.optionData.dataset.dimensions[0]
|
||||||
|
return {
|
||||||
|
key: _[nameKey],
|
||||||
|
// 报错 不知道问题在哪
|
||||||
|
max: props.optionData.maxMap[_[nameKey]].max,
|
||||||
|
min: props.optionData.maxMap[_[nameKey]].min
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return arr
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleUpdate = (k: string, type: string, v: string) => {
|
||||||
|
if(type === 'min') props.optionData.maxMap[k].min = v
|
||||||
|
else if(type === 'max') props.optionData.maxMap[k].max = v
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, PropType, watch } from 'vue'
|
import { ref, computed, PropType, watch, toRefs } from 'vue'
|
||||||
import VChart from 'vue-echarts'
|
import VChart from 'vue-echarts'
|
||||||
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
|
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
|
||||||
import dataJson from './data.json'
|
import dataJson from './data.json'
|
||||||
@ -12,10 +12,10 @@ import { CanvasRenderer } from 'echarts/renderers'
|
|||||||
import { RadarChart } from 'echarts/charts'
|
import { RadarChart } from 'echarts/charts'
|
||||||
import { includes } from './config'
|
import { includes } from './config'
|
||||||
import { mergeTheme, setOption } from '@/packages/public/chart'
|
import { mergeTheme, setOption } from '@/packages/public/chart'
|
||||||
import { useChartDataFetch } from '@/hooks'
|
import {useChartCommonData, useChartDataFetch} from '@/hooks'
|
||||||
import { CreateComponentType } from '@/packages/index.d'
|
import { CreateComponentType } from '@/packages/index.d'
|
||||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||||
import { isPreview } from '@/utils'
|
import {isPreview, setTooltipPosition} from '@/utils'
|
||||||
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
|
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -33,6 +33,8 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
props.chartConfig.option.tooltip.position = setTooltipPosition(props.chartConfig.attr)
|
||||||
|
|
||||||
const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
|
const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
|
||||||
|
|
||||||
use([DatasetComponent, CanvasRenderer, RadarChart, GridComponent, TooltipComponent, LegendComponent])
|
use([DatasetComponent, CanvasRenderer, RadarChart, GridComponent, TooltipComponent, LegendComponent])
|
||||||
@ -43,35 +45,80 @@ const option = computed(() => {
|
|||||||
return mergeTheme(props.chartConfig.option, props.themeSetting, includes)
|
return mergeTheme(props.chartConfig.option, props.themeSetting, includes)
|
||||||
})
|
})
|
||||||
|
|
||||||
const dataSetHandle = (dataset: typeof dataJson) => {
|
// const dataSetHandle = (dataset: typeof dataJson) => {
|
||||||
if (dataset.seriesData) {
|
// if (dataset.seriesData) {
|
||||||
props.chartConfig.option.series[0].data = dataset.seriesData
|
// props.chartConfig.option.series[0].data = dataset.seriesData
|
||||||
// @ts-ignore
|
// // @ts-ignore
|
||||||
props.chartConfig.option.legend.data = dataset.seriesData.map((i: { name: string }) => i.name)
|
// props.chartConfig.option.legend.data = dataset.seriesData.map((i: { name: string }) => i.name)
|
||||||
}
|
// }
|
||||||
if (dataset.radarIndicator) {
|
// if (dataset.radarIndicator) {
|
||||||
props.chartConfig.option.radar.indicator = dataset.radarIndicator
|
// props.chartConfig.option.radar.indicator = dataset.radarIndicator
|
||||||
}
|
// }
|
||||||
if (vChartRef.value && isPreview()) {
|
// if (vChartRef.value && isPreview()) {
|
||||||
setOption(vChartRef.value, props.chartConfig.option)
|
// setOption(vChartRef.value, props.chartConfig.option)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
watch(
|
// watch(
|
||||||
() => props.chartConfig.option.dataset,
|
// () => props.chartConfig.option.dataset,
|
||||||
newData => {
|
// newData => {
|
||||||
try {
|
// try {
|
||||||
dataSetHandle(newData)
|
// dataSetHandle(newData)
|
||||||
} catch (error) {
|
// } catch (error) {
|
||||||
console.log(error)
|
// console.log(error)
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// deep: false
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
|
||||||
|
watch(() => props.chartConfig.option.dataset, (v) => {
|
||||||
|
let { dimensions, source } = v
|
||||||
|
source.forEach(_ => {
|
||||||
|
if(!Object.prototype.hasOwnProperty.call(props.chartConfig.option.maxMap, _[dimensions[0]])) {
|
||||||
|
props.chartConfig.option.maxMap[_[dimensions[0]]] = {
|
||||||
|
max: null,
|
||||||
|
min: 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
{
|
props.chartConfig.option.radar.indicator = source.map(_ => {
|
||||||
deep: false
|
return {
|
||||||
}
|
name: _[dimensions[0]],
|
||||||
)
|
max: props.chartConfig.option.maxMap[_[dimensions[0]]].max,
|
||||||
|
min: props.chartConfig.option.maxMap[_[dimensions[0]]].min,
|
||||||
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: typeof dataJson) => {
|
}
|
||||||
dataSetHandle(newData)
|
})
|
||||||
|
props.chartConfig.option.series[0].data = dimensions.slice(1).map(k => {
|
||||||
|
return {
|
||||||
|
name: k,
|
||||||
|
value: source.map(_ => _[k])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
props.chartConfig.option.legend.data = dimensions.slice(1)
|
||||||
|
}, {
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(() => props.chartConfig.option.maxMap, v => {
|
||||||
|
let { dimensions, source } = props.chartConfig.option.dataset
|
||||||
|
props.chartConfig.option.radar.indicator = source.map(_ => {
|
||||||
|
return {
|
||||||
|
name: _[dimensions[0]],
|
||||||
|
max: props.chartConfig.option.maxMap[_[dimensions[0]]].max,
|
||||||
|
min: props.chartConfig.option.maxMap[_[dimensions[0]]].min,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, {
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
|
})
|
||||||
|
|
||||||
|
// useChartDataFetch(props.chartConfig, useChartEditStore, (newData: typeof dataJson) => {
|
||||||
|
// dataSetHandle(newData)
|
||||||
|
// })
|
||||||
|
|
||||||
|
useChartCommonData(props.chartConfig, useChartEditStore)
|
||||||
</script>
|
</script>
|
||||||
|
@ -10,7 +10,7 @@ import { GraphConfig } from './Graph/index'
|
|||||||
|
|
||||||
export default [
|
export default [
|
||||||
// ProcessConfig,
|
// ProcessConfig,
|
||||||
// RadarConfig,
|
RadarConfig,
|
||||||
// FunnelConfig,
|
// FunnelConfig,
|
||||||
// HeatmapConfig,
|
// HeatmapConfig,
|
||||||
WaterPoloConfig,
|
WaterPoloConfig,
|
||||||
|
@ -4,12 +4,36 @@ import { TableScrollBoardConfig } from './index'
|
|||||||
import cloneDeep from 'lodash/cloneDeep'
|
import cloneDeep from 'lodash/cloneDeep'
|
||||||
import dataJson from './data.json'
|
import dataJson from './data.json'
|
||||||
|
|
||||||
|
export enum AlignEnum {
|
||||||
|
LEFT = 'left',
|
||||||
|
CENTER = 'center',
|
||||||
|
RIGHT = 'right',
|
||||||
|
}
|
||||||
|
|
||||||
|
export type MapType = {
|
||||||
|
show: boolean
|
||||||
|
key: string
|
||||||
|
header: string
|
||||||
|
align: AlignEnum
|
||||||
|
columnWidth: number
|
||||||
|
}
|
||||||
|
|
||||||
export const option = {
|
export const option = {
|
||||||
header: ['列1', '列2', '列3'],
|
headerConfig: [],
|
||||||
dataset: dataJson,
|
headerConfigMap: {
|
||||||
index: true,
|
index: {
|
||||||
columnWidth: [30, 100, 100],
|
show: true,
|
||||||
align: ['center', 'right', 'right', 'right'],
|
key: '行号',
|
||||||
|
header: '#',
|
||||||
|
align: 'left',
|
||||||
|
columnWidth: 30,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// header: ['列1', '列2', '列3'],
|
||||||
|
dataset: { dimensions: [], source: [] },
|
||||||
|
// index: true,
|
||||||
|
// columnWidth: [],
|
||||||
|
// align: [],
|
||||||
rowNum: 5,
|
rowNum: 5,
|
||||||
waitTime: 2,
|
waitTime: 2,
|
||||||
headerHeight: 35,
|
headerHeight: 35,
|
||||||
|
@ -25,21 +25,20 @@
|
|||||||
placeholder="请输入表头高度"
|
placeholder="请输入表头高度"
|
||||||
></n-input-number>
|
></n-input-number>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
<SettingItem name="显示行号">
|
<!-- <SettingItem name="显示行号">-->
|
||||||
<n-switch size="small" v-model:value="optionData.index" />
|
<!-- <n-switch size="small" v-model:value="optionData.index" />-->
|
||||||
</SettingItem>
|
<!-- </SettingItem>-->
|
||||||
</SettingItemBox>
|
</SettingItemBox>
|
||||||
|
|
||||||
<SettingItemBox name="配置" :alone="true">
|
<SettingItemBox name="配置" :alone="true">
|
||||||
<SettingItem name="表头数据">
|
<!-- <SettingItem name="表头数据">-->
|
||||||
<n-input v-model:value="header" :min="1" size="small" placeholder="表头数据(英文','分割)"></n-input>
|
<!-- <n-input v-model:value="header" :min="1" size="small" placeholder="表头数据(英文','分割)"></n-input>-->
|
||||||
</SettingItem>
|
<!-- </SettingItem>-->
|
||||||
<SettingItem name="列对齐方式">
|
<!-- <SettingItem name="列对齐方式">-->
|
||||||
<n-input v-model:value="align" :min="1" size="small" placeholder="对齐方式(英文','分割)"></n-input>
|
<!-- <n-input v-model:value="align" :min="1" size="small" placeholder="对齐方式(英文','分割)"></n-input>-->
|
||||||
</SettingItem>
|
<!-- </SettingItem>-->
|
||||||
<SettingItem name="列宽度">
|
<!-- <SettingItem name="列宽度">-->
|
||||||
<n-input v-model:value="columnWidth" :min="1" size="small" placeholder="列宽度(英文','分割)"></n-input>
|
<!-- <n-input v-model:value="columnWidth" :min="1" size="small" placeholder="列宽度(英文','分割)"></n-input>-->
|
||||||
</SettingItem>
|
<!-- </SettingItem>-->
|
||||||
<SettingItem name="轮播方式">
|
<SettingItem name="轮播方式">
|
||||||
<n-select
|
<n-select
|
||||||
v-model:value="optionData.carousel"
|
v-model:value="optionData.carousel"
|
||||||
@ -62,13 +61,34 @@
|
|||||||
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.evenRowBGC"></n-color-picker>
|
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.evenRowBGC"></n-color-picker>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
</SettingItemBox>
|
</SettingItemBox>
|
||||||
|
<SettingItemBox :name="`列${i + 1}`" v-for="(item, i) in headerConfig" :key="i">
|
||||||
|
<SettingItem name="展示" style="grid-column: 1 / 3">
|
||||||
|
<n-space>
|
||||||
|
<n-switch v-model:value="item.show" size="small"/>
|
||||||
|
</n-space>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem name="字段">
|
||||||
|
<n-text style="height: 28px;line-height: 28px">{{item.key ? item.key : '--'}}</n-text>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem name="标题">
|
||||||
|
<n-input v-model:value="item.header" size="small" clearable/>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem name="列对齐方式">
|
||||||
|
<n-select v-model:value="item.align" :options="alignOption" size="small"/>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem name="列宽度">
|
||||||
|
<n-input-number v-model:value="item.columnWidth" :min="0" size="small"/>
|
||||||
|
</SettingItem>
|
||||||
|
</SettingItemBox>
|
||||||
</CollapseItem>
|
</CollapseItem>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { PropType, ref, watch } from 'vue'
|
import { PropType, ref, watch, computed, toRefs } from 'vue'
|
||||||
|
import type { Ref, ToRefs } from 'vue'
|
||||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||||
import { option } from './config'
|
import { option, AlignEnum, MapType } from './config'
|
||||||
|
import { PickCreateComponentType } from '@/packages/index.d'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
optionData: {
|
optionData: {
|
||||||
@ -77,33 +97,74 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const header = ref()
|
|
||||||
const align = ref()
|
|
||||||
const columnWidth = ref()
|
|
||||||
|
|
||||||
watch(
|
// const header = ref()
|
||||||
() => props.optionData,
|
// const align = ref()
|
||||||
newData => {
|
// const columnWidth = ref()
|
||||||
header.value = props.optionData.header.toString()
|
//
|
||||||
align.value = props.optionData.align.toString()
|
// watch(
|
||||||
columnWidth.value = props.optionData.columnWidth.toString()
|
// () => props.optionData,
|
||||||
},
|
// newData => {
|
||||||
{
|
// header.value = props.optionData.header.toString()
|
||||||
deep: false,
|
// align.value = props.optionData.align.toString()
|
||||||
immediate: true
|
// columnWidth.value = props.optionData.columnWidth.toString()
|
||||||
}
|
// },
|
||||||
)
|
// {
|
||||||
|
// deep: false,
|
||||||
|
// immediate: true
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// watch([header, align, columnWidth], ([headerNew, alignNew, columnWidthNew], [headerOld, alignOld, columnWidthOld]) => {
|
||||||
|
// if (headerNew !== headerOld) {
|
||||||
|
// props.optionData.header = headerNew.split(',')
|
||||||
|
// }
|
||||||
|
// if (alignNew !== alignOld) {
|
||||||
|
// props.optionData.align = alignNew.split(',')
|
||||||
|
// }
|
||||||
|
// if (columnWidthNew !== columnWidthOld) {
|
||||||
|
// // @ts-ignore
|
||||||
|
// props.optionData.columnWidth = columnWidthNew.split(',')
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
watch([header, align, columnWidth], ([headerNew, alignNew, columnWidthNew], [headerOld, alignOld, columnWidthOld]) => {
|
// const headerConfigMap: Ref<{ [k: string]: any }> = computed(() => {
|
||||||
if (headerNew !== headerOld) {
|
// return props.optionData.headerConfigMap
|
||||||
props.optionData.header = headerNew.split(',')
|
// })
|
||||||
}
|
// const headerConfig: Ref<any[]> = computed(() => {
|
||||||
if (alignNew !== alignOld) {
|
// return props.optionData.headerConfig
|
||||||
props.optionData.align = alignNew.split(',')
|
// })
|
||||||
}
|
|
||||||
if (columnWidthNew !== columnWidthOld) {
|
const alignOption = [
|
||||||
// @ts-ignore
|
{ label: '左', value: AlignEnum.LEFT },
|
||||||
props.optionData.columnWidth = columnWidthNew.split(',')
|
{ label: '中', value: AlignEnum.CENTER },
|
||||||
}
|
{ label: '右', value: AlignEnum.RIGHT },
|
||||||
|
]
|
||||||
|
// const headerConfigMap: Ref<{ [k: string]: any }> = ref(props.optionData.headerConfigMap)
|
||||||
|
// const headerConfig: Ref<any[]> = ref(props.optionData.headerConfig)
|
||||||
|
|
||||||
|
const { headerConfigMap, headerConfig } = toRefs(props.optionData) as ToRefs<{ headerConfigMap: { [k: string] : MapType }, headerConfig: MapType[] }>
|
||||||
|
|
||||||
|
watch(() => props.optionData.dataset, (v) => {
|
||||||
|
v.dimensions.forEach((k: string) => {
|
||||||
|
// 初始化
|
||||||
|
if(!Object.prototype.hasOwnProperty.call(headerConfigMap.value, k)) {
|
||||||
|
headerConfigMap.value[k] = {
|
||||||
|
show: true,
|
||||||
|
key: k,
|
||||||
|
header: k,
|
||||||
|
align: AlignEnum.LEFT,
|
||||||
|
columnWidth: 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
headerConfig.value = v.dimensions.map((k: string) => {
|
||||||
|
return headerConfigMap.value[k]
|
||||||
|
})
|
||||||
|
headerConfig.value.unshift(headerConfigMap.value['index'])
|
||||||
|
})
|
||||||
|
}, {
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -50,10 +50,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { PropType, onUnmounted, reactive, toRefs, watch, onMounted } from 'vue'
|
import { PropType, onUnmounted, reactive, toRefs, watch, onMounted } from 'vue'
|
||||||
import { CreateComponentType } from '@/packages/index.d'
|
import { CreateComponentType } from '@/packages/index.d'
|
||||||
import { useChartDataFetch } from '@/hooks'
|
import {useChartCommonData, useChartDataFetch} from '@/hooks'
|
||||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||||
import merge from 'lodash/merge'
|
import merge from 'lodash/merge'
|
||||||
import cloneDeep from 'lodash/cloneDeep'
|
import cloneDeep from 'lodash/cloneDeep'
|
||||||
|
import { MapType } from './config'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
chartConfig: {
|
chartConfig: {
|
||||||
@ -197,19 +198,29 @@ const mergeConfig = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const calcHeaderData = () => {
|
const calcHeaderData = () => {
|
||||||
let { header, index, indexHeader } = status.mergedConfig
|
let { header, index, indexHeader, headerConfig, headerConfigMap } = status.mergedConfig
|
||||||
if (!header.length) {
|
// if (!header.length) {
|
||||||
status.header = []
|
// status.header = []
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
header = [...header]
|
// header = [...header]
|
||||||
if (index) header.unshift(indexHeader)
|
// if (index) header.unshift(indexHeader)
|
||||||
status.header = header
|
// status.header = header
|
||||||
|
type ItemType = { show: boolean, header: string }
|
||||||
|
status.header = headerConfig.filter((_: ItemType) => _.show).map((_: ItemType) => _.header)
|
||||||
}
|
}
|
||||||
|
|
||||||
const calcRowsData = () => {
|
const calcRowsData = () => {
|
||||||
let { dataset, index, headerBGC, rowNum } = status.mergedConfig
|
let { dataset: datasetOrigin, index, headerBGC, rowNum } = status.mergedConfig
|
||||||
if (index) {
|
let { headerConfigMap, headerConfig } = status.mergedConfig
|
||||||
|
interface RowType { [k: string]: any }
|
||||||
|
let showCols = headerConfig.filter((_: MapType) => _.show && _.key !== '行号').map((_: MapType) => _.key)
|
||||||
|
let dataset = datasetOrigin.source.map((row: RowType) => {
|
||||||
|
return datasetOrigin.dimensions.filter((_: string) => showCols.includes(_)).map((key: string) => {
|
||||||
|
return row[key]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if (headerConfigMap['index'].show) {
|
||||||
dataset = dataset.map((row: any, i: number) => {
|
dataset = dataset.map((row: any, i: number) => {
|
||||||
row = [...row]
|
row = [...row]
|
||||||
const indexTag = `<span class="index" style="background-color: ${headerBGC};border-radius: 3px;padding: 0px 3px;">${
|
const indexTag = `<span class="index" style="background-color: ${headerBGC};border-radius: 3px;padding: 0px 3px;">${
|
||||||
@ -232,17 +243,21 @@ const calcRowsData = () => {
|
|||||||
|
|
||||||
const calcWidths = () => {
|
const calcWidths = () => {
|
||||||
const { mergedConfig, rowsData } = status
|
const { mergedConfig, rowsData } = status
|
||||||
const { columnWidth, header } = mergedConfig
|
const { columnWidth, header, headerConfig } = mergedConfig
|
||||||
const usedWidth = columnWidth.reduce((all: any, ws: number) => all + ws, 0)
|
// const usedWidth = columnWidth.reduce((all: any, ws: number) => all + ws, 0)
|
||||||
let columnNum = 0
|
// let columnNum = 0
|
||||||
if (rowsData[0]) {
|
// if (rowsData[0]) {
|
||||||
columnNum = (rowsData[0] as any).ceils.length
|
// columnNum = (rowsData[0] as any).ceils.length
|
||||||
} else if (header.length) {
|
// } else if (header.length) {
|
||||||
columnNum = header.length
|
// columnNum = header.length
|
||||||
}
|
// }
|
||||||
const avgWidth = (w.value - usedWidth) / (columnNum - columnWidth.length)
|
// const avgWidth = (w.value - usedWidth) / (columnNum - columnWidth.length)
|
||||||
const widths = new Array(columnNum).fill(avgWidth)
|
// const widths = new Array(columnNum).fill(avgWidth)
|
||||||
status.widths = merge(widths, columnWidth)
|
// status.widths = merge(widths, columnWidth)
|
||||||
|
|
||||||
|
type ItemType = {show: boolean, columnWidth: number}
|
||||||
|
let widths = headerConfig.filter((_: ItemType) => _.show).map((_: ItemType) => _.columnWidth)
|
||||||
|
status.widths = widths
|
||||||
}
|
}
|
||||||
|
|
||||||
const calcHeights = (onresize = false) => {
|
const calcHeights = (onresize = false) => {
|
||||||
@ -252,19 +267,22 @@ const calcHeights = (onresize = false) => {
|
|||||||
if (header.length) allHeight -= headerHeight
|
if (header.length) allHeight -= headerHeight
|
||||||
const avgHeight = allHeight / rowNum
|
const avgHeight = allHeight / rowNum
|
||||||
status.avgHeight = avgHeight
|
status.avgHeight = avgHeight
|
||||||
if (!onresize) status.heights = new Array(dataset.length).fill(avgHeight)
|
if (!onresize) status.heights = new Array(dataset.source.length).fill(avgHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
const calcAligns = () => {
|
const calcAligns = () => {
|
||||||
const { header, mergedConfig } = status
|
const { header, mergedConfig } = status
|
||||||
|
const { headerConfig } = mergedConfig
|
||||||
|
|
||||||
const columnNum = header.length
|
// const columnNum = header.length
|
||||||
|
//
|
||||||
|
// let aligns = new Array(columnNum).fill('left')
|
||||||
|
//
|
||||||
|
// const { align } = mergedConfig
|
||||||
|
//
|
||||||
|
// status.aligns = merge(aligns, align)
|
||||||
|
|
||||||
let aligns = new Array(columnNum).fill('left')
|
status.aligns = headerConfig.map((_: any) => _.align)
|
||||||
|
|
||||||
const { align } = mergedConfig
|
|
||||||
|
|
||||||
status.aligns = merge(aligns, align)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const animation = async (start = false) => {
|
const animation = async (start = false) => {
|
||||||
@ -339,7 +357,12 @@ watch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 数据更新 (默认更新 dataset,若更新之后有其它操作,可添加回调函数)
|
// 数据更新 (默认更新 dataset,若更新之后有其它操作,可添加回调函数)
|
||||||
useChartDataFetch(props.chartConfig, useChartEditStore, (resData: any[]) => {
|
// useChartDataFetch(props.chartConfig, useChartEditStore, (resData: any[]) => {
|
||||||
|
// props.chartConfig.option.dataset = resData
|
||||||
|
// onRestart()
|
||||||
|
// })
|
||||||
|
|
||||||
|
useChartCommonData(props.chartConfig, useChartEditStore, (resData: {}) => {
|
||||||
props.chartConfig.option.dataset = resData
|
props.chartConfig.option.dataset = resData
|
||||||
onRestart()
|
onRestart()
|
||||||
})
|
})
|
||||||
|
@ -11,7 +11,8 @@ export const option = {
|
|||||||
// 展示列
|
// 展示列
|
||||||
header: {
|
header: {
|
||||||
value: [],
|
value: [],
|
||||||
options: []
|
options: [],
|
||||||
|
map: {},
|
||||||
},
|
},
|
||||||
pagination: {
|
pagination: {
|
||||||
page: 1,
|
page: 1,
|
||||||
|
@ -2,16 +2,21 @@
|
|||||||
<collapse-item name="表格设置" :expanded="true">
|
<collapse-item name="表格设置" :expanded="true">
|
||||||
<n-tag type="primary">若配置无响应,请在预览页面查看效果</n-tag>
|
<n-tag type="primary">若配置无响应,请在预览页面查看效果</n-tag>
|
||||||
<setting-item-box name="表头" :alone="true">
|
<setting-item-box name="表头" :alone="true">
|
||||||
<div class="rows" v-for="(row, i) in optionData.header.options" :key="i">
|
<div class="rows">
|
||||||
<div class="columns">{{ row.value }}</div>
|
<div class="columns">字段</div>
|
||||||
<n-input class="columns" v-model:value="row.label" size="small"/>
|
<div class="columns">标题</div>
|
||||||
|
</div>
|
||||||
|
<div class="rows" v-for="(row: any, i) in optionData.header.options" :key="i">
|
||||||
|
<div class="columns">{{ row }}</div>
|
||||||
|
<n-input class="columns" v-model:value="optionData.header.map[row]" size="small"/>
|
||||||
</div>
|
</div>
|
||||||
</setting-item-box>
|
</setting-item-box>
|
||||||
<setting-item-box name="展示列" :alone="true">
|
<setting-item-box name="展示列" :alone="true">
|
||||||
<n-select
|
<n-select
|
||||||
v-model:value="optionData.header.value"
|
v-model:value="optionData.header.value"
|
||||||
:options="optionData.header.options"
|
:options="optionData.header.options.map(_ => ({label: optionData.header.map[_], value: _}))"
|
||||||
multiple
|
multiple
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
</setting-item-box>
|
</setting-item-box>
|
||||||
<setting-item-box :alone="true" name="对齐方式">
|
<setting-item-box :alone="true" name="对齐方式">
|
||||||
@ -178,6 +183,8 @@ const props = defineProps({
|
|||||||
.rows {
|
.rows {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
height: 28px;
|
||||||
|
line-height: 28px;
|
||||||
&:nth-last-child(1){
|
&:nth-last-child(1){
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
@ -80,9 +80,12 @@ watch(
|
|||||||
(newData: any) => {
|
(newData: any) => {
|
||||||
option.dataset = newData
|
option.dataset = newData
|
||||||
option.header.value = newData.dimensions
|
option.header.value = newData.dimensions
|
||||||
console.log(newData.dimensions.toString(), option.header.options.map((_: {value: string}) => _.value).toString())
|
option.header.options = newData.dimensions
|
||||||
if(newData.dimensions.toString() === option.header.options.map((_: {value: string}) => _.value).toString()) return
|
newData.dimensions.forEach((key: string) => {
|
||||||
option.header.options = newData.dimensions.map((_: string) => ({label: _, value: _}))
|
if(!Object.prototype.hasOwnProperty.call(option.header.map, key)) option.header.map[key] = key
|
||||||
|
})
|
||||||
|
// if(newData.dimensions.toString() === option.header.options.map((_: {value: string}) => _.value).toString()) return
|
||||||
|
// option.header.options = newData.dimensions.map((_: string) => ({label: _, value: _}))
|
||||||
// option?.dataset?.dimensions?.forEach((header: any) => {
|
// option?.dataset?.dimensions?.forEach((header: any) => {
|
||||||
// header.align = align.value
|
// header.align = align.value
|
||||||
// })
|
// })
|
||||||
@ -101,11 +104,11 @@ watch(() => props.chartConfig.option.header, v => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const columns = computed(() => {
|
const columns = computed(() => {
|
||||||
let dimensions = option.header.options.filter((_: {label: string, value: string}) => option.header.value.includes(_.value))
|
let dimensions = option.header.options.filter((_: string) => option.header.value.includes(_))
|
||||||
dimensions = dimensions.map((_: {label: string, value: string}) => {
|
dimensions = dimensions.map((_: string) => {
|
||||||
return {
|
return {
|
||||||
title: _.label,
|
title: option.header.map[_],
|
||||||
key: _.value,
|
key: _,
|
||||||
align: align.value
|
align: align.value
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user