提交 0dac5ad6 authored 作者: huhuiqing's avatar huhuiqing

科技人物观点-概览页(地图样式待修改,部分按钮待添加)

上级 11282794
<!-- PersonNewsCard.vue -->
<template>
<div class="person-news-card">
<!-- 左侧:头像 -->
<div class="avatar">
<img :src="person.image_url" alt="人物头像" />
</div>
<!-- 事件列表 -->
<div class="events">
<!-- 头部区域 -->
<div class="header">
<!-- 右侧:信息 -->
<div class="info" style="display: flex; width: 100%; justify-content: space-between">
<div>
<h2>{{ person.name }}</h2>
<p class="title">{{ person.title }}</p>
</div>
<div class="source-tag">{{ source }}</div>
</div>
</div>
<div class="line"></div>
<div style="height: 289px; width: 688px">
<el-timeline style="margin-top: 14px">
<el-timeline-item placement="top" v-for="(activity, index) in events" :key="index" type="primary"
:hollow="true">
<template #dot>
<div style="
display: flex;
justify-content: space-between;
width: 688px;
text-align: center;
align-items: center;
margin-bottom: 12px;
">
<div style="display: flex">
<img src="../assets/images/dot1.png" alt="" style="width: 10px; height: 10px" />
<div style="
margin-left: 16px;
margin-top: -6px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
letter-spacing: 1px;
text-align: left;
">
{{ activity.date }}
</div>
</div>
<img src="../assets/images/dot2.png" alt="" style="width: 20px; height: 18px" />
</div>
</template>
{{ activity.content }}
</el-timeline-item>
</el-timeline>
</div>
<!-- <div v-for="(event, index) in events" :key="index" class="event-item">
<div class="event-date">{{ event.date }}</div>
<div class="event-content">
<span class="icon">{{ event.icon }}</span>
<span>{{ event.content }}</span>
</div>
</div> -->
</div>
</div>
</template>
<script>
// 导入数据
import data from "../json/personUpdates"; // 假设你把 JSON 存在 data.json 文件中
export default {
name: "PersonNewsCard",
data() {
return {
person: data.person,
events: data.events,
source: data.source
};
}
};
</script>
<style scoped>
.person-news-card {
width: 1016px;
height: 354px;
display: flex;
}
.header {
display: flex;
height: 73px;
}
.avatar {
/* 容器 552 */
width: 266px;
height: 352px;
}
.avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
.info h2 {
color: rgba(5, 95, 194, 1);
margin: 0;
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 0px;
text-align: left;
}
.info .title {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
margin-top: 4px;
}
.source-tag {
/* 数据展示/Tag标签/亮色/蓝 */
width: 100px;
height: 24px;
/* 自动布局 */
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 1px 6px 1px 6px;
box-sizing: border-box;
border: 1px solid rgba(135, 232, 222, 1);
border-radius: 4px;
background: rgba(230, 255, 251, 1);
color: rgba(19, 168, 168, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 20px;
letter-spacing: 0px;
text-align: left;
}
.line {
/* 矩形 277 */
width: 686px;
height: 1px;
background: rgba(234, 236, 238, 1);
}
.events {
margin-left: 24px;
width: 710px;
}
.event-item {
margin-bottom: 16px;
padding: 12px;
background-color: #fff;
border-left: 4px solid #007bff;
border-radius: 6px;
position: relative;
}
.event-date {
font-size: 0.85em;
color: #999;
margin-bottom: 8px;
display: inline-block;
}
.event-content {
display: flex;
align-items: flex-start;
line-height: 1.5;
}
.event-content .icon {
margin-right: 8px;
font-size: 1.2em;
color: #ff6b00;
vertical-align: middle;
}
.event-content span {
color: #333;
font-size: 0.95em;
}
:deep(.el-timeline) {
max-width: 688px !important;
padding: 0;
}
:deep(.el-timeline-item__wrapper) {
padding-left: 16px;
}
:deep(.el-timeline-item__timestamp.is-top) {
margin-bottom: 0;
padding-top: 0;
height: 12px;
}
:deep(.el-timeline-item__content) {
margin-left: 10px;
}
:deep(.el-timeline-item__wrapper) {
padding-top: 6px;
top: 0;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: justify;
}
</style>
<template>
<div class="person-table-container">
<!-- 表头 -->
<div class="table-header">
<div class="header-item" style="width: 332px;padding-left: 78px;">人物</div>
<div class="header-item" style="width: 197px;">涉华观点次数</div>
<div class="header-item" style="width: 209px;">主流媒体引用次数</div>
</div>
<!-- 表格内容 -->
<div class="table-body">
<div class="table-row" v-for="(item, index) in personList" :key="index">
<!-- 人物信息列 -->
<div class="row-col col-person">
<div style="margin: 7px 12px 7px 24px">
<img :src="item.avatar" class="avatar" alt="avatar" />
<div class="person-tags">
<div class="person-tag-bg" v-for="(tag, tIdx) in item.tags" :key="tIdx">
<img :src="'/public/icon/header-icon' + tag + '.png'" class="tag-icon" alt="tag" />
</div>
</div>
</div>
<div class="person-info">
<div class="person-name">{{ item.name }}</div>
<div class="person-position">{{ item.position }}</div>
</div>
</div>
<!-- 涉华观点次数列 -->
<div class="row-col col-count">
<el-progress :percentage="getProgress(item.mediaQuoteCount)" :show-text="false"
style="/* 矩形 244 */ width: 82px; height: 8px" :status="getStatus(getProgress(item.mediaQuoteCount))" />
<span class="count-text">{{ item.mediaQuoteCount }}</span>
</div>
<!-- 媒体引用次数列 -->
<div class="row-col col-count">
<el-progress :percentage="getProgress(item.mediaQuoteCount)" :show-text="false"
style="/* 矩形 244 */ width: 82px; height: 8px" :status="getStatus(getProgress(item.mediaQuoteCount))" />
<span class="count-text">{{ item.mediaQuoteCount }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import personData from "../json/personData.json"; // 引入JSON数据
const personList = ref(personData);
// 进度条状态
const getStatus = _percent => {
const percent = _percent;
if (percent >= 90) {
return "exception";
} else if (percent >= 50) {
return "warning";
} else {
return "success";
}
};
// 计算进度条宽度(基于最大值的百分比)
const getMaxCount = () => {
const counts = personList.value.flatMap(item => [item.chinaRelatedCount, item.mediaQuoteCount]);
return Math.max(...counts);
};
const getProgress = count => (count / getMaxCount()) * 100;
</script>
<style scoped>
.person-table-container {
width: 738px;
height: 360px;
margin: 24px 27px;
font-family: "Microsoft YaHei", sans-serif;
}
/* 表头样式 */
.table-header {
/* 容器 47 */
display: flex;
width: 738px;
height: 60px;
box-sizing: border-box;
border-top: 1px solid rgba(230, 231, 232, 1);
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 22px;
letter-spacing: 0px;
align-items: center;
text-align: center;
}
.header-item {
/* flex: 1; */
text-align: left;
}
/* 表格内容样式 */
.table-body {
/* background-color: #fff; */
}
.table-row {
display: flex;
align-items: center;
padding: 0;
/* 容器 92 */
width: 738px;
height: 60px;
}
.table-body .table-row:nth-of-type(odd) {
background-color: rgba(247, 248, 249, 1);
}
.table-body .table-row:nth-of-type(even) {
background-color: #ffffff;
}
.row-col {
flex: 1;
display: flex;
align-items: center;
}
/* 人物列样式 */
.col-person {
align-items: flex-start;
}
.avatar {
/* 椭圆形 */
width: 42px;
height: 42px;
border-radius: 50%;
object-fit: cover;
}
.person-info {
display: flex;
flex-direction: column;
}
.person-name {
margin-top: 5px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
.person-position {
width: 253px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
.person-tags {
display: flex;
margin-top: -20px;
width: 42px;
text-align: center;
}
.person-tag-bg {
/* 椭圆 6 */
width: 20px;
height: 20px;
background: rgba(255, 255, 255, 0.8);
border-radius: 50%;
}
.tag-icon {
width: 16px;
height: 16px;
object-fit: contain;
}
/* 次数列样式 */
.col-count {
gap: 11px;
}
.progress-bar {
height: 8px;
border-radius: 4px;
background-color: #ccc;
min-width: 20px;
}
.count-text {
font-size: 14px;
color: #333;
white-space: nowrap;
}
</style>
<!-- SourceLibrary.vue -->
<template>
<div class="source-library-container">
<div class="source-library-grid">
<div v-for="(item, index) in sourceLibraryData" :key="index" class="source-library-card">
<div class="source-library-avatar-wrapper">
<img :src="item.avatar" alt="" class="source-library-avatar" />
</div>
<div class="source-library-text-content">
<div style=" width: 240px;">
<h3 class="source-library-name">{{ item.name }}</h3>
<p class="source-library-title">{{ item.title }}</p>
<p class="source-library-tag" :style="{
background: item.colorArray[2],
color: item.colorArray[0],
borderColor: item.colorArray[1],
}">{{ item.tag }}</p>
</div>
</div>
</div>
</div>
<div class="page">
<div class="count">共1205项调查</div>
<el-pagination v-model:current-page="currentPage" :page-size="pageSize" :total="total" layout="prev, pager, next"
background @current-change="handlePageChange" />
</div>
</div>
</template>
<script setup>
// 导入数据(建议使用更具语义的变量名)
import sourceLibraryData from '../json/source.json';
import { ref } from 'vue'
const total = ref(1205);
const pageSize = ref(121);
const currentPage = ref(5);
const handlePageChange = p => {
currentPage.value = p;
};
</script>
<style scoped>
.source-library-container {
width: 1530px;
margin: 0;
}
.source-library-grid {
width: 1600px;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px 16px;
}
.source-library-card {
width: 388px;
height: 160px;
box-sizing: border-box;
display: flex;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: var(---10, 10px);
padding: 20px 18px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
}
.source-library-card:hover {
transform: translateY(-2px);
}
.source-library-avatar-wrapper {
flex-shrink: 0;
margin-right: 18px;
}
.source-library-avatar {
/* 椭圆 142 */
width: 88px;
height: 88px;
border-radius: 50%;
}
.source-library-text-content {
width: 656px;
flex: 1;
}
.source-library-name {
color: rgba(59, 65, 75, 1);
margin: 0;
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 0px;
text-align: left;
}
.source-library-title {
width: 240px;
height: 48px;
color: rgba(59, 65, 75, 1);
margin: 11px 0 14px 0;
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
.source-library-tag {
/* width: 72px; */
height: 22px;
/* 自动布局 */
display: inline-block;
/* 关键:把块级盒子变成行内块 */
align-items: center;
padding: 1px 8px 1px 8px;
box-sizing: border-box;
border: 1px solid rgba(255, 229, 143, 1);
border-radius: 4px;
background: rgba(255, 251, 230, 1);
color: rgba(22, 119, 255, 1);
margin: 0;
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 20px;
letter-spacing: 0px;
text-align: left;
}
.page {
width: 1221px;
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
margin: 36px 0 0 0;
padding-left: 11px;
.count {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
}
:deep(.el-pagination) {
display: flex;
align-items: center;
}
:deep(.el-pagination.is-background .el-pager li) {
min-width: 32px;
height: 32px;
line-height: 32px;
border-radius: 6px;
margin: 0 6px;
border: 1px solid rgba(0, 0, 0, 0.15);
background-color: #fff;
color: rgb(95, 101, 108);
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
}
:deep(.el-pagination.is-background .el-pager li.is-active) {
background-color: #fff;
color: rgba(22, 119, 255, 1);
border-color: rgba(22, 119, 255, 1);
}
:deep(.el-pagination.is-background .el-pager li.is-ellipsis) {
border: none;
background-color: transparent;
color: rgb(95, 101, 108);
min-width: 16px;
margin: 0 6px;
}
:deep(.el-pagination.is-background .btn-prev),
:deep(.el-pagination.is-background .btn-next) {
min-width: 32px;
height: 32px;
border-radius: 6px;
border: 1px solid rgba(0, 0, 0, 0.15);
background-color: #fff;
color: rgb(95, 101, 108);
font-size: 16px;
font-family: "Microsoft YaHei";
margin: 0 6px;
}
:deep(.el-pagination.is-background .btn-prev.is-disabled),
:deep(.el-pagination.is-background .btn-next.is-disabled) {
color: rgba(95, 101, 108, 0.45);
border-color: rgb(235, 238, 242);
background-color: #fff;
}
</style>
\ No newline at end of file
<template>
<div class="timeline-map">
<!-- 地图容器 -->
<div ref="chartRef" style="width: 100%; height: 600px;"></div>
<!-- 控制栏 -->
<div class="controls" style="margin-top: 16px; text-align: center;">
<button @click="play" :disabled="isPlaying">播放</button>
<button @click="pause" :disabled="!isPlaying">暂停</button>
<span style="margin: 0 16px;">速度:</span>
<input type="range" min="0.5" max="3" step="0.5" v-model.number="speed" />
<span>{{ speed }}x</span>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue';
import * as echarts from 'echarts/core';
import { CanvasRenderer } from 'echarts/renderers';
import { GeoComponent } from 'echarts/components';
import { ScatterChart } from 'echarts/charts';
import { TooltipComponent } from 'echarts/components';
// 注册必要组件
echarts.use([CanvasRenderer, GeoComponent, ScatterChart, TooltipComponent]);
// 导入中国地图 GeoJSON
import chinaJson from '@/assets/json/China.json';
// 事件数据(模拟)
const events = [
{
date: '2024-09-23',
desc: '在北京会见科技企业代表',
avatar: 'https://via.placeholder.com/32?text=BJ',
lng: 116.4074,
lat: 39.9042 // 北京
},
{
date: '2024-09-24',
desc: '在上海考察集成电路产业',
avatar: 'https://via.placeholder.com/32?text=SH',
lng: 121.4737,
lat: 31.2304 // 上海
},
{
date: '2024-09-25',
desc: '在深圳调研人工智能发展',
avatar: 'https://via.placeholder.com/32?text=SZ',
lng: 114.0579,
lat: 22.5431 // 深圳
},
{
date: '2024-09-26',
desc: '在成都出席科技创新论坛',
avatar: 'https://via.placeholder.com/32?text=CD',
lng: 104.0665,
lat: 30.5728 // 成都
}
];
// 响应式状态
const chartRef = ref(null);
const currentIndex = ref(0);
const isPlaying = ref(false);
const speed = ref(1);
let intervalId = null;
let myChart = null;
// 初始化图表
onMounted(() => {
// 注册中国地图(关键!)
echarts.registerMap('China', chinaJson);
myChart = echarts.init(chartRef.value);
const option = getOption();
myChart.setOption(option);
});
onUnmounted(() => {
if (intervalId) clearInterval(intervalId);
if (myChart) myChart.dispose();
});
// 获取 ECharts 配置
function getOption() {
return {
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(255,255,255,0.9)',
borderColor: '#ccc',
borderRadius: 6,
textStyle: { color: '#333', fontSize: 12 },
formatter(params) {
const data = params.data;
return `
<div style="padding:8px; line-height:1.4;">
<img src="${data.avatar}" width="24" height="24" style="border-radius:50%; vertical-align:middle; margin-right:6px;" />
<strong>${data.date}</strong><br/>
${data.desc}
</div>
`;
}
},
geo: {
map: 'China', // 使用注册的地图名
roam: true,
zoom: 1.2,
center: [105, 35], // 中国大致中心
label: {
show: false
},
itemStyle: {
areaColor: '#f0f9ff',
borderColor: '#a0cfff'
},
emphasis: {
itemStyle: {
areaColor: '#e6f7ff'
}
}
},
series: [
{
type: 'scatter',
coordinateSystem: 'geo',
data: getCurrentData(),
symbolSize: 12,
itemStyle: {
color: '#1890ff'
},
label: {
show: false
}
}
]
};
}
// 获取当前要显示的数据
function getCurrentData() {
return [events[currentIndex.value]];
}
// 播放
function play() {
if (isPlaying.value) return;
isPlaying.value = true;
intervalId = setInterval(() => {
currentIndex.value = (currentIndex.value + 1) % events.length;
myChart.setOption({
series: [{ data: getCurrentData() }]
});
}, 1000 / speed.value);
}
// 暂停
function pause() {
if (!isPlaying.value) return;
isPlaying.value = false;
clearInterval(intervalId);
intervalId = null;
}
// 监听速度变化
watch(speed, () => {
if (isPlaying.value) {
pause();
play();
}
});
</script>
<style scoped>
.controls button {
margin: 0 8px;
padding: 6px 12px;
font-size: 14px;
}
</style>
\ No newline at end of file
<!-- SpeechStance.vue -->
<template>
<div class="speech-stance-container">
<div class="speech-stance-grid">
<div v-for="(item, index) in speechStance" :key="index" class="speech-stance-card">
<div class="speech-stance-avatar-wrapper">
<img :src="item.avatar" alt="" class="speech-stance-avatar" />
</div>
<div class="speech-stance-text-content">
<div style="display: flex; width: 683px;">
<h3 class="speech-stance-name">{{ item.name }}</h3>
<p class="speech-stance-title">{{ item.title }}</p>
</div>
<p class="speech-stance-content">{{ item.content }}</p>
</div>
</div>
</div>
</div>
</template>
<script setup>
// 导入数据
import speechStance from '../json/speechStance.json';
</script>
<style scoped>
.speech-stance-container {
width: 1530px;
/* max-width: 900px; */
margin: 0 auto;
margin: 5px 35px;
}
.speech-stance-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 30px 9px;
}
/* 响应式:小屏变一列 */
@media (max-width: 768px) {
.speech-stance-grid {
grid-template-columns: 1fr;
}
}
.speech-stance-card {
/* 容器 553 */
width: 768px;
height: 50px;
display: flex;
}
.speech-stance-avatar-wrapper {
flex-shrink: 0;
}
.speech-stance-avatar {
/* 椭圆 141 */
width: 48px;
height: 48px;
border-radius: 50%;
}
.speech-stance-text-content {
width: 656px;
flex: 1;
margin-left: 13px;
}
.speech-stance-name {
color: rgba(34, 41, 52, 1);
margin: 0;
font-family: Microsoft YaHei;
font-size: 18px;
font-weight: 700;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
.speech-stance-title {
color: rgba(95, 101, 108, 1);
margin: 0;
margin-left: 12px;
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
.speech-stance-content {
color: rgba(95, 101, 108, 1);
margin: 0;
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: left;
white-space: nowrap;
/* 禁止换行 */
overflow: hidden;
/* 隐藏溢出内容 */
text-overflow: ellipsis;
/* 溢出部分显示省略号 */
}
</style>
\ No newline at end of file
[
{
"name": "唐纳德·特朗普",
"position": "参议院情报委员会主席",
"avatar": "/public/testData/data2.png",
"tags": ["1", "2"],
"chinaRelatedCount": 129,
"mediaQuoteCount": 1140,
"color": "#C82333"
},
{
"name": "汤姆·科顿",
"position": "参议院情报委员会主席",
"avatar": "/public/testData/data2.png",
"tags": ["1", "2"],
"chinaRelatedCount": 47,
"mediaQuoteCount": 203,
"color": "#FD7E14"
},
{
"name": "马尔科·卢比奥",
"position": "国务卿",
"avatar": "/public/testData/data2.png",
"tags": ["1", "2"],
"chinaRelatedCount": 34,
"mediaQuoteCount": 180,
"color": "#FFC107"
},
{
"name": "詹姆斯·戴维·万斯",
"position": "副总统",
"avatar": "/public/testData/data2.png",
"tags": ["1", "2"],
"chinaRelatedCount": 25,
"mediaQuoteCount": 129,
"color": "#28A745"
},
{
"name": "克丽斯蒂·诺姆",
"position": "国土安全部部长",
"avatar": "/public/testData/data2.png",
"tags": ["1", "2"],
"chinaRelatedCount": 22,
"mediaQuoteCount": 101,
"color": "#28A745"
}
]
{
"person": {
"name": "黄仁勋",
"title": "NVIDIA公司创始人及首席执行官",
"image_url": "/public/testData/data1.png"
},
"events": [
{
"date": "2025-08-15",
"content": "承认美国对华芯片管制导致英伟达在华份额近半、损失150亿美元销售额,并警告若制裁继续,第二季度将再损失80亿美元收入。",
"icon": "🔥"
},
{
"date": "2025-08-15",
"content": "英伟达创始人兼 CEO 黄仁勋在上周四举行的全体员工大会上表示,希望员工在可能的情况下多使用 AI,并强调员工对此不必有疑虑。",
"icon": "🔥"
},
{
"date": "2025-08-15",
"content": "NVIDIA首席执行官黄仁勋近日在英国剑桥大学获颁2025年‘史蒂芬·霍金教授院士奖’,成为首位获此殊荣的半导体企业领袖。",
"icon": "🔥"
}
],
"source": "科技企业领袖"
}
[
{
"name": "唐纳德·特朗普",
"title": "美国总统(2017-2021、2025-至今),共和党党员",
"tag": "行政主管",
"avatar": "/public/testData/data2.png",
"colorArray": ["#1677FF", "#BAE0FF", "#E6F4FF"]
},
{
"name": "詹姆斯·戴维·万斯",
"title": "美国副总统、参议院议长、共和党全国委员会财务主席",
"tag": "行政主管",
"avatar": "/public/testData/data2.png",
"colorArray": ["#1677FF", "#BAE0FF", "#E6F4FF"]
},
{
"name": "黄仁勋",
"title": "NVIDIA公司创始人兼首席执行官,美国工程院院士",
"tag": "科技企业领袖",
"avatar": "/public/testData/data2.png",
"colorArray": ["#13A8A8", "#87E8DE", "#E6FFFFB"]
},
{
"name": "马尔科·鲁比奥",
"title": "美国国务卿,美国总统国家安全事务临时助理",
"tag": "行政主管",
"avatar": "/public/testData/data2.png",
"colorArray": ["#1677FF", "#BAE0FF", "#E6F4FF"]
},
{
"name": "埃隆·马斯克",
"title": "特斯拉创始人兼首席执行官、SpaceX、美国党创始人",
"tag": "科技企业领袖",
"avatar": "/public/testData/data2.png",
"colorArray": ["#13A8A8", "#87E8DE", "#E6FFFFB"]
},
{
"name": "乔迪·阿灵顿",
"title": "共和党党员,美国国会众议院议员,预算委员会主席",
"tag": "国会议员",
"avatar": "/public/testData/data2.png",
"colorArray": ["#FAAD14", "#FFE58F", "#FFFBE6"]
},
{
"name": "霍华德·卢特尼克",
"title": "美国商务部长",
"tag": "行政主管",
"avatar": "/public/testData/data2.png",
"colorArray": ["#1677FF", "#BAE0FF", "#E6F4FF"]
},
{
"name": "蒂姆·库克",
"title": "苹果公司首席执行官,清华大学经济管理学院顾问委员会主席",
"tag": "科技企业领袖",
"avatar": "/public/testData/data2.png",
"colorArray": ["#13A8A8", "#87E8DE", "#E6FFFFB"]
},
{
"name": "朱棣文",
"title": "第12任美国能源部部长,主要研究领域为原子物理、激光科学",
"tag": "顶级科学家",
"avatar": "/public/testData/data2.png",
"colorArray": ["#722ED1", "#D3ADF7", "#F9F0FF"]
},
{
"name": "约翰·图恩",
"title": "共和党党员,美国国会众议院议员",
"tag": "国会议员",
"avatar": "/public/testData/data2.png",
"colorArray": ["#FAAD14", "#FFE58F", "#FFFBE6"]
},
{
"name": "珍妮弗·道德纳",
"title": "主要研究领域为RNA领域和基因编辑技术",
"tag": "顶级科学家",
"avatar": "/public/testData/data2.png",
"colorArray": ["#722ED1", "#D3ADF7", "#F9F0FF"]
},
{
"name": "迈克·约翰逊",
"title": "美国众议院议长",
"tag": "国会议员",
"avatar": "/public/testData/data2.png",
"colorArray": ["#FAAD14", "#FFE58F", "#FFFBE6"]
},
{
"name": "亚当·史密斯",
"title": "美国国会众议院议员,众议院军事委员会民主党领袖",
"tag": "国会议员",
"avatar": "/public/testData/data2.png",
"colorArray": ["#FAAD14", "#FFE58F", "#FFFBE6"]
},
{
"name": "查尔斯·本内特",
"title": "美国国家科学院院士、美国物理学会院士,量子信息论主要创立者",
"tag": "顶级科学家",
"avatar": "/public/testData/data2.png",
"colorArray": ["#722ED1", "#D3ADF7", "#F9F0FF"]
},
{
"name": "桑达尔·皮查伊",
"title": "谷歌母公司Alphabet首席执行官",
"tag": "科技企业领袖",
"avatar": "/public/testData/data2.png",
"colorArray": ["#13A8A8", "#87E8DE", "#E6FFFFB"]
},
{
"name": "威康·汤姆逊",
"title": "美国国家科学院院士、美国物理学会院士,量子信息论主要创立者",
"tag": "顶级科学家",
"avatar": "/public/testData/data2.png",
"colorArray": ["#722ED1", "#D3ADF7", "#F9F0FF"]
}
]
[
{
"name": "黄仁勋",
"title": "NVIDIA公司创始人及首席执行官",
"avatar": "/public/testData/data2.png",
"content": "宣布美国政府已批准H20芯片销往中国,并表示“中国AI市场无论有没有英伟达都会进步”。"
},
{
"name": "斯里拉姆·克里希南",
"title": "白宫人工智能高级政策顾问",
"avatar": "/public/testData/data2.png",
"content": "声称特朗普政府会继续阻止中国获取先进AI技术,但将重新审视对主要贸易伙伴的限制。"
},
{
"name": "大卫·萨克斯",
"title": "白宫人工智能与加密货币主管",
"avatar": "/public/testData/data2.png",
"content": "为允许英伟达出口H20芯片辩护,称此举有助于美国同中国有效竞争为允许英伟达出口H20芯片辩护,称此举有助于美国同中国有效竞争。。"
},
{
"name": "霍华德·卢特尼克",
"title": "美国商务部长",
"avatar": "/public/testData/data2.png",
"content": "解释对华芯片出口策略是只卖“第四好”的芯片(如H20),让中国开发者依赖美国技术生态系统。"
},
{
"name": "斯科特·贝森特",
"title": "美国财政部长",
"avatar": "/public/testData/data2.png",
"content": "将H20芯片的出口管制描述为中美贸易谈判中的“平衡筹码”。"
},
{
"name": "斯里拉姆·克里希南",
"title": "白宫人工智能高级政策顾问",
"avatar": "/public/testData/data2.png",
"content": "声称特朗普政府会继续阻止中国获取先进AI技术,但将重新审视对主要贸易伙伴的限制。"
},
{
"name": "大卫·萨克斯",
"title": "白宫人工智能与加密货币主管",
"avatar": "/public/testData/data2.png",
"content": "为允许英伟达出口H20芯片辩护,称此举有助于美国同中国有效竞争。"
},
{
"name": "霍华德·卢特尼克",
"title": "美国商务部长",
"avatar": "/public/testData/data2.png",
"content": "解释对华芯片出口策略是只卖“第四好”的芯片(如H20),让中国开发者依赖美国技术生态系统。"
},
{
"name": "斯科特·贝森特",
"title": "美国财政部长",
"avatar": "/public/testData/data2.png",
"content": "将H20芯片的出口管制描述为中美贸易谈判中的“平衡筹码”。"
}
]
// donutChart.js
import * as echarts from 'echarts';
/**
* 环形图(donut / pie)
* @param {Array<string>} nameList 名称数组
* @param {Array<number>} valueList 数值数组
* @returns {Object} echarts option
*/
const getDonutChart = (nameList, valueList) => {
// 使用与折线图一致的配色(6色,取前5个)
const colors = [
'#87E8DE', // 原“集成电路”青绿 → 可替换为更协调色
'#69B1FF', // 浅蓝
'#FF7875', // 红
'#B37FEB', // 紫
'#FFD666' // 新增黄色,用于第5项(避免重复)
];
const data = nameList.map((name, i) => ({
name,
value: valueList[i]
}));
return {
color: colors,
tooltip: { trigger: "item", formatter: ({ name, value, percent }) => `${name}<br/>${value}${percent}%` },
series: [
{
type: "pie",
radius: [96, 120],
center: ["50%", "50%"],
avoidLabelOverlap: true,
itemStyle: { borderWidth: 0 },
label: {
show: true,
position: "outside",
alignTo: "edge",
formatter: ({ name, value, percent }) => `{name|${name}} {value|${value}项} {percent|${percent}%}`,
minMargin: 50,
edgeDistance: 10,
lineHeight: 15,
rich: {
name: {
fontSize: 16,
fontFamily: "Microsoft YaHei",
fontWeight: 700,
lineHeight: 24,
color: "rgb(59, 65, 75)"
},
value: {
fontSize: 14,
fontFamily: "Microsoft YaHei",
fontWeight: 400,
lineHeight: 22,
color: "rgb(95, 101, 108)"
},
percent: {
fontSize: 14,
fontFamily: "Microsoft YaHei",
fontWeight: 400,
lineHeight: 22,
color: "rgb(95, 101, 108)"
}
}
},
labelLine: {
show: true,
length: 30,
length2: 0,
maxSurfaceAngle: 80
},
labelLayout: function (params) {
const isLeft = params.labelRect.x < 380;
const points = params.labelLinePoints;
// 导航线终点在标签下方
const lineY = params.labelRect.y + params.labelRect.height;
points[2][0] = isLeft ? params.labelRect.x : params.labelRect.x + params.labelRect.width;
points[2][1] = lineY;
points[1][1] = lineY;
return {
labelLinePoints: points
};
},
data: data.map((d, i) => ({
...d,
labelLine: { lineStyle: { color: colors[i], width: 1 } }
}))
}
]
};
};
export default getDonutChart;
\ No newline at end of file
import * as echarts from 'echarts'
import * as echarts from "echarts";
const getMultiLineChart = (dataX, dataY1, dataY2, dataY3) => {
const getMultiLineChart = (dataX, dataY1, dataY2, dataY3, dataY4, dataY5, dataY6) => {
return {
tooltip: {
trigger: 'axis',
trigger: "axis",
axisPointer: {
type: 'cross',
type: "cross",
label: {
backgroundColor: '#6a7985'
backgroundColor: "#6a7985"
}
}
},
grid: {
top: '15%',
right: '5%',
bottom: '5%',
left: '5%',
top: "15px",
right: "50px",
bottom: "0px",
left: "40px",
containLabel: true
},
legend: {
data: ["人工智能", "集成电路", "量子科技", "生物科技", "通信网络", "能源"],
show: true,
top: 10,
left:'5%'
textStyle: {
color: "rgba(95, 101, 108, 1)",
fontFamily: "Microsoft YaHei",
fontSize: "16px"
}, // 设置图例标记为圆形
icon: "circle",
itemWidth: 10, // 圆的直径
itemHeight: 10, // 圆的直径
itemGap: 20 // 图例项之间的间距
},
color: ['#0A57A6', '#FA8C16','#722ED1'],
color: [
"rgba(10, 87, 166, 1)", // 人工智能(深蓝色)
"rgba(64, 196, 181, 1)", // 集成电路(青绿色)
"rgba(114, 46, 209, 1)", // 量子科技(紫色)
"rgba(245, 141, 46, 1)", // 生物科技(橙色)
"rgba(111, 180, 255, 1)", // 通信网络(浅蓝色)
"rgba(196, 92, 68, 1)" // 能源(红褐色)
],
xAxis: [
{
type: 'category',
type: "category",
boundaryGap: false,
data: dataX
data: dataX,
axisLabel: {
fontSize: 14 // 设置X轴字体大小
}
}
],
yAxis: [
{
type: 'value'
type: "value",
splitLine: {
show: true,
lineStyle: {
type: "dashed",
color: "#E7F3FF"
}
},
axisLabel: {
fontSize: 14 // 设置X轴字体大小
},
}
],
series: [
{
name: '337调查',
type: 'line',
name: "人工智能",
type: "line",
lineStyle: {
width: 1.5 // 单位:px,数值越大线条越粗
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(10, 87, 166, 0.7)' // 起始颜色
}, {
offset: 1,
color: 'rgba(10, 87, 166, 0)' // 结束颜色
}])
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(10, 87, 166, 0.2)" // 起始颜色
},
{
offset: 1,
color: "rgba(10, 87, 166, 0)" // 结束颜色
}
])
},
emphasis: {
focus: 'series'
focus: "series"
},
data: dataY1
},
{
name: '301调查',
type: 'line',
name: "集成电路",
type: "line",
lineStyle: {
width: 1.5 // 单位:px,数值越大线条越粗
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(255, 172, 77, 0.7)' // 起始颜色
}, {
offset: 1,
color: 'rgba(255, 172, 77, 0)' // 结束颜色
}])
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(64, 196, 181, 0.2)" // 起始颜色
},
{
offset: 1,
color: "rgba(64, 196, 181, 0)" // 结束颜色
}
])
},
emphasis: {
focus: 'series'
focus: "series"
},
data: dataY2
},
{
name: '232调查',
type: 'line',
name: "量子科技",
type: "line",
lineStyle: {
width: 1.5 // 单位:px,数值越大线条越粗
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(114, 46, 209, 0.7)' // 起始颜色
}, {
offset: 1,
color: 'rgba(114, 46, 209, 0)' // 结束颜色
}])
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(114, 46, 209, 1)" // 起始颜色
},
{
offset: 1,
color: "rgba(114, 46, 209, 0)" // 结束颜色
}
])
},
emphasis: {
focus: 'series'
focus: "series"
},
data: dataY3
},
{
name: "生物科技",
type: "line",
lineStyle: {
width: 1.5 // 单位:px,数值越大线条越粗
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(245, 141, 46, 0.2)" // 起始颜色
},
{
offset: 1,
color: "rgba(245, 141, 46, 0)" // 结束颜色
}
])
},
emphasis: {
focus: "series"
},
data: dataY4
},
{
name: "通信网络",
type: "line",
lineStyle: {
width: 1.5 // 单位:px,数值越大线条越粗
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(111, 180, 255, 0.2)" // 起始颜色
},
{
offset: 1,
color: "rgba(111, 180, 255, 0)" // 结束颜色
}
])
},
emphasis: {
focus: "series"
},
data: dataY5
},
{
name: "能源",
type: "line",
lineStyle: {
width: 1.5 // 单位:px,数值越大线条越粗
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(196, 92, 68, 0.2)" // 起始颜色
},
{
offset: 1,
color: "rgba(196, 92, 68, 0)" // 结束颜色
}
])
},
emphasis: {
focus: "series"
},
data: dataY6
}
]
}
}
};
};
export default getMultiLineChart
\ No newline at end of file
export default getMultiLineChart;
const getWordCloudChart = (data) => {
const option = {
grid: {
left: 0,
top: 0,
right: 0,
bottom: 0,
},
series: [
{
type: "wordCloud",
shape: "rect", //
// 其他形状你可以使用形状路径
// 或者自定义路径
// shape: 'circle' // 圆形(默认)
// shape: 'rect' // 矩形
// shape: 'roundRect' // 圆角矩形
// shape: 'triangle' // 三角形
// shape: 'diamond' // 菱形
// shape: 'pentagon' // 五边形
// shape: 'star' // 星形
// shape: 'cardioid' // 心形
gridSize: 20, // 网格大小,影响词间距。
sizeRange: [18, 32], // 定义词云中文字大小的范围
rotationRange: [0, 0],
rotationStep: 10,
drawOutOfBound: false, // 是否超出画布
// 字体
textStyle: {
normal: {
fontWeight: 'bold', // 字体加粗
// color: function () {
// return 'rgb(' + [
// Math.round(Math.random() * 160),
// Math.round(Math.random() * 160),
// Math.round(Math.random() * 160)
// ].join(',') + ')';
// }
},
color: function () {
let colors = [
"rgba(189, 33, 33, 1)",
"rgba(232, 151, 21, 1)",
"rgba(220, 190, 68, 1)",
"rgba(96, 58, 186, 1)",
"rgba(32, 121, 69, 1)",
"rgba(22, 119, 255, 1)",
];
return colors[parseInt(Math.random() * colors.length)];
},
emphasis: {
shadowBlur: 10,
shadowColor: '#333'
}
},
// 设置词云数据
data: data,
},
],
}
return option
}
export default getWordCloudChart
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论