feat: 新增图表渲染

This commit is contained in:
sy2084
2024-07-17 11:33:26 +08:00
parent 32ac8041ee
commit f6afbac2a5
10 changed files with 192 additions and 55 deletions

View File

@@ -2,16 +2,16 @@
<div class="normal-container">
<div class="view-create-box">
<div class="left-box">
<a-form :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
<a-form :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
<a-form-item label="项目"
><a-select
placeholder="请选择项目"
:options="projectSel"
v-model:value="projectId"
@change="onProjectChange"
></a-select
><a-select
placeholder="请选择项目"
:options="projectSel"
v-model:value="projectId"
@change="onProjectChange"
></a-select
></a-form-item>
<a-form-item label="数据">
<a-form-item label="数据来源">
<a-select
placeholder="请选择"
:options="modularSel"
@@ -19,16 +19,29 @@
@change="onModularChange"
></a-select>
</a-form-item>
<a-form-item label="字段">
<a-checkbox-group v-if="fieldList.length" v-model:value="fieldIds">
<a-form-item label="展示类型">
<a-select
placeholder="请选择展示类型"
:options="showTypeSel"
v-model:value="showTypeId"
@change="onShowTypeChange"
></a-select>
</a-form-item>
<a-form-item label="字段" v-if="fieldList.length">
<a-checkbox-group v-model:value="fieldIds">
<a-checkbox
v-for="(item, index) in fieldList"
:key="index"
:value="item.value"
>{{ item.label }}</a-checkbox
>{{ item.label }}</a-checkbox
>
</a-checkbox-group>
<a-empty v-else description="暂无字段数据" />
</a-form-item>
<a-form-item label="x轴" v-if="xDataList.length">
<a-radio-group :options="xDataList" v-model:value="xDataId"></a-radio-group>
</a-form-item>
<a-form-item label="y轴" v-if="yDataList.length">
<a-checkbox-group :options="yDataList" v-model:value="yDataId"></a-checkbox-group>
</a-form-item>
</a-form>
<div class="footer">
@@ -36,7 +49,7 @@
class="preview-btn"
:loading="previewLoading"
@click="toPreview"
>预览</a-button
>预览</a-button
>
<a-button type="primary" @click="addViewName">点击保存</a-button>
</div>
@@ -74,7 +87,7 @@
:columns="previewData.columnConfig"
:data-source="previewData.dataList"
:pagination="false"
:scroll="{ x: 1200 }"
:scroll="{ x: 1000, y: `calc(100vh - 260px)` }"
size="small"
bordered
></a-table>
@@ -89,6 +102,7 @@
/>
</div>
</div>
<y-chart v-if="previewData.type === 'chart'" :chartCfg="previewData.chartCfg"></y-chart>
<div class="preview-area" v-else>
<div><BarChartOutlined /></div>
<div>预览区</div>
@@ -113,16 +127,29 @@
<script setup>
import { onMounted, reactive, ref } from "vue";
import { getProModularField, preview, saveView } from "./service";
import {
getProModularField,
preview,
saveView,
getShowTypeSelect,
getFieldOpts,
} from "./service";
import { message } from "ant-design-vue";
import { BarChartOutlined } from "@ant-design/icons-vue";
import yChart from "@/components/common/y-chart.vue";
const projectSel = ref([]);
const modularSel = ref([]);
const fieldList = ref([]);
const projectSel = ref([]); // 项目下拉
const modularSel = ref([]) // 数据来源下拉
const showTypeSel = ref([]); // 展示类型下拉
const fieldList = ref([]); // 字段列表
const xDataList = ref([]); // x轴数据列表
const yDataList = ref([]); // y轴数据列表
const projectId = ref();
const modularId = ref();
const showTypeId = ref();
const fieldIds = ref([]);
const xDataId = ref();
const yDataId = ref();
const previewLoading = ref(false);
const nameVisible = ref(false);
@@ -134,6 +161,7 @@ const previewData = reactive({
columnConfig: [], // 表格表头
dataList: [], // 表格数据
filterData: {},
chartCfg: {},
page: 1,
perPage: 20,
total: 0,
@@ -141,6 +169,7 @@ const previewData = reactive({
onMounted(() => {
toGetProModularField();
toGetShowTypes();
});
const toGetProModularField = () => {
@@ -149,6 +178,31 @@ const toGetProModularField = () => {
});
};
// 获取展示类型下拉
const toGetShowTypes = () => {
getShowTypeSelect().then((res) => {
showTypeSel.value = res.data;
});
};
// 获取字段列表
const toGetFieldOpts = () => {
getFieldOpts({
modularId: modularId.value,
showTypeId: showTypeId.value,
}).then((res) => {
fieldList.value = res.data.list ? tranformList(res.data.list) : [];
xDataList.value = res.data.x_data ? tranformList(res.data.x_data) : [];
yDataList.value = res.data.y_data ? tranformList(res.data.y_data) : [];
if (!fieldList.value.length) {
fieldIds.value = [];
} else {
xDataId.value = undefined;
yDataId.value = [];
}
});
};
const onProjectChange = (val) => {
const target = projectSel.value.find((item) => item.value === val);
modularSel.value = target.child;
@@ -159,11 +213,24 @@ const onProjectChange = (val) => {
};
const onModularChange = (val) => {
const target = modularSel.value.find((item) => item.value === val);
fieldList.value = target.child;
// const target = modularSel.value.find((item) => item.value === val);
// fieldList.value = target.child;
resetPreviewData();
};
const onShowTypeChange = () => {
toGetFieldOpts();
};
const tranformList = (list) => {
return list.map((item) => {
return {
label: item.field_name,
value: item.field_id,
};
});
}
const resetPreviewData = () => {
previewData.type = "";
previewData.filterConfig = [];
@@ -194,6 +261,9 @@ const toPreview = () => {
page: previewData.page,
perPage: previewData.perPage,
filter,
showTypeId: showTypeId.value,
xDataId: xDataId.value.toString(),
yDataId: yDataId.value.toString(),
})
.then((res) => {
previewData.type = res.data.type;
@@ -207,6 +277,8 @@ const toPreview = () => {
previewData.columnConfig = res.data.header;
previewData.dataList = res.data.data;
previewData.total = res.data.count;
} else {
previewData.chartCfg = res.data.config;
}
})
.finally(() => {
@@ -228,8 +300,11 @@ const toSaveView = () => {
modularId: modularId.value,
fieldIds: fieldIds.value.toString(),
previewName: previewName.value,
showTypeId: showTypeId.value,
xDataId: xDataId.value.toString(),
yDataId: yDataId.value.toString(),
}).then(() => {
message.success("保存成功");
message.success("保存成功,可前往视图列表查看");
nameVisible.value = false;
});
};
@@ -282,7 +357,6 @@ const toFilt = () => {
font-size: 100px;
}
}
.y-table-filter {
display: flex;
flex-wrap: wrap;
@@ -290,6 +364,7 @@ const toFilt = () => {
.filter-item {
margin-right: 10px;
margin-bottom: 6px;
font-size: 14px;
}
.input-item {
width: 180px;

View File

@@ -7,8 +7,26 @@ export function getProModularField() {
});
}
// 展示类型下拉
export function getShowTypeSelect() {
return get({
url: `/api/v1/modular/get-show-type-drop`,
});
}
// 字段列表
export function getFieldOpts({ modularId, showTypeId }) {
return get({
url: "/api/v1/preview/get-preview-field",
params: {
modular_id: modularId,
show_type_id: showTypeId,
},
});
}
// 预览
export function preview({ modularId, fieldIds, page, perPage, filter }) {
export function preview({ modularId, fieldIds, page, perPage, filter, showTypeId, xDataId, yDataId }) {
return post({
url: "api/v1/preview/view",
data: {
@@ -17,18 +35,24 @@ export function preview({ modularId, fieldIds, page, perPage, filter }) {
page,
per_page: perPage,
filter,
show_type_id: showTypeId,
x_data_id: xDataId,
y_data_id: yDataId,
},
});
}
// 点击保存
export function saveView({ modularId, fieldIds, previewName }) {
export function saveView({ modularId, fieldIds, previewName, showTypeId, xDataId, yDataId }) {
return post({
url: "api/v1/preview/save",
data: {
modular_id: modularId,
field_ids: fieldIds,
preview_name: previewName,
show_type_id: showTypeId,
x_data_id: xDataId,
y_data_id: yDataId,
},
});
}

View File

@@ -2,7 +2,7 @@
<div class="normal-container">
<div class="view-list-box">
<div class="left-box">
<a-form :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
<a-form :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
<a-form-item label="项目">
<a-select
:options="projectSel"
@@ -11,11 +11,11 @@
@change="onProjectChange"
></a-select>
</a-form-item>
<a-form-item label="数据">
<a-form-item label="数据来源">
<a-select
:options="modularSel"
v-model:value="modularId"
placeholder="请选择数据表"
placeholder="请先选好项目再选择"
@change="onModularChange"
></a-select>
</a-form-item>