|
@@ -1,253 +1,163 @@
|
|
|
<template>
|
|
|
- <div>
|
|
|
- <!-- <el-dialog title="词云" :visible.sync="dialogVisibleWordCloud" :append-to-body="true" width="800px"
|
|
|
- :before-close="handleClose" class="dialog_diy dialog_diy3"> -->
|
|
|
- <div class="wordCloud__tagBall" :style="{ width: `500px`, height: `500px` }" @mouseenter="stop"
|
|
|
- @mouseleave="start" v-if="data.length">
|
|
|
- <span class="wordCloud__tag" v-for="(item, index) of data" :key="index"
|
|
|
- :style="{ color: color[index % color.length], ...contentEle[index].style }"
|
|
|
- :title="item.name ">{{ item.name }}</span>
|
|
|
- <!-- + item.value -->
|
|
|
- </div>
|
|
|
- <div class="noneBox" v-else>暂无内容</div>
|
|
|
- <!-- </el-dialog> -->
|
|
|
- </div>
|
|
|
+ <div v-loading="loading">
|
|
|
+ <div class="chart" id="charts_canvas" ref="chartRef"></div>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
<script>
|
|
|
+import { v4 as uuidv4 } from "uuid";
|
|
|
+import * as echarts from 'echarts';
|
|
|
+import "echarts-wordcloud";
|
|
|
export default {
|
|
|
- name: 'cloudWork',
|
|
|
- props: {
|
|
|
- dialogVisibleWordCloud: {
|
|
|
- type: Boolean,
|
|
|
- },
|
|
|
- // 测试数据
|
|
|
- data: {
|
|
|
- type: Array,
|
|
|
- default: () => []
|
|
|
- }
|
|
|
- },
|
|
|
- data: () => ({
|
|
|
- color: ['#2D4DB6', '#04B67C', '#D1AF07', '#E27914', '#CB4A4D', '#B02690'],
|
|
|
- contentEle: [],
|
|
|
- direction: '-1',
|
|
|
- speed: 400,
|
|
|
- animateID: null,
|
|
|
- width:500,
|
|
|
- height:500,
|
|
|
- }),
|
|
|
- watch: {
|
|
|
- dialogVisibleWordCloud(newValue, oldValue) {
|
|
|
- if(newValue){
|
|
|
- this.contentEle = this.data.map(() => ({
|
|
|
- x: 0,
|
|
|
- y: 0,
|
|
|
- z: 0,
|
|
|
- style: {}
|
|
|
- }));
|
|
|
- this.innit();
|
|
|
- }else{
|
|
|
- window.cancelAnimationFrame(this.animateID);
|
|
|
- }
|
|
|
- }
|
|
|
+ name: "cloudWork",
|
|
|
+ props: {
|
|
|
+ dialogVisibleWordCloud: {
|
|
|
+ type: Boolean
|
|
|
},
|
|
|
- created() {
|
|
|
- // this.contentEle = this.data.map(() => ({
|
|
|
- // x: 0,
|
|
|
- // y: 0,
|
|
|
- // z: 0,
|
|
|
- // style: {}
|
|
|
- // }));
|
|
|
- },
|
|
|
- mounted() {
|
|
|
- this.innit();
|
|
|
- },
|
|
|
- methods: {
|
|
|
- handleClose(done) {
|
|
|
- this.close();
|
|
|
- // done()
|
|
|
- },
|
|
|
- close() {
|
|
|
- this.$emit("update:dialogVisibleWordCloud", false)
|
|
|
- },
|
|
|
- innit() {
|
|
|
- const RADIUSX = (this.width - 50) / 2;
|
|
|
- const RADIUSY = (this.height - 50) / 2;
|
|
|
- this.contentEle = [];
|
|
|
- for (let i = 0; i < this.data.length; i += 1) {
|
|
|
- const k = -1 + (2 * (i + 1) - 1) / this.data.length;
|
|
|
- const a = Math.acos(k);
|
|
|
- const b = a * Math.sqrt(this.data.length * Math.PI);
|
|
|
- const x = RADIUSX * Math.sin(a) * Math.cos(b);
|
|
|
- const y = RADIUSY * Math.sin(a) * Math.sin(b);
|
|
|
- const z = RADIUSX * Math.cos(a);
|
|
|
- const singleEle = {
|
|
|
- x,
|
|
|
- y,
|
|
|
- z,
|
|
|
- style: {}
|
|
|
- };
|
|
|
- this.contentEle.push(singleEle);
|
|
|
- }
|
|
|
- this.animate();
|
|
|
- },
|
|
|
- animate() {
|
|
|
- this.rotateX();
|
|
|
- this.rotateY();
|
|
|
- this.move();
|
|
|
- this.animateID = window.requestAnimationFrame(this.animate);
|
|
|
- },
|
|
|
- rotateX() {
|
|
|
- const angleX = ['-1', '1'].includes(this.direction)
|
|
|
- ? Math.PI / Infinity
|
|
|
- : Math.PI / ((Number(this.direction) / 2) * Number(this.speed));
|
|
|
- const cos = Math.cos(angleX);
|
|
|
- const sin = Math.sin(angleX);
|
|
|
-
|
|
|
- this.contentEle = this.contentEle.map((t) => {
|
|
|
- const y1 = t.y * cos - t.z * sin;
|
|
|
- const z1 = t.z * cos + t.y * sin;
|
|
|
- return {
|
|
|
- ...t,
|
|
|
- y: y1,
|
|
|
- z: z1
|
|
|
- };
|
|
|
- });
|
|
|
- },
|
|
|
- rotateY() {
|
|
|
- const angleY = ['-2', '2'].includes(this.direction)
|
|
|
- ? Math.PI / Infinity
|
|
|
- : Math.PI / (Number(this.direction) * Number(this.speed));
|
|
|
- const cos = Math.cos(angleY);
|
|
|
- const sin = Math.sin(angleY);
|
|
|
- this.contentEle = this.contentEle.map((t) => {
|
|
|
- const x1 = t.x * cos - t.z * sin;
|
|
|
- const z1 = t.z * cos + t.x * sin;
|
|
|
- return {
|
|
|
- ...t,
|
|
|
- x: x1,
|
|
|
- z: z1
|
|
|
- };
|
|
|
- });
|
|
|
- },
|
|
|
- move() {
|
|
|
- const CX = this.width / 2;
|
|
|
- const CY = this.height / 2;
|
|
|
- this.contentEle = this.contentEle.map((singleEle) => {
|
|
|
- const { x, y, z } = singleEle;
|
|
|
- const fallLength = 500;
|
|
|
- const RADIUS = (this.width - 50) / 2;
|
|
|
- const scale = fallLength / (fallLength - z);
|
|
|
- const alpha = (z + RADIUS) / (2 * RADIUS);
|
|
|
- const left = `${x + CX - 15}px`;
|
|
|
- const top = `${y + CY - 15}px`;
|
|
|
- const transform = `translate(${left}, ${top}) scale(${scale})`;
|
|
|
- const style = {
|
|
|
- ...singleEle.style,
|
|
|
- opacity: alpha + 0.5,
|
|
|
- zIndex: parseInt(scale * 100, 10),
|
|
|
- transform
|
|
|
- };
|
|
|
- return {
|
|
|
- x,
|
|
|
- y,
|
|
|
- z,
|
|
|
- style
|
|
|
- };
|
|
|
- });
|
|
|
- },
|
|
|
- // 鼠标移入暂停
|
|
|
- stop() {
|
|
|
- window.cancelAnimationFrame(this.animateID);
|
|
|
- },
|
|
|
- // 鼠标离开恢复
|
|
|
- start() {
|
|
|
- this.animate();
|
|
|
- }
|
|
|
+ // 测试数据
|
|
|
+ cloudData: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
}
|
|
|
-};
|
|
|
-</script>
|
|
|
-
|
|
|
-
|
|
|
-<style scoped>
|
|
|
-@media screen and (max-width: 1280px) {
|
|
|
- .dialog_diy3>>>.el-dialog {
|
|
|
- width: 100% !important;
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ chartObj:"",
|
|
|
+ loading:false
|
|
|
}
|
|
|
-}
|
|
|
+ },
|
|
|
|
|
|
-.dialog_diy>>>.el-dialog {
|
|
|
- margin-top: 10vh !important;
|
|
|
-}
|
|
|
+ mounted() {
|
|
|
+ this.addNephogram();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ //添加云图
|
|
|
+ addNephogram() {
|
|
|
+ this.loading=true
|
|
|
+ const _msg = `NOTICE
|
|
|
+ Language: Please use the same language as the user requirement, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
|
|
|
+ ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
|
|
|
+ Instruction: Based on the context, follow "Format example", write content.
|
|
|
|
|
|
-.dialog_diy>>>.el-dialog__header {
|
|
|
- background: #454545 !important;
|
|
|
- padding: 15px 20px;
|
|
|
-}
|
|
|
+ ## 任务
|
|
|
|
|
|
-.dialog_diy>>>.el-dialog__title,
|
|
|
-.dialog_diy1>>>.el-dialog__title {
|
|
|
- color: #fff;
|
|
|
-}
|
|
|
+ 请基于以下学生回答,提炼出10-20个答案,用于绘制词云图。
|
|
|
|
|
|
-.dialog_diy>>>.el-dialog__headerbtn {
|
|
|
- top: 19px;
|
|
|
-}
|
|
|
+ ## 要求
|
|
|
|
|
|
-.dialog_diy>>>.el-dialog__headerbtn .el-dialog__close {
|
|
|
- color: #fff;
|
|
|
-}
|
|
|
+ 1. **提取关键词**:从提供的答案文本中提取出10-20个最具代表性的答案。
|
|
|
+ 2. **词频统计**:计算每个关键字在文本中出现的频率。
|
|
|
+ 3. **词汇大小**:根据词频数量,确定每个关键字在词云图中的大小。词频越高,词汇大小数值越大,数值范围1-100。
|
|
|
+ 4. **输出格式**:输出结果应包含每个关键字、对应的词频数量以及词汇大小数值。
|
|
|
|
|
|
-.dialog_diy>>>.el-dialog__headerbtn .el-dialog__close:hover {
|
|
|
- color: #fff;
|
|
|
-}
|
|
|
+ ## 输出格式
|
|
|
|
|
|
-.dialog_diy>>>.el-dialog__body {
|
|
|
- overflow:hidden;
|
|
|
-}
|
|
|
+ ### 输出格式
|
|
|
|
|
|
-.dialog_diy>>>.el-dialog__body,
|
|
|
-.dialog_diy>>>.el-dialog__footer {
|
|
|
- background: #fafafa;
|
|
|
-
|
|
|
-}
|
|
|
+ [
|
|
|
+ {"value":1,"name":"氯化钠","textStyle":{"color":"#ee7959"}},
|
|
|
+ {"value":2,"name":"溶液","textStyle":{"color":"#db9b34"}},
|
|
|
+ {"value":1,"name":"实验","textStyle":{"color":"#9d9d82"}},
|
|
|
+ {"value":3,"name":"质量分数","textStyle":{"color":"#ea5514"}},
|
|
|
+ {"value":1,"name":"溶质","textStyle":{"color":"#c8161d"}},
|
|
|
+ {"value":2,"name":"氢氧化钠","textStyle":{"color":"#e60012"}},
|
|
|
+ {"value":1,"name":"溶解度","textStyle":{"color":"#1e2732"}},
|
|
|
+ {"value":4,"name":"饱和溶液","textStyle":{"color":"#e3adb9"}}
|
|
|
+ ]
|
|
|
|
|
|
-button {
|
|
|
- margin: 20px;
|
|
|
-}
|
|
|
+ 请仅仅输出表头,输出关键词和相应的内容,无需其它任何说明文字。
|
|
|
+ 冒号、逗号等符号均使用英文字符。
|
|
|
|
|
|
-.wordCloud__tagBall {
|
|
|
- margin: 0px auto;
|
|
|
- position: relative;
|
|
|
-}
|
|
|
+ ### 输出示例
|
|
|
|
|
|
-.wordCloud__tag {
|
|
|
- display: block;
|
|
|
- position: absolute;
|
|
|
- left: 0px;
|
|
|
- top: 0px;
|
|
|
- color: green;
|
|
|
- text-decoration: none;
|
|
|
- font-size: 15px;
|
|
|
- font-family: '微软雅黑';
|
|
|
- font-weight: bold;
|
|
|
-}
|
|
|
+ [
|
|
|
+ {"value":1,"name":"氯化钠","textStyle":{"color":"#ee7959"}},
|
|
|
+ {"value":2,"name":"溶液","textStyle":{"color":"#db9b34"}},
|
|
|
+ {"value":1,"name":"实验","textStyle":{"color":"#9d9d82"}},
|
|
|
+ {"value":3,"name":"质量分数","textStyle":{"color":"#ea5514"}},
|
|
|
+ {"value":1,"name":"溶质","textStyle":{"color":"#c8161d"}},
|
|
|
+ {"value":2,"name":"氢氧化钠","textStyle":{"color":"#e60012"}},
|
|
|
+ {"value":1,"name":"溶解度","textStyle":{"color":"#1e2732"}},
|
|
|
+ {"value":4,"name":"饱和溶液","textStyle":{"color":"#e3adb9"}}
|
|
|
+ ]
|
|
|
|
|
|
-.wordCloud__tag :hover {
|
|
|
- color: red;
|
|
|
-}
|
|
|
+ ## 课堂实录
|
|
|
+ ${this.cloudData ? this.cloudData : ""}
|
|
|
+ `;
|
|
|
+ const _uuid = uuidv4();
|
|
|
+ let params = {
|
|
|
+ temperature: 0,
|
|
|
+ max_tokens: 4096,
|
|
|
+ top_p: 1,
|
|
|
+ frequency_penalty: 0,
|
|
|
+ presence_penalty: 0,
|
|
|
+ messages: [{ role: "user", content: _msg }],
|
|
|
+ uid: _uuid,
|
|
|
+ mind_map_question: "",
|
|
|
+ stream: false,
|
|
|
+ model: "gpt-4o-2024-11-20"
|
|
|
+ };
|
|
|
+ this.ajax
|
|
|
+ .post("https://gpt4.cocorobo.cn/chat", params)
|
|
|
+ .then(res => {
|
|
|
+ let _data = res.data.FunctionResponse.choices[0];
|
|
|
+ let _jsonData = _data.message.content;
|
|
|
+ _jsonData = _jsonData.replaceAll("```json", "").replaceAll("```", "");
|
|
|
+ let _result = JSON.parse(_jsonData);
|
|
|
+ console.log('_result',_result);
|
|
|
|
|
|
-.wordCloud__home {
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
-}
|
|
|
+ let poi = {
|
|
|
+ tooltip: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: "wordCloud",
|
|
|
+ sizeRange: [14, 38],
|
|
|
+ rotationRange: [0, 0],
|
|
|
+ keepAspect: false,
|
|
|
+ shape: "circle",
|
|
|
+ left: "center",
|
|
|
+ top: "center",
|
|
|
+ right: null,
|
|
|
+ bottom: null,
|
|
|
+ width: "90%",
|
|
|
+ height: "90%",
|
|
|
+ rotationRange: [-90, 90],
|
|
|
+ rotationStep: 45,
|
|
|
+ data: _result
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ console.log('poi',poi);
|
|
|
+ this.getChartData(poi)
|
|
|
+ // this.saveData(poi)
|
|
|
+ })
|
|
|
+ .catch(e => {
|
|
|
+ console.log(e);
|
|
|
+ this.$message.error("生成词云图失败");
|
|
|
+ })
|
|
|
+ .finally(_ => {
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ getChartData(poi) {
|
|
|
+ this.chartObj = echarts.init(this.$refs.chartRef);
|
|
|
+ this.chartObj.setOption(poi);
|
|
|
+ this.loading=false
|
|
|
+ window.addEventListener("resize", () => {
|
|
|
+ this.chartObj.resize();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
|
|
|
-.noneBox{
|
|
|
- height:500px;
|
|
|
- width:100%;
|
|
|
- display:flex;
|
|
|
- align-items:center;
|
|
|
- justify-content:center;
|
|
|
+<style scoped>
|
|
|
+.chart {
|
|
|
+ width: 100%;
|
|
|
+ height: 500px;
|
|
|
+ background-color: #fff;
|
|
|
}
|
|
|
-</style>
|
|
|
+
|
|
|
+</style>
|