提交 e8a57e68 authored 作者: 李顺's avatar 李顺

[update]:新增全联盟页面

import request from "@/api/request.js";
// 图表解读(流式)
/**
* @param {text}
*/
export function getChartAnalysis(data) {
return request({
method: 'POST',
url: `/aiAnalysis/chart_interpretation`,
data,
})
}
\ No newline at end of file
差异被折叠。
......@@ -2,7 +2,6 @@
import ZMGame from "@/views/ZMGame/index.vue";
const ZMGameRoutes = [
//创新主体
{
path: "/ZMGame",
name: "ZMGame",
......
......@@ -2,7 +2,6 @@
import ZMOverview from "@/views/ZMOverView/index.vue";
const ZMOverviewRoutes = [
//创新主体
{
path: "/ZMOverView",
name: "ZMOverView",
......@@ -14,4 +13,4 @@ const ZMOverviewRoutes = [
]
export default ZMOverviewRoutes
export default ZMOverviewRoutes
\ No newline at end of file
......@@ -21,11 +21,12 @@ const props = defineProps({
<style scoped lang="scss">
.com-title {
width: 100%;
width: 1601px;
height: 42px;
display: flex;
align-items: center;
margin-bottom: 36px;
// margin-bottom: 36px;
margin: 0 auto;
.cl1 {
width: 24px;
height: 30px;
......
import * as echarts from 'echarts';
const getMultiLineChart = (data) => {
// 提取标题和系列数据
// const { title, series } = data;
const title = data.title
const series = data.data
// 动态生成 series 配置
const echartsSeries = series.map((item, index) => ({
name: item.name,
type: 'line',
symbol: 'circle',
symbolSize: 8,
itemStyle: {
color: '#fff', // 图表圆点内部为白色
borderColor: item.color, // 圆点边框为系列颜色
borderWidth: 2
},
lineStyle: {
width: 2,
color: item.color
},
emphasis: {
focus: 'series'
},
data: item.value
}));
return {
color: series.map(item => item.color),
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(255, 255, 255, 0.9)',
textStyle: {
color: '#666'
},
extraCssText: 'box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); border-radius: 4px;'
},
grid: {
top: '15%',
right: '2%',
bottom: '5%',
left: '2%',
containLabel: true
},
legend: {
show: true,
top: 0,
left: 'center',
icon: 'circle',
itemWidth: 12,
itemHeight: 12,
data: series.map(item => ({
name: item.name,
itemStyle: {
color: item.color, // 强制图例使用实心系列颜色
borderWidth: 0
}
})),
textStyle: {
fontFamily: 'Microsoft YaHei',
fontSize: 16,
fontWeight: 400,
lineHeight: 24,
color: 'rgb(95, 101, 108)'
}
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: title,
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
color: '#999',
fontSize: 12,
margin: 15
}
}
],
yAxis: [
{
type: 'value',
min: 0,
max: 100,
interval: 20,
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
color: '#999',
fontSize: 12
},
splitLine: {
lineStyle: {
type: 'dashed',
color: '#E0E6F1'
}
}
}
],
series: echartsSeries
};
};
export default getMultiLineChart;
\ No newline at end of file
const getWordCloudChart = (data) => {
const option = {
grid: {
left: 0,
top: 0,
right: 0,
bottom: 0,
},
series: [
{
type: "wordCloud",
width: '80%',
height: '80%',
shape: "rect", //
// 其他形状你可以使用形状路径
// 或者自定义路径
// shape: 'circle' // 圆形(默认)
// shape: 'rect' // 矩形
// shape: 'roundRect' // 圆角矩形
// shape: 'triangle' // 三角形
// shape: 'diamond' // 菱形
// shape: 'pentagon' // 五边形
// shape: 'star' // 星形
// shape: 'cardioid' // 心形
gridSize: 15, // 网格大小,影响词间距。
sizeRange: [10, 30], // 定义词云中文字大小的范围
rotationRange: [0, 0],
rotationStep: 15,
drawOutOfBound: false, // 是否超出画布
// 字体
textStyle: {
// normal: {
// 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: 5,
shadowColor: "#333",
},
},
// 设置词云数据
data: data,
},
],
}
return option
}
export default getWordCloudChart
\ No newline at end of file
......@@ -2,18 +2,18 @@
<template>
<div class="content-wrapper">
<div class="main-nav">
<div
v-for="item in navList"
:key="item.name"
class="nav-item"
:class="{ active: activeNav === item.name }"
@click="handleNavClick(item.name)"
>
<div class="item-content">
<img v-if="activeNav === item.name" :src="right" class="active-icon" alt="" />
<span>{{ item.name }}</span>
</div>
<img v-if="activeNav === item.name" :src="background" class="active-bg" alt="" />
<div
v-for="item in navList"
:key="item.name"
class="nav-item"
:class="{ active: activeNav === item.name }"
@click="handleNavClick(item.name)"
>
<div class="item-content">
<img v-if="activeNav === item.name" :src="right" class="active-icon" alt="" />
<span>{{ item.name }}</span>
</div>
<img v-if="activeNav === item.name" :src="background" class="active-bg" alt="" />
</div>
</div>
<!-- 切换不同的组件 -->
......@@ -35,88 +35,84 @@ import AddDomain from "./components/addDomain/index.vue";
import AllUnion from "./components/allUnion/index.vue";
import AllElement from "./components/allElement/index.vue";
const navList = ref([
{ name: "全政府" },
{ name: "全领域" },
{ name: "全联盟" },
{ name: "全要素" }
]);
const navList = ref([{ name: "全政府" }, { name: "全领域" }, { name: "全联盟" }, { name: "全要素" }]);
const activeNav = ref("全政府");
const handleNavClick = (name) => {
activeNav.value = name;
const handleNavClick = name => {
activeNav.value = name;
};
</script>
<style lang="scss" scoped>
.content-wrapper {
width: 1601px;
height: 2203px;
margin: 0 auto;
.main-nav {
width: 100%;
height: 55px;
width: 1601px;
height: auto;
margin: 0 auto;
.main-nav {
width: 1600px;
height: 55px;
// margin: 0 auto;
padding: 4px 5px;
display: flex;
align-items: center;
display: flex;
align-items: center;
border-radius: 10px;
background-color: rgba(255, 255, 255, 0.65);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
box-sizing: border-box;
gap: 8px;
box-sizing: border-box;
gap: 8px;
margin-bottom: 16px;
.nav-item {
flex: 1;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
position: relative;
// transition: all 0.3s;
.nav-item {
flex: 1;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
position: relative;
// transition: all 0.3s;
.item-content {
display: flex;
align-items: center;
z-index: 1;
.item-content {
display: flex;
align-items: center;
z-index: 1;
.active-icon {
width: 18px;
height: 18px;
margin-right: 8px;
}
.active-icon {
width: 18px;
height: 18px;
margin-right: 8px;
}
span {
font-family: 'YouSheBiaoTiHei';
font-size: 24px;
font-weight: 400;
line-height: 31px;
color: rgb(59, 65, 75);
}
}
span {
font-family: "YouSheBiaoTiHei";
font-size: 24px;
font-weight: 400;
line-height: 31px;
color: rgb(59, 65, 75);
}
}
.active-bg {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
height: 60px;
z-index: 0;
}
.active-bg {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
height: 60px;
z-index: 0;
}
&.active {
background-color: rgba(246, 250, 255, 1);
border: 1px solid rgba(174, 214, 255, 1);
border-radius: 10px;
span {
color: rgb(5, 95, 194);
}
}
}
}
&.active {
background-color: rgba(246, 250, 255, 1);
border: 1px solid rgba(174, 214, 255, 1);
border-radius: 10px;
span {
color: rgb(5, 95, 194);
}
}
}
}
}
</style>
<template>
<div class="timeline-wrapper">
<button class="arrow left" :disabled="index <= 0" @click="index--">
{{ '<' }}
</button>
{{ '<' }} </button>
<div class="timeline-box">
<div class="line" style="width:100vw ;" />
<!-- 一次性渲染全部节点 -->
<div v-for="(item, i) in data" :key="item[idKey]" class="node" :style="leftStyle(i)">
<!-- 圆环 -->
<div class="dot" :class="linePos(item)" :style="{ '--i': item.unit === '中国' ? ' #E29697' : '#69A0DA' }" />
<div class="dot">
<div class="big-circle" :style="{
backgroundColor: item.unit === '中国' ? ' #CF4F51' : '#CDDFF3'
}">
<div class="small-circle" :style="{
backgroundColor: item.unit === '中国' ? ' #E29697' : '#69A0DA'
}"></div>
</div>
</div>
<div class="timeline-box">
<div class="line"></div>
<div v-for="(item, i) in showList" :key="item[idKey]" class="node" :style="leftOffset(i)">
<div class="node" :style="leftOffset(i)">
<!-- 圆环 -->
<div class="dot" :class="linePos(i, flip)"></div>
<!-- 卡片 -->
<div class="card" :class="[cardPos(item), 'right-side']" @click="$emit('click-card', item)">
<div style="justify-content: space-between;display: flex;width: 300px;">
<div class="tag">{{ item.tag }}</div>
<img :src="`/icon/${item.unit}.png`" class="icon"></img>
<!-- 卡片:放到线右侧 -->
<div class="card" :class="[cardPos(i, flip), 'right-side']" @click="$emit('click-card', item)">
</div>
<div class="title" :style="{
<div class="time">
{{ item.time }}
</div>
<div class="title">
{{ item.title }}
<img class="item-header-icon" src="@/assets/images/icon/copy.png" style="cursor: pointer;" />
</div>
<div class="content">
{{ item.content }}
}">{{ item.title }}</div>
<div class="time">{{ item.time }}</div>
<!-- <div class="title" :style="{
color: item.unit === '中国' ? ' #CF4F51' : ''
}">{{ item.title }}</div>
<div class="time">{{ item.time }}</div> -->
<div class="content">{{ item.content }}</div>
</div>
</div>
</div>
</div>
</div>
<button class="arrow right" :disabled="index >= total - 5" @click="index++">
{{ '>' }}
</button>
<button class="arrow right" :disabled="index >= total - 5" @click="index++">
{{ '>' }}
</button>
</div>
</template>
......@@ -39,18 +49,9 @@
export default {
name: 'TimeLine',
props: {
data: { // 父组件传入的数组
type: Array,
required: true
},
textKey: { // 要显示的文本字段
type: String,
default: 'text'
},
idKey: { // 唯一标识字段
type: String,
default: 'id'
}
data: { type: Array, required: true },
textKey: { type: String, default: 'text' },
idKey: { type: String, default: 'id' }
},
data() {
return { index: 0 };
......@@ -65,37 +66,49 @@ export default {
flip() { return this.index % 2 === 1; }
},
methods: {
leftOffset(i) {
return { left: `${(i * 100) / 5}%` };
// widthStyle() {
// console.log(`100 / ${this.data.length - 1}}vw`)
// let w = 100 / (this.data.length - 1)
// return { width: ` calc(${w}vw - 20px)` };
// },
/* 水平位置:按索引均匀分布 */
leftStyle(i) {
// let pos = ``
// if (i === 0) {
// pos = 0
// } else {
// this.linePos(this.data[i - 1]) !== this.linePos(this.data[i]) ? pos = { left: `${(i * 270) - 125}px` } : pos = { left: `${(i * 270)}px` }
// }
return { left: `${(i * 327)}px` }
// return pos;
},
/* 上下层翻转(保留上次逻辑) */
cardPos(i, flip = false) {
return (i % 2) ^ flip ? 'down' : 'up';
/* 卡片上下位置:unit=0 -> 下侧,其余 -> 上侧 */
cardPos(item) {
return item.unit === '中国' ? 'down' : 'up';
},
/* 线延伸方向 = 卡片出现方向 */
linePos(i, flip = false) {
return this.cardPos(i, flip); // up / down
/* 延伸线方向 = 卡片方向 */
linePos(item) {
return this.cardPos(item);
}
}
};
</script>
<style scoped>
/* 样式与之前完全一致,不再重复 */
/* 以下样式完全沿用你已有的,无需改动 */
.timeline-wrapper {
display: flex;
align-items: center;
width: 100%;
position: relative;
padding: 0 40px;
width: 1500px;
overflow: auto;
}
.arrow {
position: absolute;
top: 170px;
/* 左右切换按钮 */
width: 24px;
height: 48px;
font-size: 24px;
......@@ -123,10 +136,21 @@ export default {
border-radius: 4px 0px 0px 4px;
}
.year-box {
width: 80px;
height: 36px;
border-radius: 4px;
background: #055fc2;
color: #fff;
font-size: 18px;
border: none
}
.timeline-box {
flex: 1;
height: 100%;
position: relative;
margin-left: 15px;
}
.line {
......@@ -142,101 +166,185 @@ export default {
background-size: auto 100%;
}
.node {
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
z-index: 2;
z-index: 2
}
/* ===== 圆环基础 ===== */
.dot {
/* 任意尺寸/居中方式随意 */
margin: 0 auto;
position: relative;
display: flex;
justify-content: center;
align-items: center;
/* 仅示例 */
}
.big-circle {
width: 14px;
height: 14px;
border-radius: 50%;
/* 大圆颜色 */
display: flex;
justify-content: center;
align-items: center;
}
.small-circle {
width: 8px;
/* 小圆直径 */
height: 8px;
border-radius: 50%;
/* 小圆颜色 */
}
/* .dot {
width: 14px;
height: 14px;
border-radius: 50%;
border: 3px solid #409eff;
background: #fff;
position: relative;
margin: 0 auto;
z-index: 2;
}
position: relative
} */
/* ===== 延伸线 ===== */
.dot::after {
content: '';
position: absolute;
left: 50%;
transform: translateX(-1px);
/* 居中细线 */
width: 1px;
background: #409eff;
/* background: #409eff */
background: var(--i);
}
/* 向上节点:线往下伸 */
.dot.up::after {
bottom: 100%;
height: 165px;
/* 圆环底部 → 卡片顶 */
height: 240px
}
/* 向下节点:线往上伸 */
.dot.down::after {
top: 100%;
height: 165px;
height: 240px
}
.card {
position: absolute;
height: 165px;
width: 320px;
padding: 8px 12px;
text-align: left;
cursor: pointer;
/* 容器 28 */
width: 327px;
height: 270px;
padding-left: 27px;
font-size: 14px;
cursor: pointer
}
.time {
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 0px;
text-align: justify;
margin-bottom: 10px;
.card.up {
bottom: 0px
}
.card.down {
top: 10px;
padding-top: 50px
}
.icon {
width: 28px;
height: 28px;
}
.title {
/* 美国进一步收紧对华AI芯片出口限制 */
width: 300px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-style: Bold;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 0px;
text-align: justify;
margin-bottom: 10px;
}
.content {
color: rgba(95, 101, 108, 1);
.tag {
/* 容器 1626 */
width: 120px;
height: 28px;
/* 自动布局 */
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
padding: 2px 8px 2px 8px;
border-radius: 4px;
background: rgba(231, 243, 255, 1);
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
font-style: Regular;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: justify;
text-align: center;
margin-bottom: 4px;
}
.card.up {
bottom: 20px;
.tag1 {
/* 容器 1626 */
width: 120px;
height: 28px;
/* 自动布局 */
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
padding: 2px 8px 2px 8px;
border-radius: 4px;
background: rgba(206, 79, 81, 0.1);
color: rgba(206, 79, 81, 1);
font-family: Microsoft YaHei;
font-style: Regular;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
.card.down {
top: 20px;
.time {
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: justify;
}
.content {
width: 300px;
height: 150px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-style: Regular;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: justify;
}
</style>
\ No newline at end of file
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论