|
@@ -16,7 +16,11 @@
|
|
|
"
|
|
"
|
|
|
>
|
|
>
|
|
|
<span>纬度标签</span>
|
|
<span>纬度标签</span>
|
|
|
- <!-- <el-tooltip content="添加纬度" placement="bottom-start">
|
|
|
|
|
|
|
+ <el-tooltip
|
|
|
|
|
+ content="添加纬度"
|
|
|
|
|
+ placement="bottom-start"
|
|
|
|
|
+ v-if="curEdit.type === 'scatter' || curEdit.type === 'radar'"
|
|
|
|
|
+ >
|
|
|
<i
|
|
<i
|
|
|
@click="
|
|
@click="
|
|
|
formLabelAlign.Xdata.push({ lable: '', data: [], id: '' })
|
|
formLabelAlign.Xdata.push({ lable: '', data: [], id: '' })
|
|
@@ -24,24 +28,46 @@
|
|
|
class="el-icon-circle-plus-outline"
|
|
class="el-icon-circle-plus-outline"
|
|
|
style="font-size: 20px"
|
|
style="font-size: 20px"
|
|
|
></i>
|
|
></i>
|
|
|
- </el-tooltip> -->
|
|
|
|
|
|
|
+ </el-tooltip>
|
|
|
</div>
|
|
</div>
|
|
|
<template v-for="(item, ind) in formLabelAlign.Xdata">
|
|
<template v-for="(item, ind) in formLabelAlign.Xdata">
|
|
|
- <el-select
|
|
|
|
|
- style="margin: 5px 0"
|
|
|
|
|
- :key="ind + 'select'"
|
|
|
|
|
- v-model="formLabelAlign.Xdata[ind].id"
|
|
|
|
|
- placeholder="请先进行数据配置"
|
|
|
|
|
- :disabled="disabled"
|
|
|
|
|
- @change="handleXdata"
|
|
|
|
|
- >
|
|
|
|
|
- <el-option
|
|
|
|
|
- v-for="item in selectData"
|
|
|
|
|
- :label="item.label"
|
|
|
|
|
- :value="item.id"
|
|
|
|
|
- :key="item.id"
|
|
|
|
|
- ></el-option>
|
|
|
|
|
- </el-select>
|
|
|
|
|
|
|
+ <div class="attributeItemData">
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ style="margin: 5px 0"
|
|
|
|
|
+ :key="ind + 'select'"
|
|
|
|
|
+ v-model="formLabelAlign.Xdata[ind].id"
|
|
|
|
|
+ placeholder="请先进行数据配置"
|
|
|
|
|
+ :disabled="disabled"
|
|
|
|
|
+ @change="handleXdata"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="item in selectData"
|
|
|
|
|
+ :label="item.label"
|
|
|
|
|
+ :value="item.id"
|
|
|
|
|
+ :key="item.id"
|
|
|
|
|
+ ></el-option>
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-tooltip
|
|
|
|
|
+ v-if="curEdit.type === 'scatter' || curEdit.type === 'radar'"
|
|
|
|
|
+ :content="
|
|
|
|
|
+ formLabelAlign.Xdata.length <= 1
|
|
|
|
|
+ ? '该指标不可删除,最少存在一组指标'
|
|
|
|
|
+ : '删除该指标'
|
|
|
|
|
+ "
|
|
|
|
|
+ placement="bottom-start"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ :disabled="formLabelAlign.Xdata.length <= 1"
|
|
|
|
|
+ @click="removeXdata(ind)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <i
|
|
|
|
|
+ class="el-icon-delete"
|
|
|
|
|
+ style="font-size: 16px; color: red; padding: 0 0 0 10px"
|
|
|
|
|
+ ></i
|
|
|
|
|
+ ></el-button>
|
|
|
|
|
+ </el-tooltip>
|
|
|
|
|
+ </div>
|
|
|
</template>
|
|
</template>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="指标值">
|
|
<el-form-item label="指标值">
|
|
@@ -204,8 +230,12 @@
|
|
|
</template>
|
|
</template>
|
|
|
<script>
|
|
<script>
|
|
|
import { mapState, mapMutations } from "vuex";
|
|
import { mapState, mapMutations } from "vuex";
|
|
|
-import { getFormattedLabels, getFormattedSeries } from "./configFn";
|
|
|
|
|
-
|
|
|
|
|
|
|
+// import { getFormattedLabels, getFormattedSeries } from "./configFn";
|
|
|
|
|
+// import { filterData } from "./chartLogic/dargChartFIlter";
|
|
|
|
|
+import {
|
|
|
|
|
+ handleBarChartLogic,
|
|
|
|
|
+ handleScatterChartLogic,
|
|
|
|
|
+} from "./chartLogic/index";
|
|
|
export default {
|
|
export default {
|
|
|
name: "title",
|
|
name: "title",
|
|
|
props: {
|
|
props: {
|
|
@@ -223,7 +253,16 @@ export default {
|
|
|
data() {
|
|
data() {
|
|
|
return {
|
|
return {
|
|
|
value: "all",
|
|
value: "all",
|
|
|
- formFilterAlign: [],
|
|
|
|
|
|
|
+ formFilterAlign: [
|
|
|
|
|
+ {
|
|
|
|
|
+ filters: [],
|
|
|
|
|
+ filterType1: "",
|
|
|
|
|
+ number1: null,
|
|
|
|
|
+ filterType2: "",
|
|
|
|
|
+ number2: null,
|
|
|
|
|
+ radio: null,
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
options: [
|
|
options: [
|
|
|
{
|
|
{
|
|
|
value: "<",
|
|
value: "<",
|
|
@@ -299,54 +338,6 @@ export default {
|
|
|
this.changeData();
|
|
this.changeData();
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
|
- // 修改后的 filterData 方法
|
|
|
|
|
- filterData(filterData, dataList, label) {
|
|
|
|
|
- const filter = filterData; // 处理第一个条件组
|
|
|
|
|
- const filteredData = dataList.map((item) => {
|
|
|
|
|
- // 如果没有提供 number1 或 filterType1,则默认 condition1 满足
|
|
|
|
|
- if (item !== null) {
|
|
|
|
|
- const condition1 =
|
|
|
|
|
- filter.filterType1 && filter.number1 !== null
|
|
|
|
|
- ? this.calculate(filter.filterType1, item[label], filter.number1)
|
|
|
|
|
- : true;
|
|
|
|
|
- // 如果没有提供 number2 或 filterType2,则默认 condition2 满足
|
|
|
|
|
- const condition2 =
|
|
|
|
|
- filter.filterType2 && filter.number2 !== null
|
|
|
|
|
- ? this.calculate(filter.filterType2, item[label], filter.number2)
|
|
|
|
|
- : true;
|
|
|
|
|
- // 根据逻辑关系 (或/且)
|
|
|
|
|
- if (filter.radio === "1") {
|
|
|
|
|
- return condition1 || condition2 ? item : null; // 满足任一条件
|
|
|
|
|
- } else if (filter.radio === "2") {
|
|
|
|
|
- return condition1 && condition2 ? item : null; // 同时满足两个条件
|
|
|
|
|
- } else if (!condition2) {
|
|
|
|
|
- return null;
|
|
|
|
|
- } else if (!condition1) {
|
|
|
|
|
- return null;
|
|
|
|
|
- } else {
|
|
|
|
|
- // 未指定逻辑关系时默认满足条件
|
|
|
|
|
- return item;
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- return filteredData; // 返回包含 null 的数据
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
- // 修改后的 calculate 方法
|
|
|
|
|
- calculate(operator, testValue, conditionValue) {
|
|
|
|
|
- switch (operator) {
|
|
|
|
|
- case ">":
|
|
|
|
|
- return Number(testValue) > Number(conditionValue);
|
|
|
|
|
- case "<":
|
|
|
|
|
- return Number(testValue) < Number(conditionValue);
|
|
|
|
|
- case "=":
|
|
|
|
|
- return Number(testValue) === Number(conditionValue);
|
|
|
|
|
- default:
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
handleMetrics() {
|
|
handleMetrics() {
|
|
|
this.formLabelAlign.Ydata.push({ lable: "", data: [], id: "" });
|
|
this.formLabelAlign.Ydata.push({ lable: "", data: [], id: "" });
|
|
|
this.formFilterAlign.push({
|
|
this.formFilterAlign.push({
|
|
@@ -363,12 +354,13 @@ export default {
|
|
|
"setCurEdit",
|
|
"setCurEdit",
|
|
|
"setFormFilterAlignData",
|
|
"setFormFilterAlignData",
|
|
|
]),
|
|
]),
|
|
|
- //纬度轴
|
|
|
|
|
|
|
+ //纬度轴 处理整合数据
|
|
|
handleXdata() {
|
|
handleXdata() {
|
|
|
this.formLabelAlign.Xdata = this.updateAxisData(
|
|
this.formLabelAlign.Xdata = this.updateAxisData(
|
|
|
this.formLabelAlign.Xdata
|
|
this.formLabelAlign.Xdata
|
|
|
);
|
|
);
|
|
|
},
|
|
},
|
|
|
|
|
+ //指标值 处理整合数据
|
|
|
handleYdata() {
|
|
handleYdata() {
|
|
|
this.formLabelAlign.Ydata = this.updateAxisData(
|
|
this.formLabelAlign.Ydata = this.updateAxisData(
|
|
|
this.formLabelAlign.Ydata
|
|
this.formLabelAlign.Ydata
|
|
@@ -393,7 +385,7 @@ export default {
|
|
|
if (this.$refs.form) {
|
|
if (this.$refs.form) {
|
|
|
this.$refs.form.resetFields();
|
|
this.$refs.form.resetFields();
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+ //图表内容回显图表配置赋值
|
|
|
if (this.curEdit && this.curEdit.option) {
|
|
if (this.curEdit && this.curEdit.option) {
|
|
|
this.formLabelAlign = {
|
|
this.formLabelAlign = {
|
|
|
text: this.curEdit.option.title?.text || "",
|
|
text: this.curEdit.option.title?.text || "",
|
|
@@ -420,6 +412,7 @@ export default {
|
|
|
},
|
|
},
|
|
|
],
|
|
],
|
|
|
};
|
|
};
|
|
|
|
|
+ //查找是否存在数据
|
|
|
const index = this.formFilterAlignData.findIndex(
|
|
const index = this.formFilterAlignData.findIndex(
|
|
|
(item) => item.id === this.curEdit.id
|
|
(item) => item.id === this.curEdit.id
|
|
|
);
|
|
);
|
|
@@ -445,117 +438,58 @@ export default {
|
|
|
changeChart(isFilter) {
|
|
changeChart(isFilter) {
|
|
|
if (!this.curEdit?.option) return; // 确保 curEdit 和 option 存在
|
|
if (!this.curEdit?.option) return; // 确保 curEdit 和 option 存在
|
|
|
const item = JSON.parse(JSON.stringify(this.curEdit));
|
|
const item = JSON.parse(JSON.stringify(this.curEdit));
|
|
|
- // 确保标题和坐标轴对象存在
|
|
|
|
|
- item.option.title = item.option.title || {};
|
|
|
|
|
- Object.assign(item.option.title, { text: this.formLabelAlign.text });
|
|
|
|
|
- if (this.curEdit.type !== "pie" && this.curEdit.type !== "radar") {
|
|
|
|
|
- if (isFilter === "filter") {
|
|
|
|
|
- // 数据筛选逻辑
|
|
|
|
|
- const filterResult = this.formLabelAlign.Ydata.map(
|
|
|
|
|
- (yItem, index) => ({
|
|
|
|
|
- label: yItem.label,
|
|
|
|
|
- id: yItem.id,
|
|
|
|
|
- data: yItem.data.map((val) => {
|
|
|
|
|
- const filters = this.formFilterAlign[index]?.filters || [];
|
|
|
|
|
- return filters.length > 0 && !filters.includes(val[yItem.label])
|
|
|
|
|
- ? null
|
|
|
|
|
- : val; // 如果不匹配,返回 null;否则返回原始项
|
|
|
|
|
- }),
|
|
|
|
|
- })
|
|
|
|
|
- );
|
|
|
|
|
- // 条件筛选逻辑
|
|
|
|
|
- const filterList = filterResult.map((filteredItem, index) => {
|
|
|
|
|
- const filter = this.formFilterAlign[index];
|
|
|
|
|
- const { filterType1, filterType2, number1, number2 } = filter;
|
|
|
|
|
- if (
|
|
|
|
|
- !filterType1 &&
|
|
|
|
|
- !filterType2 &&
|
|
|
|
|
- number1 == null &&
|
|
|
|
|
- number2 == null
|
|
|
|
|
- ) {
|
|
|
|
|
- // 如果所有条件为空,直接保留原始数据
|
|
|
|
|
- return {
|
|
|
|
|
- label: filteredItem.label,
|
|
|
|
|
- id: filteredItem.id,
|
|
|
|
|
- data: filteredItem.data,
|
|
|
|
|
- };
|
|
|
|
|
- } else {
|
|
|
|
|
- // 执行条件筛选
|
|
|
|
|
- const filterDatas = this.filterData(
|
|
|
|
|
- filter, //条件项
|
|
|
|
|
- filteredItem.data, //过滤数据其中包含null
|
|
|
|
|
- filteredItem.label //过滤数据其中包含null
|
|
|
|
|
|
|
+ if (this.curEdit.type === "scatter") {
|
|
|
|
|
+ const isAllNumbers = (data) =>
|
|
|
|
|
+ data.every((val) =>
|
|
|
|
|
+ val.data.every((vals) => {
|
|
|
|
|
+ // console.log(vals[val.label], "vals[val.label]");
|
|
|
|
|
+ return !isNaN(
|
|
|
|
|
+ Number(vals[val.label] == undefined ? 0 : vals[val.label])
|
|
|
);
|
|
);
|
|
|
- return {
|
|
|
|
|
- label: filteredItem.label,
|
|
|
|
|
- id: filteredItem.id,
|
|
|
|
|
- data: [...filterDatas],
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- item.Xdata = this.formLabelAlign.Xdata;
|
|
|
|
|
- item.Ydata = filterList;
|
|
|
|
|
- } else {
|
|
|
|
|
- // 未筛选,直接赋值
|
|
|
|
|
- item.Xdata = this.formLabelAlign.Xdata;
|
|
|
|
|
- item.Ydata = this.formLabelAlign.Ydata;
|
|
|
|
|
- }
|
|
|
|
|
- // 配置 xAxis 和 yAxis
|
|
|
|
|
- item.option.xAxis = {
|
|
|
|
|
- ...item.option.xAxis,
|
|
|
|
|
- name: this.formLabelAlign.Xlable,
|
|
|
|
|
- };
|
|
|
|
|
- item.option.yAxis = {
|
|
|
|
|
- ...item.option.yAxis,
|
|
|
|
|
- name: this.formLabelAlign.Ylable,
|
|
|
|
|
- };
|
|
|
|
|
- if (item.Ydata[0]?.data?.length > 0) {
|
|
|
|
|
- item.option.series = getFormattedSeries(
|
|
|
|
|
- item.Ydata,
|
|
|
|
|
- this.curEdit.type
|
|
|
|
|
|
|
+ })
|
|
|
);
|
|
);
|
|
|
- }
|
|
|
|
|
- if (item.Xdata[0]?.data?.length > 0) {
|
|
|
|
|
- item.option.xAxis = {
|
|
|
|
|
- ...item.option.xAxis,
|
|
|
|
|
- data: item.Xdata[0].data,
|
|
|
|
|
- axisTick: { alignWithLabel: true },
|
|
|
|
|
- axisLabel: {
|
|
|
|
|
- formatter: (value, index) =>
|
|
|
|
|
- value !== null
|
|
|
|
|
- ? getFormattedLabels(index, item.Xdata, value)
|
|
|
|
|
- : "",
|
|
|
|
|
- },
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- item.option.tooltip = {
|
|
|
|
|
- trigger: "axis",
|
|
|
|
|
- axisPointer: { type: "shadow" },
|
|
|
|
|
- formatter: (params) => {
|
|
|
|
|
- const index = params[0]?.dataIndex; // 获取当前数据点索引
|
|
|
|
|
- const content = params
|
|
|
|
|
- .map(
|
|
|
|
|
- (param) =>
|
|
|
|
|
- `${param.marker}${param.seriesName}: ${param.value}`
|
|
|
|
|
- )
|
|
|
|
|
- .join("<br/>");
|
|
|
|
|
- const customLabels = getFormattedLabels(index, item.Xdata);
|
|
|
|
|
- return `${customLabels}<br/>${content}`;
|
|
|
|
|
- },
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ // console.log(isAllNumbers(this.formLabelAlign.Xdata), "isAllNumbers");
|
|
|
|
|
+ const isAllNumbersXdata = isAllNumbers(this.formLabelAlign.Xdata);
|
|
|
|
|
+ const isAllNumbersYdata = isAllNumbers(this.formLabelAlign.Ydata);
|
|
|
|
|
+ if (!isAllNumbersXdata || !isAllNumbersYdata) {
|
|
|
|
|
+ this.$message.warning("请选择数值项进行散点图绘制");
|
|
|
|
|
+ return;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ // 确保标题和坐标轴对象存在
|
|
|
|
|
+ item.option.title = item.option.title || {};
|
|
|
|
|
+ Object.assign(item.option.title, { text: this.formLabelAlign.text });
|
|
|
|
|
+ if (this.curEdit.type === "bar" || this.curEdit.type === "line") {
|
|
|
|
|
+ handleBarChartLogic(
|
|
|
|
|
+ item,
|
|
|
|
|
+ this.formLabelAlign,
|
|
|
|
|
+ this.formFilterAlign,
|
|
|
|
|
+ isFilter,
|
|
|
|
|
+ this.curEdit.type
|
|
|
|
|
+ );
|
|
|
|
|
+ } else if (this.curEdit.type === "scatter") {
|
|
|
|
|
+ handleScatterChartLogic(
|
|
|
|
|
+ item,
|
|
|
|
|
+ this.formLabelAlign,
|
|
|
|
|
+ this.formFilterAlign,
|
|
|
|
|
+ isFilter,
|
|
|
|
|
+ this.curEdit.type
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //设置仓库
|
|
|
this.setFormFilterAlignData({
|
|
this.setFormFilterAlignData({
|
|
|
id: this.curEdit.id,
|
|
id: this.curEdit.id,
|
|
|
data: JSON.parse(JSON.stringify(this.formFilterAlign)),
|
|
data: JSON.parse(JSON.stringify(this.formFilterAlign)),
|
|
|
});
|
|
});
|
|
|
-
|
|
|
|
|
this.updateChart(item); // 更新图表
|
|
this.updateChart(item); // 更新图表
|
|
|
},
|
|
},
|
|
|
removeYdata(index) {
|
|
removeYdata(index) {
|
|
|
this.formLabelAlign.Ydata.splice(index, 1); // 删除当前项
|
|
this.formLabelAlign.Ydata.splice(index, 1); // 删除当前项
|
|
|
},
|
|
},
|
|
|
|
|
+ removeXdata(index) {
|
|
|
|
|
+ this.formLabelAlign.Xdata.splice(index, 1); // 删除当前项
|
|
|
|
|
+ },
|
|
|
},
|
|
},
|
|
|
};
|
|
};
|
|
|
</script>
|
|
</script>
|