|
|
|
@ -82,7 +82,7 @@
|
|
|
|
</el-scrollbar>
|
|
|
|
</el-scrollbar>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="main-right">
|
|
|
|
<div class="main-right">
|
|
|
|
<el-scrollbar height="500px" ref="scrollbar" style="padding: 20px">
|
|
|
|
<el-scrollbar height="590px" ref="scrollbar" style="padding: 20px">
|
|
|
|
<div>
|
|
|
|
<div>
|
|
|
|
<span style="font-weight: bold; font-size: 18px; color: #3596eb">分析数据:</span>
|
|
|
|
<span style="font-weight: bold; font-size: 18px; color: #3596eb">分析数据:</span>
|
|
|
|
<el-table :data="tableData2" style="width: 98%; margin-top: 10px" :header-cell-style="headerCellStyle" height="350">
|
|
|
|
<el-table :data="tableData2" style="width: 98%; margin-top: 10px" :header-cell-style="headerCellStyle" height="350">
|
|
|
|
@ -103,6 +103,11 @@
|
|
|
|
</el-table-column>
|
|
|
|
</el-table-column>
|
|
|
|
</el-table>
|
|
|
|
</el-table>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="pdfRef" id="pdfRef" style="margin-top: 20px; display: flex" v-show="flagUP">
|
|
|
|
|
|
|
|
<div style="background: #ffffff">
|
|
|
|
|
|
|
|
<div id="main" style="width: 550px; height: 500px"></div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</el-scrollbar>
|
|
|
|
</el-scrollbar>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
@ -313,9 +318,11 @@ import useAlgorithmStore from "@/store/modules/algorithm.js";
|
|
|
|
const algorithmStore = useAlgorithmStore();
|
|
|
|
const algorithmStore = useAlgorithmStore();
|
|
|
|
import popModel from "@/views/components/popModal.vue";
|
|
|
|
import popModel from "@/views/components/popModal.vue";
|
|
|
|
import * as echarts from "echarts";
|
|
|
|
import * as echarts from "echarts";
|
|
|
|
|
|
|
|
import { htmlPdf } from "@/utils/pdf.js";
|
|
|
|
import * as API from "@/api/AI.js";
|
|
|
|
import * as API from "@/api/AI.js";
|
|
|
|
import { getUserInfo } from "@/utils/auth";
|
|
|
|
import { getUserInfo } from "@/utils/auth";
|
|
|
|
import * as XLSX from "XLSX";
|
|
|
|
import * as XLSX from "XLSX";
|
|
|
|
|
|
|
|
import JSZip from "jszip";
|
|
|
|
import { onMounted, reactive } from "vue";
|
|
|
|
import { onMounted, reactive } from "vue";
|
|
|
|
const { proxy } = getCurrentInstance();
|
|
|
|
const { proxy } = getCurrentInstance();
|
|
|
|
const dialogVisible = ref(false);
|
|
|
|
const dialogVisible = ref(false);
|
|
|
|
@ -398,10 +405,72 @@ const handleChange = (info) => {
|
|
|
|
fileList.value.push(info);
|
|
|
|
fileList.value.push(info);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
const flag = ref(false);
|
|
|
|
const flag = ref(false);
|
|
|
|
|
|
|
|
let myChart;
|
|
|
|
|
|
|
|
const getRandomColorHex = () => {
|
|
|
|
|
|
|
|
const randomValue = (min, max) => {
|
|
|
|
|
|
|
|
// 生成 min 到 max 之间的随机整数
|
|
|
|
|
|
|
|
const value = Math.floor(Math.random() * (max - min + 1)) + min;
|
|
|
|
|
|
|
|
// 将整数转换为两位十六进制形式
|
|
|
|
|
|
|
|
return value.toString(16).padStart(2, "0");
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 限制红色通道较低,绿色和蓝色通道较高
|
|
|
|
|
|
|
|
const r = randomValue(0, 128); // 红色通道较低 (0-128)
|
|
|
|
|
|
|
|
const g = randomValue(128, 255); // 绿色通道较高 (128-255)
|
|
|
|
|
|
|
|
const b = randomValue(128, 255); // 蓝色通道较高 (128-255)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return `#${r}${g}${b}`;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
//图标添加数据
|
|
|
|
|
|
|
|
const addData = (myChart, newData, color) => {
|
|
|
|
|
|
|
|
// 获取当前的数据
|
|
|
|
|
|
|
|
let currentData = myChart.getOption().series[0].data || [];
|
|
|
|
|
|
|
|
// 添加新数据集,并为每个数据点单独设置颜色
|
|
|
|
|
|
|
|
newData.forEach((dataPoint) => {
|
|
|
|
|
|
|
|
currentData.push({
|
|
|
|
|
|
|
|
value: [dataPoint[0], dataPoint[1]],
|
|
|
|
|
|
|
|
itemStyle: { color: color },
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
// 更新图表
|
|
|
|
|
|
|
|
myChart.setOption({
|
|
|
|
|
|
|
|
series: [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
data: currentData,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
onMounted(() => {
|
|
|
|
getList();
|
|
|
|
getList();
|
|
|
|
optionData();
|
|
|
|
optionData();
|
|
|
|
|
|
|
|
var chartDom = document.getElementById("main");
|
|
|
|
|
|
|
|
myChart = echarts.init(chartDom);
|
|
|
|
|
|
|
|
var option = {
|
|
|
|
|
|
|
|
dataset: [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
source: [], // 初始时数据为空
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
tooltip: {
|
|
|
|
|
|
|
|
position: "top",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
xAxis: {},
|
|
|
|
|
|
|
|
yAxis: {},
|
|
|
|
|
|
|
|
series: [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
type: "line",
|
|
|
|
|
|
|
|
encode: { tooltip: [0, 1] },
|
|
|
|
|
|
|
|
symbolSize: 8,
|
|
|
|
|
|
|
|
itemStyle: {
|
|
|
|
|
|
|
|
borderColor: "#555",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
// 设置初始的配置
|
|
|
|
|
|
|
|
myChart.setOption(option);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const optionData = () => {
|
|
|
|
const optionData = () => {
|
|
|
|
@ -532,35 +601,6 @@ const computation = () => {
|
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
loading1.value = true;
|
|
|
|
loading1.value = true;
|
|
|
|
if (input4.value === "线性回归") {
|
|
|
|
|
|
|
|
if (input5.value.length > 1) {
|
|
|
|
|
|
|
|
proxy.$modal.msgError("y变量数量有误!");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (input6.value.length != 2 || input6.value.length > 2) {
|
|
|
|
|
|
|
|
proxy.$modal.msgError("x变量数量有误!");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
flagColumn.value = true;
|
|
|
|
|
|
|
|
tableData2.value.forEach((item) => {
|
|
|
|
|
|
|
|
sendData.y.push(item[input5.value[0]]);
|
|
|
|
|
|
|
|
sendData.x.push([item[input6.value[0]], item[input6.value[1]]]);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
API.linearRegression(sendData).then((res) => {
|
|
|
|
|
|
|
|
tableLabel2.length = 0;
|
|
|
|
|
|
|
|
for (const key in res.data) {
|
|
|
|
|
|
|
|
tableLabel2.push({
|
|
|
|
|
|
|
|
label: key,
|
|
|
|
|
|
|
|
prop: key,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
let data = res.data;
|
|
|
|
|
|
|
|
data.slopes = data.slopes.join(",");
|
|
|
|
|
|
|
|
tableData3.value = [data];
|
|
|
|
|
|
|
|
predictionResults.value = "";
|
|
|
|
|
|
|
|
loading1.value = false;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (input5.value.length > 1) {
|
|
|
|
if (input5.value.length > 1) {
|
|
|
|
proxy.$modal.msgError("y变量数量有误!");
|
|
|
|
proxy.$modal.msgError("y变量数量有误!");
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
@ -591,7 +631,33 @@ const computation = () => {
|
|
|
|
predictionResults.value = "";
|
|
|
|
predictionResults.value = "";
|
|
|
|
loading1.value = true;
|
|
|
|
loading1.value = true;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
//表格
|
|
|
|
|
|
|
|
let sendData2={}
|
|
|
|
|
|
|
|
if(input5.value[0]==="sales_volume"){
|
|
|
|
|
|
|
|
sendData2={
|
|
|
|
|
|
|
|
userId:JSON.parse(getUserInfo()).userId,
|
|
|
|
|
|
|
|
y:tableData2.value.map(item=>item.sales_volume),
|
|
|
|
|
|
|
|
x:tableData2.value.map(item=>item.sales_forehead)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
|
|
sendData2={
|
|
|
|
|
|
|
|
userId:JSON.parse(getUserInfo()).userId,
|
|
|
|
|
|
|
|
y:tableData2.value.map(item=>item.sales_forehead),
|
|
|
|
|
|
|
|
x:tableData2.value.map(item=>item.sales_volume)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
API.regressionAnalysisTrendChart(sendData2).then((res)=>{
|
|
|
|
|
|
|
|
myChart.setOption({
|
|
|
|
|
|
|
|
series: [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
data: [], // 清空数据
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
const bgColor = getRandomColorHex();
|
|
|
|
|
|
|
|
addData(myChart,res.data,bgColor)
|
|
|
|
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
proxy.$modal.msgWarning("请模型参数进行设置!");
|
|
|
|
proxy.$modal.msgWarning("请模型参数进行设置!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -616,19 +682,6 @@ const handleClick = (item) => {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
const predictionResults = ref("");
|
|
|
|
const predictionResults = ref("");
|
|
|
|
const Forecasting = () => {
|
|
|
|
const Forecasting = () => {
|
|
|
|
// if (nowData.value.type === "线性回归") {
|
|
|
|
|
|
|
|
// const sendData = {
|
|
|
|
|
|
|
|
// intercept: nowData.value.intercept,
|
|
|
|
|
|
|
|
// type: nowData.value.type,
|
|
|
|
|
|
|
|
// slopes: nowData.value.slopes.split(",").map(Number),
|
|
|
|
|
|
|
|
// raX: formInline2.user.split(",").map(Number),
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
// API.logisticRegressionPrediction(sendData).then((res) => {
|
|
|
|
|
|
|
|
// dialogVisible2.value = false;
|
|
|
|
|
|
|
|
// predictionResults.value = res.data;
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// if (nowData.value.type === "逻辑回归") {
|
|
|
|
|
|
|
|
const sendData = {
|
|
|
|
const sendData = {
|
|
|
|
intercept: nowData.value.intercept,
|
|
|
|
intercept: nowData.value.intercept,
|
|
|
|
slope: nowData.value.slope,
|
|
|
|
slope: nowData.value.slope,
|
|
|
|
@ -645,9 +698,22 @@ const upLoad = () => {
|
|
|
|
if (!tableDom) {
|
|
|
|
if (!tableDom) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const wb = XLSX.utils.table_to_book(tableDom);
|
|
|
|
const wb = XLSX.utils.table_to_book(tableDom);
|
|
|
|
XLSX.writeFile(wb, "回归分析.xlsx");
|
|
|
|
// XLSX.writeFile(wb, '聚类分析.xlsx');
|
|
|
|
|
|
|
|
const zip = new JSZip();
|
|
|
|
|
|
|
|
const excelBlob = XLSX.write(wb, { bookType: "xlsx", type: "array" });
|
|
|
|
|
|
|
|
zip.file("回归分析.xlsx", new Blob([excelBlob], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }));
|
|
|
|
|
|
|
|
zip.file("回归分析图.pdf", handleExport());
|
|
|
|
|
|
|
|
zip.generateAsync({ type: "blob" }).then((content) => {
|
|
|
|
|
|
|
|
saveAs(content, "回归分析.zip");
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
//图表导出pdf
|
|
|
|
|
|
|
|
const handleExport = async (name) => {
|
|
|
|
|
|
|
|
var fileName = "回归分析图";
|
|
|
|
|
|
|
|
const fileList = document.getElementsByClassName("pdfRef"); // 很重要
|
|
|
|
|
|
|
|
const pdfBlob = await htmlPdf(fileName, document.querySelector("#pdfRef"), fileList, true);
|
|
|
|
|
|
|
|
return pdfBlob;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
const startOver = () => {
|
|
|
|
const startOver = () => {
|
|
|
|
input.value = "";
|
|
|
|
input.value = "";
|
|
|
|
|