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'] ARadio: typeof import('ant-design-vue/es')['Radio']
ARadioButton: typeof import('ant-design-vue/es')['RadioButton'] ARadioButton: typeof import('ant-design-vue/es')['RadioButton']
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup'] ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
ARangePicker: typeof import('ant-design-vue/es')['RangePicker']
ASelect: typeof import('ant-design-vue/es')['Select'] ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption'] ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
ASpace: typeof import('ant-design-vue/es')['Space'] ASpace: typeof import('ant-design-vue/es')['Space']

View File

@ -1,6 +1,21 @@
<template> <template>
<div class="chart-show-box"> <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-group v-model:value="chartType">
<a-radio-button value="line">折线图</a-radio-button> <a-radio-button value="line">折线图</a-radio-button>
<a-radio-button value="bar">柱状图</a-radio-button> <a-radio-button value="bar">柱状图</a-radio-button>
@ -14,26 +29,100 @@
</template> </template>
<script setup> <script setup>
import { computed, ref } from "vue"; import { computed, ref, watch } from "vue";
import Line from "@/plugins/antv-g2plot/line.vue"; import Line from "@/plugins/antv-g2plot/line.vue";
import Column from "@/plugins/antv-g2plot/column.vue"; import Column from "@/plugins/antv-g2plot/column.vue";
import _ from 'lodash';
const props = defineProps({ const props = defineProps({
title: {
type: String,
default: "",
},
chartCfg: { chartCfg: {
type: Object,
default: () => ({}),
},
filterConfig: {
type: Array, type: Array,
default: () => [], default: () => [],
}, },
}); });
const emit = defineEmits(["toFilt"]);
const chartType = ref("line"); 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(() => { const currentChart = computed(() => {
return props.chartCfg[chartType.value]; 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> </script>
<style lang="less" scoped> <style lang="less" scoped>
.chart-wrap { .chart-wrap {
padding: 20px; 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> </style>

View File

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

View File

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

View File

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