提交 d3de03db authored 作者: 李智林's avatar 李智林

“人物主页12个页面”

上级 71ef59ba
// 人物主页
import CharacterPage from "@/views/characterPage/index.vue";
const characterPageRoutes = [
// 人物主页
{
// 根据不同的type跳转到不同的页面,type=1为科技领袖,2为国会议员,3为智库研究人员
path: "/characterPage/:type?",
name: "CharacterPage",
component: CharacterPage,
meta: {
title: "人物主页"
}
}
]
export default characterPageRoutes
<template>
<div class="character-relationships">
<div class="headerBox">
<span
v-for="(item, index) in list"
:key="index"
class="headerItem"
:class="{ active: item === activeIndex }"
@click="activeIndex = item"
>{{ item }}</span
>
</div>
<div class="headerBtnBox"><img src="./assets/下载按钮.png" alt="" /><img src="./assets/收藏按钮.png" alt="" /></div>
<!-- 主要内容,人物关系图 -->
<div class="mainBox">
<div class="graph" id="relGraph"></div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from "vue";
import * as echarts from "echarts";
import Center from "./assets/约翰·伦道夫·图恩.png";
import P1 from "./assets/唐纳德·特朗普.png";
import P2 from "./assets/约翰·巴拉索.png";
import P3 from "./assets/布里顿·图恩.png";
import P4 from "./assets/金伯利·韦姆斯·图恩.png";
import P5 from "./assets/乔治·S·米克尔森.png";
import P6 from "./assets/哈罗德·理查德·图恩.png";
import P7 from "./assets/伊冯娜·帕特里夏·图恩.png";
import P8 from "./assets/蒂姆·约翰逊.png";
import P9 from "./assets/吉姆·阿布德诺.png";
import P10 from "./assets/汤姆·达施勒.png";
import P11 from "./assets/拉里莎·图恩.png";
import PS from "./assets/拉里·普雷斯勒.png";
const list = ref(["圆形布局", "力导向布局", "树形布局"]);
const activeIndex = ref("圆形布局");
const nodes = [
{
id: "c",
name: "约翰·伦道夫·图恩",
category: 0,
symbolSize: 80,
symbol: `image://${Center}`,
label: {
show: true,
position: "bottom",
formatter: "{n|约翰·伦道夫·图恩}",
rich: {
n: {
color: "rgba(5,95,194,1)",
fontSize: 24,
fontWeight: 700,
fontFamily: "Microsoft YaHei",
lineHeight: 36
}
}
}
},
// 从三点钟方向顺时针排序
{ id: "n11", name: "拉里莎·图恩", category: 1, symbolSize: 80, symbol: `image://${P11}` },
{ id: "n7", name: "伊冯娜·帕特里夏·图恩", category: 1, symbolSize: 80, symbol: `image://${P7}`, r: 80 },
{ id: "n6", name: "哈罗德·理查德·图恩", category: 1, symbolSize: 80, symbol: `image://${P6}` },
{ id: "n9", name: "吉姆·阿布德诺", category: 1, symbolSize: 80, symbol: `image://${P9}` },
{ id: "n12", name: "拉里·普雷斯勒", category: 1, symbolSize: 80, symbol: `image://${PS}` },
{ id: "n5", name: "乔治·S·米克尔森", category: 1, symbolSize: 80, symbol: `image://${P5}`, r: 80 },
{ id: "n8", name: "蒂姆·约翰逊", category: 1, symbolSize: 80, symbol: `image://${P8}` },
{ id: "n10", name: "汤姆·达施勒", category: 1, symbolSize: 80, symbol: `image://${P10}`, r: 80 },
{ id: "n2", name: "约翰·巴拉索", category: 1, symbolSize: 80, symbol: `image://${P2}` },
{ id: "n1", name: "唐纳德・特朗普", category: 1, symbolSize: 80, symbol: `image://${P1}` },
{ id: "n4", name: "金伯利·韦姆斯·图恩", category: 1, symbolSize: 80, symbol: `image://${P4}` },
{ id: "n3", name: "布里顿·图恩", category: 1, symbolSize: 80, symbol: `image://${P3}`, r: 80 }
];
const links = [
{ source: "n11", target: "c", label: { show: true, formatter: "次女" } },
{ source: "n7", target: "c", label: { show: true, formatter: "母亲" } },
{ source: "n6", target: "c", label: { show: true, formatter: "父亲" } },
{ source: "n9", target: "c", label: { show: true, formatter: "" } },
{ source: "n12", target: "c", label: { show: true, formatter: "盟友" } },
{ source: "n5", target: "c", label: { show: true, formatter: "前南达科他州州长" } },
{ source: "n8", target: "c", label: { show: true, formatter: "政治对手" } },
{ source: "n10", target: "c", label: { show: true, formatter: "政治对手" } },
{ source: "n2", target: "c", label: { show: true, formatter: "亲密盟友" } },
{ source: "n1", target: "c", label: { show: true, formatter: "政治盟友" } },
{ source: "n4", target: "c", label: { show: true, formatter: "妻子" } },
{ source: "n3", target: "c", label: { show: true, formatter: "长女" } }
];
let chart;
onMounted(() => {
const el = document.getElementById("relGraph");
if (!el) return;
chart = echarts.init(el);
const setOption = () => {
const rect = el.getBoundingClientRect();
const cx = rect.width / 2;
const cy = rect.height / 2;
const radius = Math.min(cx, cy) - 140;
const dataNodes = nodes.map((n, i) => {
if (n.id === "c") {
return { ...n, x: cx, y: cy, fixed: true };
}
// 均匀环形分布
const idx = i - 1;
const angle = (idx / (nodes.length - 1)) * Math.PI * 2;
const rLocal = radius + (n.r || 0);
const x = cx + rLocal * Math.cos(angle);
const y = cy + rLocal * Math.sin(angle);
return { ...n, x, y };
});
chart.setOption({
tooltip: {},
series: [
{
type: "graph",
layout: activeIndex.value === "圆形布局" ? "none" : "force",
circular: { rotateLabel: true },
force: { repulsion: 800, edgeLength: [80, 160] },
roam: true,
data: activeIndex.value === "圆形布局" ? dataNodes : nodes,
links: links,
edgeSymbol: ["none", "arrow"],
edgeSymbolSize: [4, 10],
lineStyle: { color: "rgba(174,214,255,1)", width: 2, opacity: 0.8 },
edgeLabel: {
show: true,
position: "middle",
distance: -18,
formatter: ({ data }) => data?.label?.formatter || "",
color: "rgb(5, 95, 194)",
fontSize: 12,
fontWeight: 400,
fontFamily: "Microsoft YaHei",
lineHeight: 24,
backgroundColor: "rgba(231, 243, 255, 1)",
borderRadius: 24,
padding: [0, 12]
},
label: { show: true, position: "bottom", color: "rgb(59,65,75)", fontSize: 16 },
itemStyle: { color: "rgba(5,95,194,1)" },
emphasis: { focus: "adjacency" }
}
]
});
};
setOption();
const onResize = () => chart && chart.resize();
window.addEventListener("resize", onResize);
watch(activeIndex, () => setOption());
onBeforeUnmount(() => {
window.removeEventListener("resize", onResize);
chart && chart.dispose();
});
});
</script>
<style lang="scss" scoped>
* {
padding: 0;
margin: 0;
}
.character-relationships {
width: 1600px;
height: 688px;
background-color: #fff;
margin: 0 auto;
position: relative;
border-radius: 4px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
.headerBox {
position: absolute;
top: 14px;
right: 96px;
.headerItem {
padding: 1px 8px;
border-radius: 4px;
font-size: 16px;
font-weight: 400;
line-height: 30px;
cursor: pointer;
color: rgb(59, 65, 75);
font-family: "Microsoft YaHei";
margin-right: 8px;
border: 1px solid rgb(230, 231, 232);
}
.active {
background-color: rgba(246, 250, 255, 1);
border-color: rgb(5, 95, 194);
color: rgb(5, 95, 194);
}
}
.headerBtnBox {
position: absolute;
top: 14px;
right: 12px;
img {
width: 28px;
height: 28px;
margin-right: 4px;
cursor: pointer;
}
}
.mainBox {
width: 100%;
height: 100%;
padding-top: 42px;
.graph {
width: 100%;
height: 100%;
}
}
}
</style>
<template>
<div class="historical-proposal">
<div class="nav">
<el-input placeholder="搜索关键词" v-model="searchText" :suffix-icon="Search" class="search-input"></el-input>
<div class="select-box">
<el-select v-model="value1" placeholder="请选择" class="select">
<el-option label="全部法案" value="全部法案"></el-option>
</el-select>
<el-select v-model="value2" placeholder="请选择" class="select">
<el-option label="全部领域" value="全部领域"></el-option>
</el-select>
</div>
</div>
<div class="main">
<div v-for="item in list" :key="item.id" class="item">
<div class="img-box">
<img :src="item.img" alt="" class="img" />
<div class="info">
<div class="title">{{ item.title }}</div>
<div>
<span
v-for="(tag, index) in item.tie"
:key="tag"
class="tag"
:class="{ 'tag-1': index == 0, 'tag-2': index == 1 }"
>{{ tag }}</span
>
</div>
</div>
</div>
<div class="info-box">
<div class="box">
<div class="label">法案描述:</div>
<div class="content">{{ item.disc }}</div>
</div>
<div class="box">
<div class="label">法案状态:</div>
<div class="content">{{ item.state }}</div>
</div>
<div class="box">
<div class="label">提案日期:</div>
<div class="content">{{ item.time }}</div>
</div>
</div>
</div>
</div>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination
background
layout="prev, pager, next"
:total="100"
v-model:current-page="currentPage"
class="custom-pagination"
/>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { Search } from "@element-plus/icons-vue";
import img from "./assets/img.png";
const searchText = ref("");
const value1 = ref("全部法案");
const value2 = ref("全部领域");
const currentPage = ref(2);
const list = ref([
{
id: 1,
title: "FY2025 National Defense Authorization Act (NDAA, S.4638)",
tie: ["法案", "国防与军事"],
disc: "提供2.82亿美元用于Ellsworth空军基地B-21轰炸机任务和军事建设,包括现代化指令。图恩强调这是其领导的条款,确保南达科他州国防投资。",
state: "2024年12月参议院通过,待总统签署。",
time: "2024年6月",
img: img
},
{
id: 2,
title: "Bipartisan Appropriations Bills",
tie: ["法案", "政府预算"],
disc: "推动农业、商务、司法和军事等四项两党拨款法案,恢复“常规程序”以允许修正案辩论,避免年底“全包”法案或继续决议(CR)。图恩公开敦促民主党合作。",
state: "委员会报告,部分进入辩论阶段。",
time: "2025年7月",
img: img
},
{
id: 3,
title: "Tax Relief, Unemployment Insurance Reauthorization, and Job Creation Act",
tie: ["法案", "税收与经济"],
disc: "续推失业保险和就业创造措施,图恩在2024报告中排名共和党第8位影响力,推动小企业税收减免。",
state: "纳入2024报告卡,影响2025税收辩论",
time: "2024年续推",
img: img
},
{
id: 4,
title: "Farm Bill Renewal Provisions",
tie: ["修正案", "农业与农村"],
disc: "加强农村基础设施和作物保险,支持南达科他州农民。图恩强调两党合作,避免拖延。",
state: "纳入2024 Farm Bill讨论,部分通过",
time: "2024年",
img: img
},
{
id: 5,
title: "Regular Order Restoration",
tie: ["修正案", "能源"],
disc: "承诺恢复委员会起草、修正案辩论和投票规范,避免领导层封闭谈判。图恩表示将允许100多项修正案投票。",
state: "实施中,2025年夏季拨款辩论",
time: "2025年1月",
img: img
},
{
id: 6,
title: "S.Amdt.3946 和 S.Amdt.3947",
tie: ["法案", "政府预算"],
disc: "改进政府资金法案,允许参议员就电话记录扣押提起诉讼,保护国会隐私(源于2020选举调查争议)。图恩提议将法院赔偿退回财政部以调整条款。",
state: "2025年11月10日失败",
time: "2025年11月10日",
img: img
}
]);
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.historical-proposal {
width: 1600px;
height: 644px;
.nav {
width: 100%;
height: 32px;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
.search-input {
width: 300px;
height: 32px;
color: rgb(132, 136, 142);
font-size: 14px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 22px;
}
.select-box {
width: 332px;
height: 32px;
display: flex;
justify-content: space-between;
align-items: center;
.select {
width: 160px;
height: 32px;
color: rgb(132, 136, 142);
font-size: 14px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 22px;
}
}
}
.main {
width: 1600px;
height: 540px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-content: space-between;
.item {
width: 523px;
height: 262px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
padding: 16px 19px 17px 16px;
.img-box {
width: 488px;
height: 77px;
display: flex;
margin-bottom: 12px;
img {
width: 57px;
height: 77px;
margin-right: 15px;
}
.info {
width: 420px;
height: 77px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-start;
.title {
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(5, 95, 194);
}
.tag {
display: inline-block;
padding: 1px 8px;
font-size: 14px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 20px;
border-radius: 4px;
border: 1px solid;
margin-right: 8px;
}
.tag-1 {
background-color: rgba(246, 255, 237, 1);
color: rgba(82, 196, 26, 1);
border-color: rgba(217, 247, 190, 1);
}
.tag-2 {
background-color: rgba(255, 251, 230, 1);
color: rgba(250, 173, 20, 1);
border-color: rgba(255, 241, 184, 1);
}
}
}
.info-box {
width: 488px;
height: 140px;
.box {
width: 100%;
margin-bottom: 10px;
display: flex;
.label {
width: 84px;
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
.content {
width:400px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
}
}
}
}
.pagination-container {
width: 100%;
display: flex;
justify-content: center;
margin-top: 20px;
:deep(.el-pagination.is-background .el-pager li) {
background-color: #fff;
border: 1px solid rgba(229, 230, 235, 1);
border-radius: 4px;
color: rgba(29, 33, 41, 1);
font-weight: 400;
margin: 0 4px;
}
:deep(.el-pagination.is-background .el-pager li.is-active) {
background-color: #fff;
border-color: #165DFF;
color: #165DFF;
}
:deep(.el-pagination.is-background .btn-prev),
:deep(.el-pagination.is-background .btn-next) {
background-color: #fff;
border: 1px solid rgba(229, 230, 235, 1);
border-radius: 4px;
margin: 0 4px;
}
}
}
</style>
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论