qinzhenpen 1 year ago
commit 73aded467d

@ -36,7 +36,7 @@
"md-editor-v3": "^4.18.1",
"nprogress": "0.2.0",
"pinia": "2.0.22",
"video.js": "^8.17.3",
"video.js": "7.x",
"vue": "^3.2.47",
"vue-cropper": "1.0.3",
"vue-router": "4.1.4",

@ -60,7 +60,7 @@ export function clusterAnalysisPlot(data) {
//关联规则挖掘
export function associationRuleMining(data) {
return request({
url: '/api/model/apriori',
url: '/api/python/associationRules',
method: 'post',
data:data,
})
@ -120,4 +120,12 @@ export function knowledgeProfileScore(data) {
method: "post",
data: data,
});
}
//聚类分析
export function clusterAnalysis2(data) {
return request({
url: "/api/python/clusterAnalysis",
method: "post",
data: data,
});
}

@ -146,3 +146,11 @@ export function timeCountSubmit(data) {
data: data,
});
}
//聚类分析
export function clusterAnalysis(data) {
return request({
url: "/api/python/clusterAnalysis",
method: "post",
data: data,
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

@ -0,0 +1,211 @@
<!--
* @Author: qinzhenpen qzp1807@126.com
* @Date: 2024-11-12 16:24:01
* @LastEditors: qinzhenpen qzp1807@126.com
* @LastEditTime: 2024-12-10 14:07:23
* @FilePath: \corporate-finance\src\components\codemirror\index.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<div class="codemirror">
<pre>
<code id="answer" ref="answer" class="python">
</code>
</pre>
<div class="output" v-if="Result">
<span v-html="Result"></span>
</div>
<!-- <el-button @click="Execution" type="primary">运行</el-button> -->
<!-- <el-button @click="loadTaskInfo" type="primary">清除</el-button> -->
</div>
</template>
<script setup>
import { ref } from "vue"
// import * as caseTraining from "@/api/caseTraining"
const props = defineProps({
code: {
type: String,
default: ""
}
})
const code = ref("")
const Result = ref("")
const answer = ref(null)
const text = ref("")
onMounted(() => {
setTimeout(() => {
loadTaskInfo()
}, 500)
})
function formatPythonCode(code) {
// 使```python
const trimmedCode = code
.replace(/```python\s*/, "")
.replace(/```Python\s*/, "")
.replace(/```/, "")
// 使
const lines = trimmedCode.split("\n")
//
const highlightWords = [
{ word: "print", className: "highlight" },
{ word: "import", className: "highlight" },
{ word: "as", className: "highlight" },
{ word: "from", className: "highlight" },
{ word: "num", className: "highlight-green" },
{ word: "if", className: "highlight-blue" },
{ word: "else", className: "highlight-blue" },
{ word: "str", className: "highlight-blue" }
]
//
const style = document.createElement("style")
style.textContent = `
.highlight {
color: yellow;
}
.highlight-green {
color: lightgreen;
}
.highlight-blue {
color: lightblue;
}
.comment-highlight {
color: #d4d0ab;
font-weight: bold;
}
`
document.head.append(style)
// <li>
const formattedLines = lines
.map((line) => {
let codePart = line
let commentPart = ""
//
const commentIndex = line.indexOf("#")
if (commentIndex !== -1) {
codePart = line.slice(0, commentIndex)
commentPart = line.slice(commentIndex)
}
//
highlightWords.forEach(({ word, className }) => {
const regex = new RegExp(`\\b${word}\\b`, "g")
codePart = codePart.replace(regex, `<span class="${className}">${word}</span>`)
})
if (codePart.includes("___")) {
// ___使<input>
const parts = codePart.split("___")
const inputs = parts
.map((part, index) => {
if (index < parts.length - 1) {
return `${part}<input type="text" style="text-align: center;line-height: 20px;margin: 0 10px;border: none;border-bottom: 1px solid #1e9fff;border-radius: 5px;padding: 0 10px;width: 80px;font-family: inherit;font-size: inherit;font-style: inherit;font-weight: inherit;outline: 0;background:transparent;color:#FF6100">`
}
return part
})
.join("")
return `<li style="white-space: pre-wrap;">${inputs}<span class="comment-highlight">${commentPart}</span></li>`
} else if (commentPart) {
//
return `<li style="white-space: pre-wrap;"><span style="white-space: pre-wrap;">${codePart}</span><span class="comment-highlight">${commentPart}</span></li>`
} else {
if (codePart !== "") {
return `<li style="white-space: pre-wrap;"><span style="white-space: pre-wrap;">${codePart}</span></li>`
}
}
})
.filter(Boolean) // undefined
//
return `<ol style="min-height:100%px;padding: 5px 0;list-style: none; padding-left: 0;width:100%">${formattedLines.join("\n")}</ol>`
}
//
// function Execution() {
// answer.value.querySelectorAll("input").forEach((inputElement, index) => {
// const spanElement = document.createElement("span")
// spanElement.style.color = "#FF6100"
// spanElement.textContent = inputElement.value
// inputElement.replaceWith(spanElement)
// })
// text.value = answer.value.textContent
// caseTraining
// .pythonRun({ code: text.value })
// .then((res) => {
// if (res.data !== null) {
// res.data.forEach((item) => {
// Result.value += `<img src="data:image/png;base64,${item}"/>`
// })
// } else {
// Result.value = res.msg
// }
// })
// .catch((err) => {})
// }
function filterStringWithCommaPrefix(str) {
// split
const parts = str.split(",")
// 使 slice(-1)
return parts.slice(-1)[0]
}
function loadTaskInfo() {
nextTick(() => {
Result.value = ""
answer.value.innerHTML = formatPythonCode(props.code)
})
}
watch(
() => props.code,
(newVal) => {
loadTaskInfo()
}
)
</script>
<style lang='scss' scoped>
.codemirror {
margin-bottom: 20px;
pre{
margin-bottom: -32px;
}
:deep(#answer) {
display: block;
margin: -41px 0px 0px 0px;
font-size: 14px;
ol {
line-height: 10px;
li,
span {
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 14px;
color: #666666;
line-height: 14px;
}
}
}
#answer span {
white-space: pre-wrap;
}
.output {
width: calc(100% - 300px);
padding: 10px;
min-height: 100px;
margin-left: 5px;
box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
margin-bottom: 10px;
//
}
.el-button {
background: url("../../assets/images/xz按钮.png") no-repeat !important;
background-size: 100% 100% !important;
border: none;
min-width: 135px;
min-height: 25px;
}
.el-button:nth-child(3) {
background: url("../../assets/images/xz按钮2.png") no-repeat !important;
background-size: 100% 100% !important;
}
}
</style>

@ -2,7 +2,8 @@
<div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }">
<div class="title" style="height: 58px; background-color: #072048 !important; z-index: 900 !important; position: relative">
<div :class="[role!==3 ? 'navTitle':'TnavTitle']">
<span class="nacber-name"> - </span>
<span class="nacber-name" v-if="role!==3"> </span>
<span class="nacber-name" v-else> - </span>
</div>
</div>
<div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside" />

@ -2,7 +2,7 @@
* @Author: qinzhenpen qzp1807@126.com
* @Date: 2024-08-16 17:56:32
* @LastEditors: qinzhenpen qzp1807@126.com
* @LastEditTime: 2024-08-28 14:59:50
* @LastEditTime: 2025-04-02 17:55:19
* @FilePath: \digital-marketing\src\store\modules\algorithm.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/

@ -50,6 +50,9 @@
<div class="left-top" style="margin-top: 50px">
<span>模型参数设置</span>
</div>
<div class="metrics-table">
<el-button @click="codeSetting"></el-button>
</div>
<div class="metrics-table" style="margin-top: 10px">
<span style="font-weight: 400; font-size: 12px; color: #ffffff">聚类方法</span>
<div class="metrics" style="margin-top: 10px">
@ -322,9 +325,17 @@
</div>
</template>
</pop-model>
<pop-model :showModel="runResultShow2" title="设置代码" @closePop="closeCode">
<template v-slot:content>
<div>
<codemirror :code="code"></codemirror>
</div>
</template>
</pop-model>
</template>
<script setup>
import codemirror from "@/components/codemirror/index.vue"
import useAlgorithmStore from "@/store/modules/algorithm.js";
const algorithmStore = useAlgorithmStore();
import * as portraitModel from "@/api/portraitModel";
@ -344,6 +355,7 @@ const formData = reactive({
value4: "",
value5: "",
});
const code=ref('')
const scrollbar=ref(null)
const loading1 =ref(false)
const task = () => {
@ -377,78 +389,22 @@ const task = () => {
proxy.$modal.msgSuccess("提交成功");
});
};
const runResultShow2 = ref(false)
const closeCode=()=>{
runResultShow2.value = false
const inputs = document.querySelectorAll('.codemirror pre code input')
const values = []
inputs.forEach(input => {
values.push(input.value)
})
input5.value=values[0]*100
input6.value=values[1]*100
input4.value='Apriori关联算法'
}
const dialogVisible = ref(false);
const runResultShow = ref(false);
const tableLabel = reactive([{ prop: "date", label: "" }]);
const tableLabel2 = reactive([{ prop: "date", label: "" }]);
const text = ref(`首先导入必要的库:
\`\`\`python
from itertools import chain, combinations
\`\`\`
接着定义几个辅助函数
\`\`\`python
# 生成候选项集的所有非空子集
def powerset(s):
return chain.from_iterable(combinations(s, r) for r in range(1, len(s)))
# 计算支持度
def calculate_support(itemset, transactions):
return sum(1 for transaction in transactions if itemset.issubset(transaction)) / len(transactions)
\`\`\`
现在我们来实现Apriori算法
\`\`\`python
def apriori(transactions, min_support, min_confidence):
# 初始化频繁项集和关联规则列表
frequent_itemsets = []
association_rules = []
# 第一步找出单项频繁项集
singletons = {frozenset([item]) for transaction in transactions for item in transaction}
singletons = {itemset for itemset in singletons if calculate_support(itemset, transactions) >= min_support}
frequent_itemsets.extend(singletons)
# 迭代找出所有其他频繁项集
prev_frequent_itemsets = singletons
while prev_frequent_itemsets:
# 生成新的候选项集
candidates = {itemset1 | itemset2 for itemset1 in prev_frequent_itemsets for itemset2 in prev_frequent_itemsets if len(itemset1 | itemset2) == len(itemset1) + 1}
# 计算支持度并筛选
new_frequent_itemsets = {itemset for itemset in candidates if calculate_support(itemset, transactions) >= min_support}
frequent_itemsets.extend(new_frequent_itemsets)
# 生成关联规则
for itemset in new_frequent_itemsets:
for subset in powerset(itemset):
subset = frozenset(subset)
diff = itemset - subset
if diff:
confidence = calculate_support(itemset, transactions) / calculate_support(subset, transactions)
if confidence >= min_confidence:
association_rules.append((subset, diff, confidence))
prev_frequent_itemsets = new_frequent_itemsets
return frequent_itemsets, association_rules
\`\`\`
### 示例和输出
假设我们有以下简单的购物数据集
\`\`\`python
transactions = [
{'牛奶', '面包', '黄油'},
{'啤酒', '面包'},
{'牛奶', '啤酒', '黄油'},
{'牛奶', '鸡蛋'},
{'面包', '鸡蛋', '黄油'}
]
\`\`\`
调用Apriori算法
\`\`\`python
min_support = 0.4
min_confidence = 0.5
frequent_itemsets, association_rules = apriori(transactions, min_support, min_confidence)
print("频繁项集:", frequent_itemsets)
print("关联规则:", association_rules)
\`\`\`
输出可能如下
\`\`\`python
频繁项集 [{'牛奶'}, {'面包'}, {'黄油'}, {'啤酒'}, {'鸡蛋'}, {'牛奶', '面包'}, {'牛奶', '黄油'}, {'面包', '黄油'}, {'啤酒', '黄油'}, {'面包', '啤酒'}]
关联规则 [(('牛奶',), ('面包',), 0.6666666666666666), (('面包',), ('牛奶',), 0.6666666666666666), ...]
\`\`\`
通过这个实战应用我们不仅学习了如何在Python中实现Apriori算法还了解了它在购物篮分析中的具体应用这为进一步的研究和实际应用提供了有用的指导`);
const getList = () => {
API.selectionMetrics({ userId: JSON.parse(getUserInfo()).userId }).then((res) => {
res.data.forEach((element) => {
@ -548,6 +504,13 @@ const taskSubmit = () => {
dialogVisible.value = true;
};
const tableData = ref([]);
const codeSetting=()=>{
if(input.value==="购物车数据表"){
runResultShow2.value=true
}else{
proxy.$modal.msgWarning("请选择购物车数据表!")
}
}
const headerCellStyle = () => {
return {
backgroundColor: "#1882DE !important", //
@ -572,7 +535,66 @@ const optionData2 = () => {
tableData2.value = [];
tableData2.value = res.data;
proxy.$modal.msgSuccess("预处理成功!");
});
}).then(()=>{
code.value=`
# -*- coding: utf-8 -*-
import json
from itertools import chain, combinations
def powerset(s):
return chain.from_iterable(combinations(s, r) for r in range(1, len(s) + 1))
def calculate_support(itemset, transactions):
return sum(1 for transaction in transactions if itemset.issubset(transaction)) / len(transactions)
def apriori(transactions, min_support, min_confidence):
frequent_itemsets = []
association_rules = []
singletons = {frozenset([item]) for transaction in transactions for item in transaction}
singletons = {itemset for itemset in singletons if calculate_support(itemset, transactions) >= min_support}
frequent_itemsets.extend(singletons)
prev_frequent_itemsets = singletons
while prev_frequent_itemsets:
candidates = {itemset1 | itemset2 for itemset1 in prev_frequent_itemsets for itemset2 in prev_frequent_itemsets if len(itemset1 | itemset2) == len(itemset1) + 1}
new_frequent_itemsets = {itemset for itemset in candidates if calculate_support(itemset, transactions) >= min_support}
frequent_itemsets.extend(new_frequent_itemsets)
for itemset in new_frequent_itemsets:
for subset in powerset(itemset):
subset = frozenset(subset)
diff = itemset - subset
if diff:
confidence = calculate_support(itemset, transactions) / calculate_support(subset, transactions)
if confidence >= min_confidence:
rule = {
"correlation": list(subset),
"associated": list(diff),
"confidenceLevel": round(confidence, 2),
"rule": f"[{', '.join(subset)}]==>[{', '.join(diff)}]==>{round(confidence, 2)}"
}
association_rules.append(rule)
prev_frequent_itemsets = new_frequent_itemsets
result = {
# "frequentItemsets": [list(itemset) for itemset in frequent_itemsets],
"associationRules": association_rules
}
print(json.dumps(result, ensure_ascii=False))
transactions = [
${resTable2.value.map(item => "{" + item.consumer_goods.split(',').map(good => "'" + good + "'").join(',') + "}").join(',')}
]
min_support = ___
min_confidence = ___
apriori(transactions, min_support, min_confidence)
`
})
}
};
@ -585,25 +607,31 @@ const computation = () => {
return;
}
if (input5.value && input6.value && input4.value) {
const sendData = {
confidence: parseFloat(input5.value) / 100,
support: parseFloat(input6.value) / 100,
userId: JSON.parse(getUserInfo()).userId,
deduplicatedDataList: resTable2.value,
};
API.associationRuleMining(sendData)
const sendData =ref({
minConfidence: parseFloat(input6.value) / 100,
minSupport: parseFloat(input5.value) / 100,
type: input.value,
data: Object.keys(resTable2.value[0]).reduce((acc, key) => {
acc[key] = resTable2.value.map(item => item[key]);
return acc;
}, {}),
})
if(input.value==="购物车数据表"){
sendData.value.data = {consumer_goods:resTable2.value.map(item => item.consumer_goods.split(','))}
}
API.associationRuleMining(sendData.value)
.then((res) => {
loading1.value = true;
uplodFlag.value = true;
tableData3.value = [];
tableLabel2.length = 0;
for (const key in res.data[0]) {
for (const key in res.data.associationRules[0]) {
tableLabel2.push({
label: key,
prop: key,
});
}
tableData3.value = res.data;
tableData3.value = res.data.associationRules;
//
setTimeout(() => {
loading1.value = false;

@ -49,6 +49,9 @@
<div class="left-top" style="margin-top: 50px">
<span>模型参数设置</span>
</div>
<div class="metrics-table">
<el-button @click="codeSetting"></el-button>
</div>
<div class="metrics-table" style="margin-top: 10px">
<span style="font-weight: 400; font-size: 12px; color: #ffffff">聚类方法</span>
<div class="metrics" style="margin-top: 10px">
@ -274,9 +277,18 @@
</div>
</template>
</pop-model>
<pop-model :showModel="runResultShow2" title="设置代码" @closePop="closeCode">
<template v-slot:content>
<div>
<codemirror :code="code"></codemirror>
</div>
</template>
</pop-model>
</template>
<script setup>
import codemirror from "@/components/codemirror/index.vue"
import * as portraitModel from "@/api/portraitModel";
import useAlgorithmStore from "@/store/modules/algorithm.js";
const algorithmStore = useAlgorithmStore();
@ -288,6 +300,10 @@ import JSZip from "jszip";
import * as API from "@/api/AI.js";
import { getUserInfo } from "@/utils/auth";
import { onMounted, reactive } from "vue";
const age=ref('')
const income=ref('')
const runResultShow2=ref(false)
const code=ref()
const loading1 = ref(false);
const loading2 = ref(false);
const loading3 = ref(false);
@ -374,7 +390,7 @@ const addData = (myChart, newData, color) => {
//
newData.forEach((dataPoint) => {
currentData.push({
value: [dataPoint.x, dataPoint.y],
value: [dataPoint.age, dataPoint.income],
itemStyle: { color: color },
});
});
@ -388,7 +404,27 @@ const addData = (myChart, newData, color) => {
],
});
};
//
const addData2 = (myChart, newData, color) => {
//
let currentData = myChart.getOption().series[0].data || [];
//
// newData.forEach((dataPoint) => {
currentData.push({
value: [newData[0], newData[1]],
itemStyle: { color: color },
});
// });
//
myChart.setOption({
series: [
{
data: currentData,
},
],
});
};
onMounted(() => {
getList();
optionData()
@ -517,6 +553,9 @@ const headerCellStyle = () => {
color: "#ffffff !important",
};
};
const codeSetting=()=>{
runResultShow2.value=true
}
const optionData2 = () => {
if (tableData2.value.length === 0) {
input2.value = "";
@ -540,12 +579,119 @@ const optionData2 = () => {
setTimeout(() => {
loading2.value = false;
}, 500);
}).then(()=>{
const fields = Object.keys(resTable2.value[0])
const data = {}
fields.forEach(field => {
const values = resTable2.value.map(item => item[field]).join(',')
data[field] = values
})
code.value=`
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
import json
# 模拟输入数据可以根据实际输入动态更改
data = {
${Object.entries(data).map(([key, value]) => `'${key}': [${value}]`).join(',\n ')}
}
# 将字典转换为 DataFrame
df = pd.DataFrame(data)
# 提取特征数组
X = df.values
# 选择聚类的数量和设置最大迭代次数
num_clusters = ___
max_iter = ___ # 设置最大迭代次数
n_init = 10 # 初始化次数
kmeans = KMeans(n_clusters=num_clusters, n_init=n_init, max_iter=max_iter, random_state=0)
# 拟合模型
kmeans.fit(X)
# 获取聚类结果
labels = kmeans.labels_
centroids = kmeans.cluster_centers_
# 记录每次的迭代结果
iterations_per_init = []
for _ in range(n_init):
kmeans = KMeans(n_clusters=num_clusters, n_init=1, max_iter=max_iter, random_state=None) # 随机化每次初始化
kmeans.fit(X)
iterations_per_init.append(kmeans.n_iter_)
# 计算总体迭代次数
total_iterations = sum(iterations_per_init)
# 构建输出每个簇的成员并生成 JSON 格式
clusters_output = {
"data": {} # 初始化一个 Members 字典
}
for i in range(num_clusters):
cluster_members = X[labels == i] # 获取所有成员
member_dicts = [{col: int(member[j]) if isinstance(member[j], np.int64) else member[j] for j, col in enumerate(df.columns)} for member in cluster_members]
# 添加到数据字典中
clusters_output["data"][f"Cluster_{i + 1}"] = {
"Members": member_dicts, # 添加簇的所有成员
"Centroid": [float(c) for c in centroids[i]] # 转换质心为 float以避免可能的整数问题
}
# 添加最大迭代次数和总体迭代次数
clusters_output["maxIterations"] = int(max_iter)
clusters_output["totalIterations"] = int(total_iterations)
# 输出最终结果
output_json = json.dumps(clusters_output, ensure_ascii=False, separators=(',', ': '))
# 按照需求进行格式化输出
formatted_output = output_json.replace('},{', '},\n{') # 簇之间换行
print(formatted_output)
# 可视化聚类结果
plt.figure(figsize=(10, 6))
for i in range(num_clusters):
plt.scatter(X[labels == i, 0], X[labels == i, 1], label=f'Cluster {i + 1}')
# 显示聚类中心并标记坐标
for i, centroid in enumerate(centroids):
plt.scatter(centroid[0], centroid[1], s=300, c='red', label='Centroid ' + str(i + 1), marker='X')
plt.text(centroid[0], centroid[1], f'C{i + 1}: ({centroid[0]:.1f}, {centroid[1]:.1f})', fontsize=12, ha='right')
# 在每个点旁边显示坐标
for idx, point in enumerate(X):
plt.text(point[0], point[1], f'({point[0]}, {point[1]})', fontsize=9, ha='right')
plt.title('K-Means Clustering')
plt.xlabel('Age')
plt.ylabel('Income')
plt.legend()
plt.grid()
plt.show()`
})
.catch(() => {
loading2.value = false;
});
}
};
const closeCode=()=>{
runResultShow2.value = false
const inputs = document.querySelectorAll('.codemirror pre code input')
const values = []
inputs.forEach(input => {
values.push(input.value)
})
input5.value=values[0]
input6.value=values[1]
input4.value='K-means'
}
const showChart = ref(false);
//
const iterations=ref(0)
@ -558,10 +704,10 @@ const clusterAnalysisCalculation = () => {
if (input5.value && input6.value && input4.value) {
loading3.value = true;
const sendData = {
k: input5.value,
t: input6.value,
k: input5.value,
userId: JSON.parse(getUserInfo()).userId,
deduplicatedDataList: resTable2.value,
deduplicatedDataList: resTable2.value
};
API.clusterAnalysisPlot(sendData)
.then((res) => {
@ -593,11 +739,19 @@ const clusterAnalysisCalculation = () => {
children.value.push(newItem2);
});
tableData3.value[index].children = children.value;
console.log(tableData3.value);
});
})
.then(() => {
API.clusterAnalysis(sendData).then((res) => {
const sendData2 = {
maxIterations: input6.value,
clusteringFrequency: input5.value,
// userId: JSON.parse(getUserInfo()).userId,
data:Object.keys(resTable2.value[0]).reduce((acc, key) => {
acc[key] = resTable2.value.map(item => item[key]);
return acc;
}, {}),
};
API.clusterAnalysis2(sendData2).then((res) => {
myChart.setOption({
series: [
{
@ -612,14 +766,19 @@ const clusterAnalysisCalculation = () => {
},
],
});
Object.keys(res.data.dataSet).forEach((key) => {
const bgColor = getRandomColorHex();
addData(myChart, res.data.dataSet[key], bgColor);
addData(myChart2, res.data.dataSet[key], bgColor);
});
Object.keys(res.data.centroid).forEach((key) => {
addData(myChart2, res.data.centroid[key], "red");
});
const bgColor = getRandomColorHex();
addData(myChart, res.data.data.Cluster_1.members, bgColor)
addData(myChart2, res.data.data.Cluster_2.members, bgColor)
addData2(myChart, res.data.data.Cluster_1.centroid, "red")
addData2(myChart2, res.data.data.Cluster_2.centroid, "red")
// Object.keys(res.data.dataSet).forEach((key) => {
// const bgColor = getRandomColorHex();
// addData(myChart, res.data.dataSet[key], bgColor);
// addData(myChart2, res.data.dataSet[key], bgColor);
// });
// Object.keys(res.data.centroid).forEach((key) => {
// addData(myChart2, res.data.centroid[key], "red");
// });
setTimeout(() => {
loading3.value = false;
}, 500);

@ -1,4 +1,5 @@
<template>
<div class="rgzn_top app-container2" v-loading="loading" element-loading-text="Loading..." :element-loading-spinner="svg" element-loading-svg-view-box="-10, -10, 50, 50" element-loading-background="rgba(122, 122, 122, 0.8)">
<div class="rgzn_top app-container2" v-loading="loading" element-loading-text="Loading..." :element-loading-spinner="svg" element-loading-svg-view-box="-10, -10, 50, 50" element-loading-background="rgba(122, 122, 122, 0.8)">
<div class="top_item">
<el-button :class="{ active: isActive === 1 }" @click="activeIndex(1)"></el-button>

@ -1271,7 +1271,7 @@ defineExpose({
});
const openKnowledge = () => {
dialogVisible.value = true;
startCount();
// startCount();
};
const handlClose = () => {
console.log('123');
@ -1293,15 +1293,15 @@ const startCount = () => {
}, 1000);
};
const submitTimeCount = () => {
portraitModel
.timeCountSubmit({
stuScoreDetailsDTO: {
userId: JSON.parse(getUserInfo()).userId,
viewingTime: timeCount.value,
},
})
.then((res) => {})
.catch((error) => {});
// portraitModel
// .timeCountSubmit({
// stuScoreDetailsDTO: {
// userId: JSON.parse(getUserInfo()).userId,
// viewingTime: timeCount.value,
// },
// })
// .then((res) => {})
// .catch((error) => {});
};
</script>

@ -1244,7 +1244,7 @@ defineExpose({
});
const openKnowledge = () => {
dialogVisible.value = true;
startCount();
// startCount();
};
const handlClose = () => {
console.log('123');
@ -1266,15 +1266,15 @@ const startCount = () => {
}, 1000);
};
const submitTimeCount = () => {
portraitModel
.timeCountSubmit({
stuScoreDetailsDTO: {
userId: JSON.parse(getUserInfo()).userId,
viewingTime: timeCount.value,
},
})
.then((res) => {})
.catch((error) => {});
// portraitModel
// .timeCountSubmit({
// stuScoreDetailsDTO: {
// userId: JSON.parse(getUserInfo()).userId,
// viewingTime: timeCount.value,
// },
// })
// .then((res) => {})
// .catch((error) => {});
};
</script>

@ -1145,7 +1145,7 @@ defineExpose({
});
const openKnowledge = () => {
dialogVisible.value = true;
startCount();
// startCount();
};
const handlClose = () => {
console.log('123');
@ -1164,15 +1164,15 @@ const startCount = () => {
}, 1000);
};
const submitTimeCount = () => {
portraitModel
.timeCountSubmit({
stuScoreDetailsDTO: {
userId: JSON.parse(getUserInfo()).userId,
viewingTime: timeCount.value,
},
})
.then((res) => {})
.catch((error) => {});
// portraitModel
// .timeCountSubmit({
// stuScoreDetailsDTO: {
// userId: JSON.parse(getUserInfo()).userId,
// viewingTime: timeCount.value,
// },
// })
// .then((res) => {})
// .catch((error) => {});
};
</script>

@ -1935,7 +1935,7 @@ defineExpose({
});
const openKnowledge = () => {
dialogVisible.value = true;
startCount();
// startCount();
};
const handlClose = () => {
console.log('123');
@ -1954,15 +1954,15 @@ const startCount = () => {
}, 1000);
};
const submitTimeCount = () => {
portraitModel
.timeCountSubmit({
stuScoreDetailsDTO: {
userId: JSON.parse(getUserInfo()).userId,
viewingTime: timeCount.value,
},
})
.then((res) => {})
.catch((error) => {});
// portraitModel
// .timeCountSubmit({
// stuScoreDetailsDTO: {
// userId: JSON.parse(getUserInfo()).userId,
// viewingTime: timeCount.value,
// },
// })
// .then((res) => {})
// .catch((error) => {});
};
</script>

@ -1217,7 +1217,7 @@ defineExpose({
});
const openKnowledge = () => {
dialogVisible.value = true;
startCount();
// startCount();
};
const handlClose = () => {
console.log('123');
@ -1236,15 +1236,15 @@ const startCount = () => {
}, 1000);
};
const submitTimeCount = () => {
portraitModel
.timeCountSubmit({
stuScoreDetailsDTO: {
userId: JSON.parse(getUserInfo()).userId,
viewingTime: timeCount.value,
},
})
.then((res) => {})
.catch((error) => {});
// portraitModel
// .timeCountSubmit({
// stuScoreDetailsDTO: {
// userId: JSON.parse(getUserInfo()).userId,
// viewingTime: timeCount.value,
// },
// })
// .then((res) => {})
// .catch((error) => {});
};
</script>

@ -1232,7 +1232,7 @@ defineExpose({
});
const openKnowledge = () => {
dialogVisible.value = true;
startCount();
// startCount();
};
const handlClose = () => {
console.log('123');
@ -1251,15 +1251,15 @@ const startCount = () => {
}, 1000);
};
const submitTimeCount = () => {
portraitModel
.timeCountSubmit({
stuScoreDetailsDTO: {
userId: JSON.parse(getUserInfo()).userId,
viewingTime: timeCount.value,
},
})
.then((res) => {})
.catch((error) => {});
// portraitModel
// .timeCountSubmit({
// stuScoreDetailsDTO: {
// userId: JSON.parse(getUserInfo()).userId,
// viewingTime: timeCount.value,
// },
// })
// .then((res) => {})
// .catch((error) => {});
};
</script>

@ -2236,7 +2236,7 @@ defineExpose({
});
const openKnowledge = () => {
dialogVisible.value = true;
startCount();
// startCount();
};
const handlClose = () => {
console.log('123');
@ -2255,15 +2255,15 @@ const startCount = () => {
}, 1000);
};
const submitTimeCount = () => {
portraitModel
.timeCountSubmit({
stuScoreDetailsDTO: {
userId: JSON.parse(getUserInfo()).userId,
viewingTime: timeCount.value,
},
})
.then((res) => {})
.catch((error) => {});
// portraitModel
// .timeCountSubmit({
// stuScoreDetailsDTO: {
// userId: JSON.parse(getUserInfo()).userId,
// viewingTime: timeCount.value,
// },
// })
// .then((res) => {})
// .catch((error) => {});
};
</script>

@ -1762,7 +1762,7 @@ defineExpose({
});
const openKnowledge = () => {
dialogVisible.value = true;
startCount();
// startCount();
};
const handlClose = () => {
console.log('123');
@ -1781,15 +1781,15 @@ const startCount = () => {
}, 1000);
};
const submitTimeCount = () => {
portraitModel
.timeCountSubmit({
stuScoreDetailsDTO: {
userId: JSON.parse(getUserInfo()).userId,
viewingTime: timeCount.value,
},
})
.then((res) => {})
.catch((error) => {});
// portraitModel
// .timeCountSubmit({
// stuScoreDetailsDTO: {
// userId: JSON.parse(getUserInfo()).userId,
// viewingTime: timeCount.value,
// },
// })
// .then((res) => {})
// .catch((error) => {});
};
</script>

@ -37,7 +37,7 @@
<img src="@/assets/images/步骤.png" alt="" />
<span>第一步确定近一段时间的时间间隔</span>
</div>
<span style="line-height: 25px; font-size: 14px">计划分析最近30天的用户假设现在是2025.05.30需要对数据进行筛选筛选出统计样本</span>
<span style="line-height: 25px; font-size: 14px">计划分析最近30天的用户假设现在是2024.05.30需要对数据进行筛选筛选出统计样本</span>
<div style="margin-top: 10px; display: flex">
<el-table
:data="fileTable1"

@ -1937,7 +1937,7 @@ defineExpose({
});
const openKnowledge = () => {
dialogVisible.value = true;
startCount();
// startCount();
};
const handlClose = () => {
console.log('123');
@ -1956,15 +1956,15 @@ const startCount = () => {
}, 1000);
};
const submitTimeCount = () => {
portraitModel
.timeCountSubmit({
stuScoreDetailsDTO: {
userId: JSON.parse(getUserInfo()).userId,
viewingTime: timeCount.value,
},
})
.then((res) => {})
.catch((error) => {});
// portraitModel
// .timeCountSubmit({
// stuScoreDetailsDTO: {
// userId: JSON.parse(getUserInfo()).userId,
// viewingTime: timeCount.value,
// },
// })
// .then((res) => {})
// .catch((error) => {});
};
</script>

Loading…
Cancel
Save