fix: 调整数据图表组件
This commit is contained in:
parent
f6afbac2a5
commit
dfa40d207f
1
components.d.ts
vendored
1
components.d.ts
vendored
@ -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']
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user