fix: 调整数据图表组件

This commit is contained in:
sy2084 2024-07-17 20:02:31 +08:00
parent f6afbac2a5
commit dfa40d207f
5 changed files with 141 additions and 14 deletions

1
components.d.ts vendored
View File

@ -28,6 +28,7 @@ declare module 'vue' {
ARadio: typeof import('ant-design-vue/es')['Radio']
ARadioButton: typeof import('ant-design-vue/es')['RadioButton']
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
ARangePicker: typeof import('ant-design-vue/es')['RangePicker']
ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
ASpace: typeof import('ant-design-vue/es')['Space']

View File

@ -1,6 +1,21 @@
<template>
<div class="chart-show-box">
<div class="switch-type">
<div class="chart-name">
<div class="title">{{ title }}</div>
</div>
<div class="chart-header">
<div class="chart-filter">
<div v-for="(item, index) in filterConfig" :key="index" class="filter-item">
<div>
<a-radio-group v-model:value="dateType" button-style="solid">
<a-radio-button value="day"></a-radio-button>
<a-radio-button value="week"></a-radio-button>
<a-radio-button value="month"></a-radio-button>
</a-radio-group>
<a-range-picker v-if="item.type === 'time'" class="date-item" v-model:value="filterData[item.name]" :picker="rangePicker" @change="toFilt" />
</div>
</div>
</div>
<a-radio-group v-model:value="chartType">
<a-radio-button value="line">折线图</a-radio-button>
<a-radio-button value="bar">柱状图</a-radio-button>
@ -14,26 +29,100 @@
</template>
<script setup>
import { computed, ref } from "vue";
import { computed, ref, watch } from "vue";
import Line from "@/plugins/antv-g2plot/line.vue";
import Column from "@/plugins/antv-g2plot/column.vue";
import _ from 'lodash';
const props = defineProps({
title: {
type: String,
default: "",
},
chartCfg: {
type: Object,
default: () => ({}),
},
filterConfig: {
type: Array,
default: () => [],
},
});
const emit = defineEmits(["toFilt"]);
const chartType = ref("line");
const dateType = ref("day");
const filterData = ref({});
const rangePicker = computed(() => {
switch(dateType.value) {
case 'week':
return 'week';
case 'month':
return 'month';
default:
return 'date';
}
});
const currentChart = computed(() => {
return props.chartCfg[chartType.value];
})
watch(
() => props.filterConfig,
(newVal) => {
newVal.forEach((item) => {
filterData.value[item.name] = undefined;
});
},
);
const toFilt = () => {
const cloneFilter = _.cloneDeep(props.filterConfig);
const filter = cloneFilter
.filter((item) => {
return filterData.value[item.name] !== undefined && filterData.value[item.name] !== null;
})
.map((item) => {
return item.type === 'time' ? {
name: item.name,
type: item.type,
start_time: dateType.value === 'month' ? filterData.value[item.name][0].format('YYYY-MM') : filterData.value[item.name][0].format('YYYY-MM-DD'),
end_time: dateType.value === 'month' ? filterData.value[item.name][1].format('YYYY-MM') : filterData.value[item.name][1].format('YYYY-MM-DD'),
date_type: dateType.value,
} : {
name: item.name,
type: item.type,
value: filterData.value[item.name],
}
})
emit('toFilt', {
filter,
});
};
</script>
<style lang="less" scoped>
.chart-wrap {
padding: 20px;
}
.chart-name {
margin-bottom: 8px;
.title {
font-size: 18px;
font-weight: bold;
}
}
.chart-header {
display: flex;
justify-content: space-between;
}
.date-item {
margin-left: 10px;
}
</style>

View File

@ -1,5 +1,8 @@
<template>
<div class="y-table-container">
<div class="y-table-name">
<div class="title">{{ title }}</div>
</div>
<div class="y-table-filter">
<div
v-for="(item, index) in filterConfig"
@ -16,13 +19,14 @@
@change="toFilt"
></a-select>
<a-input
v-if="item.type === 'text'"
v-else-if="item.type === 'text'"
class="input-item"
placeholder="请输入"
allow-clear
v-model:value="filterData[item.name]"
@change="toFilt"
/>
<a-range-picker v-else-if="item.type === 'time'" class="date-item" v-model:value="filterData[item.name]" @change="toFilt" />
</div>
</div>
<div class="y-table-content">
@ -30,7 +34,7 @@
:columns="columnConfig"
:data-source="dataList"
:pagination="false"
:scroll="{ x: 1000, y: `calc(100vh - 260px)` }"
:scroll="{ x: 1000, y: `calc(100vh - 280px)` }"
size="small"
bordered
></a-table>
@ -69,8 +73,12 @@ const props = defineProps({
type: Number,
default: 0,
},
title: {
type: String,
default: "",
},
});
const emit = defineEmits(["handleFilt"]);
const emit = defineEmits(["toFilt"]);
const filterData = ref({});
@ -93,10 +101,15 @@ const getData = () => {
const cloneFilter = _.cloneDeep(props.filterConfig);
const filter = cloneFilter
.filter((item) => {
return filterData.value[item.name] !== undefined;
return filterData.value[item.name] !== undefined && filterData.value[item.name] !== null;
})
.map((item) => {
return {
return item.type === 'time' ? {
name: item.name,
type: item.type,
start_time: filterData.value[item.name][0].format('YYYY-MM-DD'),
end_time: filterData.value[item.name][1].format('YYYY-MM-DD'),
} : {
name: item.name,
type: item.type,
value: filterData.value[item.name],
@ -119,6 +132,13 @@ const pageChange = () => {
</script>
<style lang="less" scoped>
.y-table-name {
margin-bottom: 10px;
.title {
font-size: 18px;
font-weight: bold;
}
}
.y-table-filter {
display: flex;
flex-wrap: wrap;
@ -131,10 +151,14 @@ const pageChange = () => {
.input-item {
width: 180px;
}
.date-item {
width: 240px;
}
.y-table-content {
margin-top: 10px;
}
.pagination-box {
text-align: center;
margin-top: 10px;
}
</style>

View File

@ -56,9 +56,12 @@
</div>
<div class="right-box">
<div class="y-table-container" v-if="previewData.type === 'table'">
<div class="y-table-name">
<div class="title">{{ previewData.preview_name }}</div>
</div>
<div class="y-table-filter">
<div
v-for="(item, index) in previewData.filterConfig"
v-for="item in previewData.filterConfig"
:key="item.name"
class="filter-item"
>
@ -80,6 +83,7 @@
v-model:value="previewData.filterData[item.name]"
@change="toFilt"
/>
<a-range-picker v-if="item.type === 'date'" class="input-item" v-model:value="previewData.filterData[item.name]" @change="toFilt" />
</div>
</div>
<div class="y-table-content">
@ -102,7 +106,7 @@
/>
</div>
</div>
<y-chart v-if="previewData.type === 'chart'" :chartCfg="previewData.chartCfg"></y-chart>
<y-chart v-else-if="previewData.type === 'chart'" :chart-cfg="previewData.chartCfg"></y-chart>
<div class="preview-area" v-else>
<div><BarChartOutlined /></div>
<div>预览区</div>
@ -262,8 +266,8 @@ const toPreview = () => {
perPage: previewData.perPage,
filter,
showTypeId: showTypeId.value,
xDataId: xDataId.value.toString(),
yDataId: yDataId.value.toString(),
xDataId: xDataId.value?.toString(),
yDataId: yDataId.value?.toString(),
})
.then((res) => {
previewData.type = res.data.type;
@ -357,6 +361,12 @@ const toFilt = () => {
font-size: 100px;
}
}
.y-table-name {
.title {
font-size: 18px;
font-weight: bold;
}
}
.y-table-filter {
display: flex;
flex-wrap: wrap;

View File

@ -73,16 +73,18 @@
<div class="right-box">
<y-table
v-if="selectViewInfo.type === 'table'"
:filterConfig="selectViewInfo.filter"
:dataList="selectViewInfo.data"
:columnConfig="selectViewInfo.header"
:filter-config="selectViewInfo.filter"
:data-list="selectViewInfo.data"
:column-config="selectViewInfo.header"
:total="selectViewInfo.count"
:title="selectViewInfo.preview_name"
@toFilt="
(params) => {
toGetViewInfo(params);
}
"
/>
<y-chart v-else-if="selectViewInfo.type === 'chart'" :chartCfg="selectViewInfo.config" :title="selectViewInfo.preview_name" :filter-config="selectViewInfo.filter" @toFilt="toGetViewInfo" />
<div class="preview-area" v-else>
<div><BarChartOutlined /></div>
<div>展示区</div>
@ -182,6 +184,7 @@ const toDelete = (previewId) => {
padding: 10px;
flex-shrink: 0;
border-right: 1px solid #ddd;
overflow: auto;
}
:deep(.ant-table-row:hover) {