系统功能完善

This commit is contained in:
于磊奇 2025-06-19 12:59:39 +08:00
parent b36c27f911
commit bad2583779
9 changed files with 570 additions and 104 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -26,7 +26,7 @@ let myChart = null;
const option = {
title: {
text: '中国海警首次登检菲律宾运补船只 (Y轴镜像)',
text: '事件热度预测',
left: 'center'
},
tooltip: { trigger: 'axis' },

View File

@ -27,7 +27,7 @@ let myChart = null;
const option = {
title: {
text: '中方回应菲称我海警挥舞刀具 (Y轴镜像)',
text: '事件热度预测',
left: 'center'
},
tooltip: { trigger: 'axis' },

View File

@ -24,7 +24,7 @@ let myChart = null;
const option = {
title: {
text: '中国海警夺回菲方盗窃赃物 (Y轴镜像)',
text: '事件热度预测',
left: 'center'
},
tooltip: { trigger: 'axis' },
@ -38,7 +38,7 @@ const option = {
series: [{
name: '热度',
data: yAxisMirroredData,
type: 'bar', // 使
type: 'line',
itemStyle: { color: '#91cc75' }
}]
};

View File

@ -26,7 +26,7 @@ let myChart = null;
const option = {
title: {
text: '菲自曝被缴枪的是顶级特种部队 (Y轴镜像)',
text: '时间热度预测',
left: 'center'
},
tooltip: { trigger: 'axis' },

View File

@ -27,7 +27,7 @@ let myChart = null;
const option = {
title: {
text: '菲希望与中国就南海问题对话 (Y轴镜像)',
text: '事件热度预测',
left: 'center'
},
tooltip: { trigger: 'axis' },
@ -42,7 +42,6 @@ const option = {
name: '热度',
data: yAxisMirroredData,
type: 'line',
step: 'start', // 使线
itemStyle: { color: '#ee6666' }
}]
};

View File

@ -2,18 +2,32 @@
<template>
<div style="width: 100%; height: 100%;">
<div class="graph-box" id="graph-container"></div>
<div class="slider-box">
<el-slider v-model="state.sliderValue" @input="sliderChange" :marks="state.marks" />
<div class="slider-box">
<div class="slider-container">
<div class="play-controls">
<button @click="togglePlay" class="play-button">
{{ isPlaying ? '暂停' : '播放' }}
</button>
</div>
<el-slider style="" v-model="state.sliderValue" @input="sliderChange" :marks="state.marks" />
</div>
</div>
</div>
</template>
<script setup>
import axios from "axios";
import { onMounted, reactive } from "vue";
import { onMounted,onUnmounted, reactive,ref } from "vue";
import { Graph } from "@antv/g6";
import { ElLoading } from 'element-plus';
const isPlaying = ref(false);
const playTimer = ref(null);
const state = reactive({
graph: null,
marks: {
@ -22,8 +36,8 @@ const state = reactive({
'20': "2024-01-05",
'30': "2024-03-14",
'40': "2024-03-16",
'60': "2024-05-26",
'70': "2024-06-21",
'60': "2024-05-18",
'80': "2024-05-23",
'100': "2024-06-28"
},
sliderValue: 0,
@ -46,12 +60,58 @@ const hideLoading = () => {
}
};
const setStateSliderValue = (value) => {
state.sliderValue = value;
sliderChange(value);
};
//
const togglePlay = () => {
if (isPlaying.value) {
stopAutoPlay();
} else {
startAutoPlay();
}
};
const startAutoPlay = () => {
isPlaying.value = true;
// mark
const markKeys = Object.keys(state.marks).map(Number).sort((a, b) => a - b);
let currentIndex = markKeys.indexOf(state.sliderValue);
playTimer.value = setInterval(() => {
if (currentIndex < markKeys.length - 1) {
currentIndex++;
} else {
stopAutoPlay();
return;
}
const nextValue = markKeys[currentIndex];
state.sliderValue = nextValue;
sliderChange(nextValue);
}, 3000); // 3
};
const stopAutoPlay = () => {
isPlaying.value = false;
if (playTimer.value) {
clearInterval(playTimer.value);
playTimer.value = null;
}
};
const sliderChange = (val) => {
//
if (isPlaying.value) {
stopAutoPlay();
}
if (state.marks[val]) {
if (state.marks[val]) {
getData(state.marks[val]);
}
}
}
/**
* 根据日期获取图谱数据
* @param dataTime 日期
@ -152,6 +212,15 @@ const highlightNode = (id) => {
});
}
defineExpose({
highlightNode,
setStateSliderValue
});
onUnmounted(() => {
stopAutoPlay();
});
onMounted(() => {
getData('2024-01-03')
})
@ -163,7 +232,37 @@ onMounted(() => {
height: 100%;
}
.slider-box {
.slider-container {
display: flex;
align-items: center;
gap: 10px;
margin-top: -230px;
}
.play-controls {
}
.play-button {
width: 60px;
padding: 6px 12px;
background-color: #409EFF;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
margin-right: 10px;
}
.play-button:hover {
background-color: #337ecc;
}
.slider-box {
flex: 1;
margin-top: 0;
width: 90%;
margin-top: -230px;
margin-left: 10px;
flex-direction: column;
}
</style>

View File

@ -6,14 +6,19 @@
<img src="../assets/images/mess/key.png" alt="">
<div class="tooltip-containner-data">
<li><img :src="currentItem.img" alt="" style=""></li>
<li><chart32_-inspection /></li>
<li style="margin-left: 10px; margin-top: 20px;"><img src="../assets/images/logo/point.png"
alt="">最初首发者&nbsp;&nbsp;&nbsp;{{ currentItem.earler }} </li>
<li style="margin-left: 10px;"><img src="../assets/images/logo/point.png" alt="">积极评论者{{ currentItem.comenter
<li v-if="currentItem.title.includes('中国海警首次登检菲律宾运补船只')"><chart32_-inspection /></li>
<li v-else-if="currentItem.title.includes('中方回应菲称我海警挥舞刀具')"> <Chart33_WavingBlades /></li>
<li v-else-if="currentItem.title.includes('中国海警夺回菲方盗窃赃物')"><Chart34_RecoveredGoods /></li>
<li v-else-if="currentItem.title.includes('菲自曝被中国海警缴枪的是顶级特种部队')"><Chart35_SpecialForces /></li>
<li v-else-if="currentItem.title.includes('菲律宾希望与中国就南海问题进行对话')"><Chart36_Dialogue /></li>
<li style="margin-left: 10px; margin-top:20px;"><img src="../assets/images/logo/point.png"
alt="" style="margin-bottom: -7px;">最初首发者&nbsp;&nbsp;&nbsp;{{ currentItem.earler }} </li>
<li style="margin-left: 10px;"><img src="../assets/images/logo/point.png" alt="" style="margin-bottom: -7px;">积极评论者{{ currentItem.comenter
}}</li>
<li style="margin-left: 200px;margin-top: -57px;"><img src="../assets/images/logo/point.png" alt="">锚点用户{{
<li style="margin-left: 200px;margin-top: -45px;"><img src="../assets/images/logo/point.png" alt="" style="margin-bottom: -7px;">锚点用户{{
currentItem.keyuser }}</li>
<li style="margin-left: 200px;;"><img src="../assets/images/logo/point.png" alt="">积极转发者&nbsp;&nbsp;&nbsp;{{
<li style="margin-left: 200px;;"><img src="../assets/images/logo/point.png" alt="" style="margin-bottom: -7px;">积极转发者&nbsp;&nbsp;&nbsp;{{
currentItem.switcher }}</li>
</div>
<img src="../assets/images/logo/cancel.png" alt=""
@ -44,19 +49,20 @@
<div class="info-coment">精选贴文
<!-- 新增贴文列表容器 -->
<div class="post-list-container">
<div class="post-item" v-for="(post, index) in visibleData" :key="index">
<p class="post-content">{{ post.commenter }}</p>
<div class="post-item" v-for="(post, index) in filteredComments" :key="index">
<p class="post-content">{{ post.comment }}</p>
<p class="post-time">{{ post.time }}</p>
</div>
<div v-if="filteredComments.length === 0" class="no-posts">
暂无该用户的贴文数据
</div>
</div>
</div>
</div>
</div>
<header class="header">
<button class="back-home-btn" @click="goToHome">返回主页面</button>
<div class="timer">
<button class="reload-button" @click="handleReload" :disabled="isReloading" style="margin-top: -10px;">
<img src="../assets/images/logo/reload.png">
{{ buttonText }}
@ -104,10 +110,9 @@
</div>
<div class="suggestion-containner">
<ul>
<button
style="background-image: url('src/assets/images/logo/定位.png'); background-size: cover; background-repeat: no-repeat; background-position: center;width: 20px;height: 20px;margin-left: 370px;margin-bottom: -60px;border-radius: 0px;border: 0;cursor: pointer;"
@click.stop="handleCombineAction"></button>
<li v-for="item in filteredData" :key="item.id" @click="openDetailModal(item)"
<!-- 只显示第一个按钮 -->
<li v-for="(item, index) in filteredData" :key="item.id" @click="openDetailModal(item)"
@mouseenter="handleMouseEnter(item.id)" @mouseleave="handleMouseLeave()"
:class="{ 'hover-item': hoverItemId === item.id }">
<img :src="item.avatar">
@ -117,6 +122,9 @@
<span class="span-2">粉丝数&nbsp;{{ item.number }}</span>
<span class="span-3">推荐监控频率{{ item.transmit }}</span>
</div>
<button v-if="index === 0"
style="background-image: url('src/assets/images/logo/定位.png'); background-size: cover; background-repeat: no-repeat; background-position: center;margin-left: 340px;margin-top: -100px;width: 20px;height: 20px;border-radius: 0px;border: 0;cursor: pointer;"
@click.stop="handleLocateMark"></button>
</li>
</ul>
</div>
@ -139,10 +147,15 @@
</div>
</div>
<div class="intime">
<img src="../assets/images/percent/intime.png" alt="" style="margin-left:30px;margin-top: 30px;">
<img src="../assets/images/percent/intime-data.png " style="margin-left:30px;margin-bottom: 10px;">
<img src="../assets/images/logo/xingwei.png" alt="" style="margin-left:30px;margin-top: 30px;">
<img src="../assets/images/logo/xingwei-data.png" style="margin-left:30px;margin-bottom: 30px;">
<!-- 添加图表切换按钮 -->
<div class="chart-tabs">
<button @click="switchChartType('registration')"
:class="{ 'active-tab': currentChartType === 'registration' }">注册时间</button>
<button @click="switchChartType('behavior')"
:class="{ 'active-tab': currentChartType === 'behavior' }">行为模式</button>
</div>
<!-- ECharts图表容器 -->
<div id="categoryChart" style="width: 400px;height: 200px;margin-top: 30px;"></div>
</div>
</div>
</div>
@ -178,17 +191,17 @@
</div>
</div>
<div class="containner5" style="width: 850px; height: 850px">
<IndexView />
<IndexView ref="appRef" />
</div>
<div class="containner6">
<div class="containner6-data">
<img src="../assets/images/main-6/mao.png" alt="" style="margin-top: 20px; margin-left: 100px;">
<p class="containner6-font1">500</p>
<p class="containner6-font1">20</p>
<p class="containner6-font2">锚点数量</p>
</div>
<div class="containner6-data" style="margin-top: -180px;margin-left: 200px;">
<img src="../assets/images/main-6/jiankong.png" alt="" style="margin-top: 10px; margin-left: 100px;">
<p class="containner6-font1">36</p>
<p class="containner6-font1">15</p>
<p class="containner6-font2">已监控锚点</p>
</div>
<div class="containner6-data" style="margin-top: -210px;margin-left: 400px;">
@ -205,7 +218,7 @@
</div>
</template>
<script setup>
import { ref, computed, reactive, onMounted, onUnmounted, nextTick } from 'vue';
import { ref, computed, reactive, onMounted, onUnmounted, nextTick,watch } from 'vue';
import { useRouter } from 'vue-router';
import IndexView from './App.vue';
import ScrollContainer from '@/components/ScrollContainer.vue';
@ -213,6 +226,10 @@ import * as echarts from 'echarts';
import axios from 'axios';
import { useActionStore } from '@/store';
import Chart32_Inspection from '@/components/Chart32_Inspection(1).vue';
import Chart33_WavingBlades from '@/components/Chart33_WavingBlades(1).vue';
import Chart34_RecoveredGoods from '@/components/Chart34_RecoveredGoods(1).vue';
import Chart35_SpecialForces from '@/components/Chart35_SpecialForces(1).vue';
import Chart36_Dialogue from '@/components/Chart36_Dialogue(1).vue';
let myChart = null;
@ -237,6 +254,20 @@ const goToHome = () => {
router.push('/'); //
};
const appRef = ref(null);
const handleLocateMark = () => {
if (appRef.value) {
// marks=2024-3-14sliderValue
appRef.value.setStateSliderValue(30);
//
setTimeout(() => {
// 'ID'ID
appRef.value.highlightNode('840983');
}, 1500); // 1.5
}
};
const handleCombineAction = () => {
actionStore.triggerCombine();
};
@ -347,33 +378,33 @@ const handleInput = () => {
};
const mediaData = [
{ id: 1, type: '新闻媒体', name: '新浪军事', avatar: 'src/views/user/xinlang.png', number: '5005.8w', transmit: '425', time: '2024.1.5', posts: '2.1w', atten: '98', interaction: '16.1w' },
{ id: 2, type: '新闻媒体', name: '环球时报', avatar: 'src/views/user/huanqiu.png', number: '3126.1w', transmit: '557', time: '2024.3.12', posts: '1.8w', atten: '76', interaction: '9.3w' },
{ id: 3, type: '自媒体', name: '大侠啊啊啊啊', avatar: 'src/views/user/daxia.png', number: '288', transmit: '55', time: '2024.2.20', posts: '896', atten: '12', interaction: '3.2w' },
{ id: 4, type: '自媒体', name: '外贸发布BBS', avatar: 'src/views/user/bbs.png', number: '1.3w', transmit: '68', time: '2024.4.5', posts: '562', atten: '8', interaction: '1.5w' },
{ id: 5, type: '自媒体', name: '空天砺剑', avatar: 'src/views/user/kongtian.png', number: '516.5w', transmit: '55', time: '2024.1.28', posts: '3.2w', atten: '156', interaction: '22.7w' },
{ id: 6, type: '自媒体', name: '爱锤盾海桃-霆恩启副', avatar: 'src/views/user/ai.png', number: '223', transmit: '76', time: '2024.3.18', posts: '432', atten: '5', interaction: '896' },
{ id: 7, type: '自媒体', name: '苍龙飞天79', avatar: 'src/views/user/79.png', number: '516.6w', transmit: '76', time: '2024.2.10', posts: '2.9w', atten: '142', interaction: '19.5w' },
{ id: 8, type: '自媒体', name: '盖世英雄玉椒龙', avatar: 'src/views/user/gaishi.png', number: '42w', transmit: '53', time: '2024.4.1', posts: '1.2w', atten: '67', interaction: '8.3w' },
{ id: 9, type: '自媒体', name: '十八子91221', avatar: 'src/views/user/91221.png', number: '1947', transmit: '56', time: '2024.1.15', posts: '654', atten: '9', interaction: '2.1w' },
{ id: 10, type: '自媒体', name: '江夏云飞', avatar: 'src/views/user/jiang.png', number: '1629', transmit: '33', time: '2024.3.25', posts: '321', atten: '4', interaction: '987' },
{ id: 11, type: '自媒体', name: '唐宁20150903', avatar: 'src/views/user/tang.png', number: '25', transmit: '43', time: '2024.2.5', posts: '128', atten: '2', interaction: '456' },
{ id: 12, type: '自媒体', name: '钻石狗Boss', avatar: 'src/views/user/bbs.png', number: '1184', transmit: '76', time: '2024.4.12', posts: '512', atten: '7', interaction: '1.8w' },
{ id: 13, type: '自媒体', name: '乐之567', avatar: 'src/views/user/567.png', number: '266', transmit: '24', time: '2024.1.30', posts: '209', atten: '3', interaction: '654' },
{ id: 14, type: '自媒体', name: '地瓜熊老六', avatar: 'src/views/user/lao.png', number: '667.5w', transmit: '33', time: '2024.3.8', posts: '4.7w', atten: '210', interaction: '33.2w' },
{ id: 15, type: '自媒体', name: 'CGTN记者团', avatar: 'src/views/user/cgtn.png', number: '322.1w', transmit: '43', time: '2024.2.18', posts: '2.5w', atten: '105', interaction: '17.8w' },
{ id: 16, type: '自媒体', name: '钱局长本人', avatar: 'src/views/user/qian.png', number: '40万', transmit: '56', time: '2024.4.20', posts: '1.3w', atten: '58', interaction: '9.4w' },
{ id: 17, type: '自媒体', name: '肥_谍_gg', avatar: 'src/views/user/gg.png', number: '245', transmit: '56', time: '2024.1.22', posts: '317', atten: '6', interaction: '1.2w' },
{ id: 18, type: '自媒体', name: '深海一万米', avatar: 'src/views/user/shenhai.png', number: '126w', transmit: '44', time: '2024.3.5', posts: '8906', atten: '42', interaction: '6.7w' },
{ id: 19, type: '政府官号', name: '中国海警', avatar: 'src/views/user/haijing.png', number: '80.9w', transmit: '45', time: '2024.2.8', posts: '1.1w', atten: '35', interaction: '5.2w' },
{ id: 20, type: '政府官号', name: '平安泸县', avatar: 'src/views/user/luxian.png', number: '3.9w', transmit: '45', time: '2024.4.15', posts: '4321', atten: '18', interaction: '2.9w' },
{ id: 1, type: '新闻媒体', name: '新浪军事', avatar: 'src/views/user/xinlang.png', number: '5005.8w', transmit: '10h/1次', time: '2024.1.5', posts: '2.1w', atten: '98', interaction: '16.1w' },
{ id: 2, type: '新闻媒体', name: '环球时报', avatar: 'src/views/user/huanqiu.png', number: '3126.1w', transmit: '8h/1次', time: '2024.3.12', posts: '1.8w', atten: '76', interaction: '9.3w' },
{ id: 3, type: '自媒体', name: '大侠啊啊啊啊', avatar: 'src/views/user/daxia.png', number: '288', transmit: '20h/1次', time: '2024.2.20', posts: '896', atten: '12', interaction: '3.2w' },
{ id: 4, type: '自媒体', name: '外贸发布BBS', avatar: 'src/views/user/bbs.png', number: '1.3w', transmit: '21h/1次', time: '2024.4.5', posts: '562', atten: '8', interaction: '1.5w' },
{ id: 5, type: '自媒体', name: '空天砺剑', avatar: 'src/views/user/kongtian.png', number: '516.5w', transmit: '18h/1次', time: '2024.1.28', posts: '3.2w', atten: '156', interaction: '22.7w' },
{ id: 6, type: '自媒体', name: '爱锤盾海桃-霆恩启副', avatar: 'src/views/user/ai.png', number: '223', transmit: '25h/1次', time: '2024.3.18', posts: '432', atten: '5', interaction: '896' },
{ id: 7, type: '自媒体', name: '苍龙飞天79', avatar: 'src/views/user/79.png', number: '516.6w', transmit: '24h/1次', time: '2024.2.10', posts: '2.9w', atten: '142', interaction: '19.5w' },
{ id: 8, type: '自媒体', name: '盖世英雄玉椒龙', avatar: 'src/views/user/gaishi.png', number: '42w', transmit: '26h/1次', time: '2024.4.1', posts: '1.2w', atten: '67', interaction: '8.3w' },
{ id: 9, type: '自媒体', name: '十八子91221', avatar: 'src/views/user/91221.png', number: '1947', transmit: '30h/1次', time: '2024.1.15', posts: '654', atten: '9', interaction: '2.1w' },
{ id: 10, type: '自媒体', name: '江夏云飞', avatar: 'src/views/user/jiang.png', number: '1629', transmit: '23h/1次', time: '2024.3.25', posts: '321', atten: '4', interaction: '987' },
{ id: 11, type: '自媒体', name: '唐宁20150903', avatar: 'src/views/user/tang.png', number: '25', transmit: '22h/1次', time: '2024.2.5', posts: '128', atten: '2', interaction: '456' },
{ id: 12, type: '自媒体', name: '钻石狗Boss', avatar: 'src/views/user/bbs.png', number: '1184', transmit: '22h/1次', time: '2024.4.12', posts: '512', atten: '7', interaction: '1.8w' },
{ id: 13, type: '自媒体', name: '乐之567', avatar: 'src/views/user/567.png', number: '266', transmit: '18h/1次', time: '2024.1.30', posts: '209', atten: '3', interaction: '654' },
{ id: 14, type: '自媒体', name: '地瓜熊老六', avatar: 'src/views/user/lao.png', number: '667.5w', transmit: '10h/1次', time: '2024.3.8', posts: '4.7w', atten: '210', interaction: '33.2w' },
{ id: 15, type: '自媒体', name: 'CGTN记者团', avatar: 'src/views/user/cgtn.png', number: '322.1w', transmit: '15h/1次', time: '2024.2.18', posts: '2.5w', atten: '105', interaction: '17.8w' },
{ id: 16, type: '自媒体', name: '钱局长本人', avatar: 'src/views/user/qian.png', number: '40万', transmit: '24h/1次', time: '2024.4.20', posts: '1.3w', atten: '58', interaction: '9.4w' },
{ id: 17, type: '自媒体', name: '肥_谍_gg', avatar: 'src/views/user/gg.png', number: '245', transmit: '19h/1次', time: '2024.1.22', posts: '317', atten: '6', interaction: '1.2w' },
{ id: 18, type: '自媒体', name: '深海一万米', avatar: 'src/views/user/shenhai.png', number: '126w', transmit: '21h/1次', time: '2024.3.5', posts: '8906', atten: '42', interaction: '6.7w' },
{ id: 19, type: '政府官号', name: '中国海警', avatar: 'src/views/user/haijing.png', number: '80.9w', transmit: '26h/1次', time: '2024.2.8', posts: '1.1w', atten: '35', interaction: '5.2w' },
{ id: 20, type: '政府官号', name: '平安泸县', avatar: 'src/views/user/luxian.png', number: '3.9w', transmit: '18h/1次', time: '2024.4.15', posts: '4321', atten: '18', interaction: '2.9w' },
];
const categoryData = {
'全部': {
anchorCount: 36,
anchorCount: 20,
postFrequency: '5.1天/次',
fansCount: '1.7w',
interactionCount: 0
interactionCount: 6
},
'自媒体': {
anchorCount: 16,
@ -391,7 +422,7 @@ const categoryData = {
anchorCount: 2,
postFrequency: '14.8天/次',
fansCount: '4065.5w',
interactionCount: 0
interactionCount: 4
}
};
//
@ -414,7 +445,6 @@ const showTooltip = ref(false);
const allData = Array.from({ length: 5 }, (_, index) => ({ id: index, showTemporaryStyle: false }));
const currentIndex = ref(0);
const visibleData = ref([
{
avatar: './src/views/user/boss.png',
@ -604,6 +634,37 @@ const visibleData = ref([
},
]);
// commentervisibleData
const groupedByCommenter = visibleData.value.reduce((groups, item) => {
const commenter = item.commenter.trim();
if (!groups[commenter]) {
groups[commenter] = [];
}
groups[commenter].push(item);
return groups;
}, {});
const commenterGroups = Object.entries(groupedByCommenter).map(([commenter, comments]) => ({
commenter,
comments
}));
//
const filteredComments = computed(() => {
if (!currentDetailItem.value) return [];
//
const targetName = currentDetailItem.value.name?.trim().toLowerCase();
if (!targetName) return [];
//
const matchedGroup = commenterGroups.find(group =>
group.commenter.trim().toLowerCase() === targetName
);
return matchedGroup ? matchedGroup.comments : [];
});
//
const tooltipDdata1 = [
{
@ -777,7 +838,7 @@ const tooltipDdata5 = [
switcher: '杨毅妻儿',
earler: '白俄罗斯大宽',
keyuser: '盖世英雄玉椒龙, 肥_谍_gg, 钻石狗Boss, 外贸发布BBS, 新浪军事, 钱局长本人, 地瓜熊老六,唐宁20150903,空天砺剑',
img: 'src/assets/images/mess/main4.png',
img: 'src/assets/images/mess/main5.png',
imgdata: 'src/assets/images/mess/4top.png',
beforeimg: 'src/assets/images/logo/ruank4.png',
backimg: 'src/assets/images/logo/high3.png'
@ -789,7 +850,7 @@ const tooltipDdata5 = [
switcher: '彼岸星光德尔塔',
earler: '今日俄罗斯RT',
keyuser: '新浪军事',
img: 'src/assets/images/mess/main5.png',
img: 'src/assets/images/mess/main4.png',
imgdata: 'src/assets/images/mess/5top.png',
beforeimg: 'src/assets/images/logo/ruank5.png',
backimg: 'src/assets/images/logo/high3.png'
@ -872,8 +933,6 @@ const startDataSwitchTimer = () => {
timers.push(interval, timeout);
};
//
const appRef = ref(null);
//
const handleLocationClick = (itemId) => {
@ -887,8 +946,188 @@ const handleLocationClick = (itemId) => {
}, 500);
};
//
const currentChartType = ref('registration'); // 'registration' 'behavior'
let categoryChart = null;
//
const chartData = {
'全部': {
registration: [
{ name: '小于6个月', value: 0, itemStyle: { color: '#3398DB' } },
{ name: '6-12个月', value: 5, itemStyle: { color: '#13C2C2' } },
{ name: '1-3年', value: 15, itemStyle: { color: '#00B42A' } },
{ name: '大于三年', value: 80, itemStyle: { color: '#F53F3F' } }
],
behavior: [
{ name: '转发行为', value: 43.12, itemStyle: { color: '#722ED1' } },
{ name: '评论行为', value: 22.06, itemStyle: { color: '#EB0AA4' } },
{ name: '原发行为', value: 34.82, itemStyle: { color: '#FF7D00' } }
]
},
'自媒体': {
registration: [
{ name: '小于6个月', value: 0, itemStyle: { color: '#3398DB' } },
{ name: '6-12个月', value: 10, itemStyle: { color: '#13C2C2' } },
{ name: '1-3年', value: 20, itemStyle: { color: '#00B42A' } },
{ name: '大于三年', value: 70, itemStyle: { color: '#F53F3F' } }
],
behavior: [
{ name: '转发行为', value: 49.19, itemStyle: { color: '#722ED1' } },
{ name: '评论行为', value: 24.48, itemStyle: { color: '#EB0AA4' } },
{ name: '原发行为', value: 26.33, itemStyle: { color: '#FF7D00' } }
]
},
'政府官号': {
registration: [
{ name: '小于6个月', value: 0, itemStyle: { color: '#3398DB' } },
{ name: '6-12个月', value: 0, itemStyle: { color: '#13C2C2' } },
{ name: '大于1年', value: 0, itemStyle: { color: '#00B42A' } },
{ name: '大于三年', value: 100, itemStyle: { color: '#F53F3F' } }
],
behavior: [
{ name: '转发行为', value: 0, itemStyle: { color: '#722ED1' } },
{ name: '评论行为', value: 15, itemStyle: { color: '#EB0AA4' } },
{ name: '原发行为', value: 85, itemStyle: { color: '#FF7D00' } }
]
},
'新闻媒体': {
registration: [
{ name: '小于6个月', value: 0, itemStyle: { color: '#3398DB' } },
{ name: '6-12个月', value: 50, itemStyle: { color: '#13C2C2' } },
{ name: '大于1年', value: 0, itemStyle: { color: '#00B42A' } },
{ name: '大于三年', value: 50, itemStyle: { color: '#F53F3F' } }
],
behavior: [
{ name: '转发行为', value: 0, itemStyle: { color: '#722ED1' } },
{ name: '评论行为', value: 0, itemStyle: { color: '#EB0AA4' } },
{ name: '原发行为', value: 100, itemStyle: { color: '#FF7D00' } }
]
}
};
// /
const switchChartType = (type) => {
currentChartType.value = type;
updateChart();
};
//
const updateChart = () => {
if (!categoryChart) return;
//
const category = currentCategory.value === '全部' ? '全部' : currentCategory.value;
const data = chartData[category][currentChartType.value];
//
categoryChart.setOption({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c}% ({d}%)'
},
legend: {
orient: 'vertical', //
top: 'center', //
left: 'right', //
right: 100, //
itemGap: 20,
textStyle: { color: '#fff', width: 120 }, //
formatter: function(name) {
//
const item = data.find(item => item.name === name);
if (!item) return name;
//
const total = data.reduce((sum, item) => sum + item.value, 0);
const percentage = total > 0 ? ((item.value / total) * 100).toFixed(1) + '%' : '0%';
// 使
return `{name|${name}}{percent|${percentage}}`;
},
textStyle: {
rich: {
name: { width: 100, color: '#fff' },
percent: { align: 'right', color: '#ffcc00', fontWeight: 'bold', }
}
}
},
series: [
{
name: currentChartType.value === 'registration' ? '注册时间分布' : '行为模式分布',
type: 'pie',
radius: ['40%', '70%'],
center: ['40%', '50%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'outside'
},
emphasis: {
label: {
show: true,
fontSize: 16,
fontWeight: 'bold',
color: '#fff'
}
},
labelLine: {
show: false
},
data: data
}
]
});
};
//
const initChart = () => {
// DOM
const chartDom = document.getElementById('categoryChart');
if (!chartDom) return;
// ECharts
categoryChart = echarts.init(chartDom);
//
const option = {
backgroundColor: 'transparent',
tooltip: {
trigger: 'item'
},
series: [
{
type: 'pie',
radius: ['40%', '70%'],
data: []
}
]
};
option && categoryChart.setOption(option);
//
updateChart();
};
//
watch(currentCategory, () => {
updateChart();
});
onMounted(() => {
// ... ...
// ... ...
initChart();
//
window.addEventListener('resize', () => {
if (categoryChart) {
categoryChart.resize();
}
});
startActiveWarningTimer();
startHighRiskTimer();
startDataSwitchTimer();
@ -907,6 +1146,8 @@ onMounted(() => {
myChart = echarts.init(chartDom);
// Set option here
const option = {
animationDuration: 60000, // ms
animationEasing: 'cubicInOut',
title: {
},
tooltip: {
@ -916,8 +1157,7 @@ onMounted(() => {
data: ['活跃预警事件', '高风险事件']
},
grid: {
left: '3%',
right: '4%',
left: '5%',
containLabel: true
},
toolbox: {
@ -930,7 +1170,6 @@ onMounted(() => {
boundaryGap: true,//
data: ['6.29', '6.30', '7-1', '7-2', '7-3', '7-4', '7-5'],
name: '日期',
nameLocation: 'middle',
nameGap: 20,
nameTextStyle: {
color: '#606266',
@ -1069,10 +1308,6 @@ onMounted(() => {
myChart.setOption(option);
}
});
//
onUnmounted(() => {
document.removeEventListener('click', handleClickOutside);
//
@ -1088,6 +1323,10 @@ onUnmounted(() => {
myChart.dispose();
myChart = null;
}
if (categoryChart) {
categoryChart.dispose();
categoryChart = null;
}
});
});
</script>
@ -1118,9 +1357,6 @@ onUnmounted(() => {
position: relative;
z-index: 1;
}
.time span {
font-family: LCD2;
font-weight: 400;
@ -1132,7 +1368,6 @@ onUnmounted(() => {
margin-right: 80px;
margin-top: -148px;
}
.search {
width: 530px;
height: 48px;
@ -1424,7 +1659,7 @@ onUnmounted(() => {
.suggestion-containner {
margin-left: 10px;
margin-top: 15px;
width: 400px;
width: 420px;
height: 480px;
max-height: 380px;
/* 可根据需要调整最大高度 */
@ -1463,6 +1698,7 @@ onUnmounted(() => {
}
.span-3 {
width: 200px;
font-family: PingFang SC;
font-weight: 200;
font-size: 14px;
@ -1518,7 +1754,7 @@ onUnmounted(() => {
.containner2-alldata {
margin-left: 25px;
width: 420px;
width: 450px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
@ -1543,7 +1779,7 @@ onUnmounted(() => {
justify-content: center;
align-items: center;
color: #C6E3F5;
width: 200px;
width: 400px;
list-style-type: none;
flex: 1;
min-width: 0;
@ -1554,15 +1790,6 @@ onUnmounted(() => {
width: 420px;
height: 200px;
max-height: 200px;
/* 可根据需要调整最大高度 */
overflow-y: auto;
/* 当内容超出最大高度时显示垂直滚动条 */
overflow-x: hidden;
/* 隐藏水平滚动条 */
scrollbar-width: none;
/* Firefox */
;
}
.color-block1 {
@ -2086,4 +2313,47 @@ onUnmounted(() => {
.back-home-btn:active {
background-color: #0a1949;
}
.chart-tabs {
margin-top: -80px;
display: flex;
justify-content: center;
gap: 0px;
margin-left: 180px;
}
.chart-tabs button {
width: 100px;
height: 30px;
margin-top: 60px;
margin-left: 10px;
border: none;
border-radius: 15px;
background-color: #333;
color: #fff;
cursor: pointer;
transition: all 0.3s ease;
}
.chart-tabs button.active-tab {
margin-top: 60px;
background-color: #1890ff;
box-shadow: 0 0 10px rgba(24, 144, 255, 0.5);
}
/* 图表容器样式 */
#categoryChart {
width: 80%;
height: 400px;
margin-left: -40px;
}
/* 响应式调整 */
@media (max-width: 900px) {
#categoryChart {
height: 200px;
}
}
</style>

View File

@ -56,19 +56,25 @@
style=" width: 180px;margin-top: 30px;margin-right: 50px;float: right;">
<img src="../assets/images/percent/1-2.png" alt=""
style=" width: 180px;margin-top: -70px;margin-right: 50px;float: right;">
<img src="../assets/images/percent/1-1-1.png" alt="" style="margin-left: 45px;">
<!-- 修改点点击时调用不带参数的 openModal -->
<img
:src="image111"
alt="可点击图片"
style="margin-left: 45px; cursor: pointer;"
@click="openModal()"
>
<button
class="mao-button"
:class="{ active: route.path === '/Main' }"
@click="goToPage('/Main')"
>
<img src="../assets/images/logo/mainmao.png" alt="" style="
display: block;
width: 100%;
height: 100%;
object-fit: cover;
">
</button>
class="mao-button"
:class="{ active: route.path === '/Main' }"
@click="goToPage('/Main')"
>
<img src="../assets/images/logo/mainmao.png" alt="" style="
display: block;
width: 100%;
height: 100%;
object-fit: cover;
">
</button>
<img src="../assets/images/percent/1-1-2.png" alt="" style="margin-top: 25px;margin-left: 45px;">
</div>
<div class="main2">
@ -78,7 +84,13 @@
style=" width: 180px;margin-top: 30px;margin-right: 50px;float: right;">
<img src="../assets/images/percent/2-2.png" alt=""
style=" width: 180px;margin-top: -70px;margin-right: 50px;float: right;">
<img src="../assets/images/percent/2-1-1.png" alt="" style="margin-left: 45px;">
<!-- 修改点点击时调用不带参数的 openModal -->
<img
:src="image211"
alt="可点击图片"
style="margin-left: 45px; cursor: pointer;"
@click="openModal()"
>
<img src="../assets/images/percent/2-1-2.png" alt="" style="margin-top: 25px;margin-left: 45px;">
</div>
<div class="main3">
@ -88,13 +100,24 @@
style=" width: 180px;margin-top: 30px;margin-right: 50px;float: right;">
<img src="../assets/images/percent/3-2.png" alt=""
style=" width: 180px;margin-top: -70px;margin-right: 50px;float: right;">
<img src="../assets/images/percent/3-1-1.png" alt="" style="margin-left: 45px;">
<!-- 修改点点击时调用不带参数的 openModal -->
<img
:src="image311"
alt="可点击图片"
style="margin-left: 45px; cursor: pointer;"
@click="openModal()"
>
<img src="../assets/images/percent/3-1-2.png" alt="" style="margin-top: 25px;margin-left: 45px;">
</div>
</div>
</body>
<div>
<!-- 图片弹窗/模态框 -->
<div v-if="isModalVisible" class="modal-overlay" @click="closeModal">
<div class="modal-content" @click.stop>
<span class="modal-close-button" @click="closeModal">×</span>
<img :src="modalImageSrc" alt="Modal Image" class="modal-image">
</div>
</div>
</div>
@ -104,8 +127,34 @@
import { useRouter } from 'vue-router';
import { ref, onMounted,onUnmounted } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
import { ElLoading } from 'element-plus';
//
import tanchuangImage from '../assets/images/tanchuang.png';
//
import image111 from '../assets/images/percent/1-1-1.png';
import image211 from '../assets/images/percent/2-1-1.png';
import image311 from '../assets/images/percent/3-1-1.png';
const route = useRoute();
//
const isModalVisible = ref(false);
const modalImageSrc = ref('');
// tanchuang.png
const openModal = () => {
modalImageSrc.value = tanchuangImage; // 使 tanchuang.png
isModalVisible.value = true;
};
//
const closeModal = () => {
isModalVisible.value = false;
};
//
const currentTime = ref('');
@ -224,6 +273,55 @@ onUnmounted(() => {
</script>
<style scoped>
/* 弹窗样式 */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
cursor: pointer;
}
.modal-content {
position: relative;
/* 【修改点】移除了白色背景和内边距,让弹窗图片本身作为背景 */
background-color: transparent;
border-radius: 5px;
cursor: default;
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
}
.modal-image {
max-width: 80vw;
max-height: 80vh;
display: block;
}
/* 关闭按钮样式 */
.modal-close-button {
position: absolute;
top: 10px; /* 根据tanchuang.png的设计调整位置 */
right: 15px; /* 根据tanchuang.png的设计调整位置 */
font-size: 2.5rem;
color: #ccc; /* 调整颜色使其在弹窗图片上更清晰 */
cursor: pointer;
line-height: 1;
font-weight: bold;
transition: color 0.2s;
text-shadow: 0 0 5px black; /* 添加文字阴影使其更突出 */
}
.modal-close-button:hover {
color: #fff;
}
/* 原有样式 */
.mao-button {
/* 保留原有样式 */
transition: all 0.3s ease;