提交 44e6af90 authored 作者: 胡卉清's avatar 胡卉清

合并分支 'dev_hhq' 到 'master'

Dev hhq 查看合并请求 !10
......@@ -15,6 +15,7 @@
"@traptitech/markdown-it-katex": "^3.6.0",
"axios": "^1.12.2",
"echarts": "^5.4.3",
"echarts-liquidfill": "^3.1.0",
"echarts-wordcloud": "^2.1.0",
"element-plus": "^2.4.4",
"highlight.js": "^11.11.1",
......@@ -2894,6 +2895,14 @@
"zrender": "5.6.1"
}
},
"node_modules/echarts-liquidfill": {
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/echarts-liquidfill/-/echarts-liquidfill-3.1.0.tgz",
"integrity": "sha512-5Dlqs/jTsdTUAsd+K5LPLLTgrbbNORUSBQyk8PSy1Mg2zgHDWm83FmvA4s0ooNepCJojFYRITTQ4GU1UUSKYLw==",
"peerDependencies": {
"echarts": "^5.0.1"
}
},
"node_modules/echarts-wordcloud": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/echarts-wordcloud/-/echarts-wordcloud-2.1.0.tgz",
......
......@@ -24,6 +24,7 @@
"@traptitech/markdown-it-katex": "^3.6.0",
"axios": "^1.12.2",
"echarts": "^5.4.3",
"echarts-liquidfill": "^3.1.0",
"echarts-wordcloud": "^2.1.0",
"element-plus": "^2.4.4",
"highlight.js": "^11.11.1",
......
<!-- 中M博弈资源支撑 -->
<template>
<div class="resource-box">
<DivideHeader class="divide1" :titleText="'中美博弈资源支撑'"></DivideHeader>
<div style="margin-top: 20px;height: 450px;display: flex;">
<div class="resource-content" style="width: 47.5%; display: block;">
<div class="item-header">
......@@ -25,16 +23,12 @@
</el-timeline-item>
</el-timeline>
</div>
</div>
<div class="resource-content" style="width: 47.5%;margin-left: 5%;">
<div class="item-header">
<img class="item-header-icon" src="@/assets/images/icon/thematic-card-header-time.png"></img>
<div class="item-header-text" style="width: 130px;">创新主体排名</div>
<el-radio-group v-model="InnovationRankingBtn" size="small" @change="handleInnovationRankingBtn">
<el-radio-button value="enterprise" border>科技企业
</el-radio-button>
<el-radio-button value="lab" border>国家重点实验室</el-radio-button>
......@@ -42,13 +36,11 @@
</el-radio-button>
<el-radio-button value="contractor" border>国防承包商</el-radio-button>
</el-radio-group>
</div>
<div class="item-header-divider"></div>
<el-table :data="InnovationRanking" stripe style="width: 100%;padding: 5px 25px;"
:header-cell-style="headerCellStyle">
<el-table-column prop="name" label="创新主体" width="100" />
<el-table-column prop="markValue" align="right">
<template #header>
<div class="custom-header">
......@@ -78,18 +70,20 @@
</el-table>
</div>
</div>
<div style="margin-top: 20px;height: 450px;display: flex;">
<div class="resource-content" style="width: 47.5%; display: block;">
<div class="item-header">
<img class="item-header-icon" src="@/assets/images/icon/thematic-card-header-time.png"></img>
<div class="item-header-text">研发投入情况</div>
</div>
<div class="item-header-divider"></div>
<el-radio-group v-model="putIntoBtn" size="small" @change="handlePutIntoBtn" style="margin-left: 20px;">
<el-radio-button value="development" border>研发经费
</el-radio-button>
<el-radio-button value="GDP" border>GDP占比</el-radio-button>
</el-radio-group>
<div style="display: flex;height: calc(100% - 60px);" id="char3">
</div>
</div>
<div class="resource-content" style="width: 47.5%;margin-left: 5%;">
......@@ -99,22 +93,26 @@
<div class="item-header-right"> 查看数据源> </div>
</div>
<div class="item-header-divider"></div>
<el-select v-model="areaSelect" placeholder="" style="width: 100px;float: right;margin-right: 20px;"
size="small">
<el-option v-for="item in timeList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<div style="display: flex;height: calc(100% - 60px);" id="char4">
</div>
</div>
</div>
<div style="margin-top: 20px;height: 450px;display: flex;">
<div class="resource-content" style="width: 47.5%; display: block;">
<div class="item-header">
<img class="item-header-icon" src="@/assets/images/icon/thematic-card-header-time.png"></img>
<div class="item-header-text">专利申请情况</div>
</div>
<div class="item-header-divider"></div>
<el-select v-model="patentSelect" placeholder="" style="width: 100px;float: right;margin-right: 20px;"
size="small">
<el-option v-for="item in timeList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<div style="display: flex;height: calc(100% - 60px);" id="char5">
</div>
</div>
<div class="resource-content" style="width: 47.5%;margin-left: 5%;">
......@@ -124,11 +122,13 @@
<div class="item-header-right"> 查看数据源> </div>
</div>
<div class="item-header-divider"></div>
<el-select v-model="paperSelect" placeholder="" style="width: 100px;float: right;margin-right: 20px;"
size="small">
<el-option v-for="item in timeList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<div style="display: flex;height: calc(100% - 60px);" id="char6">
</div>
</div>
</div>
</div>
......@@ -144,6 +144,30 @@ import radarChart2 from '../js/radarChart2.js'
import getMultiLineChart1 from "../js/multiLineChart1.js";
const timeList = ref([
{
label: "近半年",
value: "近半年",
},
{
label: "近一年",
value: "近一年",
},
{
label: "近两年",
value: "近两年",
},
{
label: "近三年",
value: "近三年",
},
{
label: "近五年",
value: "近五年",
},
]);
const names = ['Jan', 'Feb', 'Mar', 'Apr', 'May']
const data1 = [120, 200, 150, 80, 70]
const data2 = [90, 230, 180, 110, 100]
......@@ -223,9 +247,20 @@ const getStatus = _percent => {
const InnovationRankingBtn = ref('enterprise')
function handleInnovationRankingBtn() {
}
//研发投入情况
const putIntoBtn = ref('development')
function handlePutIntoBtn() {
}
//研发投入领域
const areaSelect = ref('近一年')
//专利申请情况
const patentSelect = ref('近一年')
const chart5Data = ref({
title: [
"2024-09",
......@@ -253,6 +288,9 @@ const chart5Data = ref({
]
});
//论文发表情况
const paperSelect = ref('近一年')
// 绘制echarts图表
const setChart = (option, chartId) => {
let chartDom = document.getElementById(chartId);
......
......@@ -17,8 +17,8 @@
<div class="title">
{{ item.time }}
</div>
<div class="name">
{{ item.name }}
<div class="title">
{{ item.title }}
</div>
<div class="content">
{{ item.content }}
......@@ -89,20 +89,21 @@ export default {
width: 100%;
position: relative;
padding: 0 40px;
box-sizing: border-box;
}
.arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 32px;
height: 32px;
border-radius: 50%;
border: 1px solid #dcdfe6;
background: #fff;
/* 左右切换按钮 */
width: 24px;
height: 48px;
font-size: 24px;
border-color: #E7F3FF;
border: 0;
background: #E7F3FF;
cursor: pointer;
z-index: 10;
color: #3E84D1;
}
.arrow:disabled {
......@@ -112,10 +113,13 @@ export default {
.left {
left: 0;
border-radius: 4px 0px 0px 4px;
}
.right {
right: 0;
border-radius: 0px 4px 4px 0px;
}
.timeline-box {
......@@ -172,7 +176,7 @@ export default {
/* 向上节点:线往下伸 */
.dot.up::after {
bottom: 100%;
height: 120px;
height: 180px;
/* 圆环底部 → 卡片顶 */
}
......@@ -180,26 +184,23 @@ export default {
.dot.down::after {
top: 100%;
height: 120px;
height: 180px;
}
.card {
position: absolute;
height: 120px;
height: 180px;
width: 15vw;
padding: 8px 12px;
text-align: center;
text-align: left;
cursor: pointer;
font-size: 14px;
}
.title {
color: rgba(5, 95, 194, 1);
font-size: 18px;
font-weight: 700;
line-height: 26px;
......@@ -207,9 +208,8 @@ export default {
text-align: justify;
}
.name {
color: var(----80, rgba(59, 65, 75, 1));
.title {
color: rgba(59, 65, 75, 1);
font-size: 20px;
font-weight: 700;
line-height: 26px;
......@@ -217,7 +217,14 @@ export default {
text-align: justify;
}
.content {}
.content {
color: rgba(95, 101, 108, 1);
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: justify;
}
.card.up {
bottom: 20px;
......
<template>
<div ref="ballDom" class="ball-box" :style="{ width: size + 'px', height: size + 'px' }" />
</template>
<script setup>
/**
* Vue3 水波进度球
* 用法:<WaterBall :percent="67" :size="200" />
*/
import { ref, watch, onMounted } from 'vue'
import * as echarts from 'echarts'
import 'echarts-liquidfill'
/* props */
const props = defineProps({
percent: { type: Number, default: 60 }, // 0~100
size: { type: Number, default: 200 }, // 画布宽高
data: { type: Object, default: {} },
color: { type: Array, default: [] },
})
/* dom */
const ballDom = ref(null)
let instance = null
// const color = ref([0, 0, 0])
// const makeColors = () => {
// props.color[0] = Math.floor(Math.random() * 360) // 随机色相
// props.color[1] = 70 // 固定饱和度
// props.color[2] = 50 // 固定亮度
// }
/* 颜色映射 */
/* 配置项 */
const makeOption = () => {
const p = Math.min(100, Math.max(0, props.percent)) / 100
console.log(props.color, 'colorcolorcolor')
return {
series: [{
type: 'liquidFill',
radius: '90%',
data: [
{ value: p, direction: 'right' },
{ value: p, direction: 'left' } // 两层波浪反向
],
color: [`hsla(${props.color[0]}, ${props.color[1]}%, ${props.color[2]}%, ${1})`, `hsla(${props.color[0]}, ${props.color[1]}%, ${props.color[2]}%, ${0.8})`],
waveAnimation: true,
animationEasingUpdate: 'cubicOut',
outline: {
show: true,
borderDistance: 4, // 第一层边框
itemStyle: {
borderWidth: 3,
borderColor: `hsla(${props.color[0]}, ${props.color[1]}%, ${props.color[2]}%, ${0.5})`
}
},
backgroundStyle: {
color: '#ffffff',
shadowColor: '#fff', //阴影
shadowBlur: 0, //阴影模糊
},
label: {
show: true,
formatter: `${props.data.text}` + `${props.data.unit}`,
fontSize: 24,
color: `hsla(${props.color[0]}, ${props.color[1]}%, ${props.color[2]}%, ${1})`,
// insideColor: '#fff'
}
}]
}
}
/* 初始化 */
const init = () => {
if (instance) instance.dispose()
instance = echarts.init(ballDom.value)
instance.setOption(makeOption())
}
/* 自动更新 */
watch(() => props.percent, () => {
instance?.setOption(makeOption())
})
onMounted(init)
</script>
<style scoped>
.ball-box {
margin: 0 auto;
}
</style>
\ No newline at end of file
......@@ -3,31 +3,79 @@
<div class="resource-box">
<DivideHeader class="divide1" :titleText="'中美科技实力对比'"></DivideHeader>
<div style="margin-top: 20px;height: 450px;display: flex;">
<div class="resource-content" style="width:100%; display: flex;">
<div style="width: 50%;height: 100%;" id="char7">
</div>
<div style="width: 50%;height: 100%;text-align: center;">
<div v-for="value in data">
<div>{{ value.name }}</div>
<div class="progress-row">
<div class="progress-wrapper left">
<el-progress :percentage="value.value[0]" :stroke-width="20" class="left-progress" />
<span class="inner-text">{{ value.value[0] }}%</span>
<div style="margin-top: 20px;display: flex;">
<div class="resource-content" style="width:100%">
<el-radio-group v-model="strengthBtn" size="small" @change="handlestrengthBtn" style="margin-left: 15%;">
<el-radio-button value="potential" border>竞争潜力
</el-radio-button>
<el-radio-button value="potency" border>竞争效力</el-radio-button>
<el-radio-button value="strength" border>竞争实力
</el-radio-button>
</el-radio-group>
<div style="display: flex;height: 350px;">
<div style="width: 50%;height: 100%;" id="char7">
</div>
<div style="width: 50%;height: 100%;text-align: center;padding:0 15px ;position: relative;">
<div class="title-box">
<div style="display: flex;width: 100%;">
<div class="unite">
<img class="unite-icon" src="@/assets/images/icon/united_USA.png" alt="" />
<div class="unite-title">
美国
</div>
</div>
<div class="unite-title" style="width: 33%;text-align: center;line-height: 40px;">
{{ data[0].name }}
</div>
<div class="unite" style=" justify-content: flex-end; ">
<div class="unite-title">
中国
</div>
<img class="unite-icon" src="@/assets/images/icon/united_CHN.png" alt="" />
</div>
</div>
<!-- 右侧进度条 -->
<div class="progress-wrapper right">
<el-progress :percentage="value.value[1]" :stroke-width="20" class="right-progress" />
<span class="inner-text">{{ value.value[0] }}%</span>
<div class="progress-row">
<div class="progress-wrapper left" :style="{ '--i': '40px', '--j': '-20px' }">
<el-progress :percentage="data[0].value[0]" :stroke-width="20" class="left-progress"
:show-text="false" />
<span class="inner-text" style="font-size: 24px;line-height: 40px;top: 20px;">{{ data[0].value[0]
}}%</span>
</div>
<!-- 右侧进度条 -->
<div class="progress-wrapper right" :style="{ '--i': '40px' }">
<el-progress :percentage="data[0].value[1]" :stroke-width="20" class="right-progress"
:show-text="false" />
<span class="inner-text" style="font-size: 24px;line-height: 40px;top: 20px;">{{ data[0].value[0]
}}%</span>
</div>
</div>
</div>
<div v-for="value in data.slice(1)">
<div class="unite-title-small" style="margin-top: 10px;">{{ value.name }}</div>
<div class="progress-row">
<div class="progress-wrapper left" :style="{ '--i': '20px', '--j': '0px' }">
<el-progress :percentage="value.value[0]" :stroke-width="20" class="left-progress"
:show-text="false" />
<span class="inner-text">{{ value.value[0] }}%</span>
</div>
<!-- 右侧进度条 -->
<div class="progress-wrapper right" :style="{ '--i': '20px' }">
<el-progress :percentage="value.value[1]" :stroke-width="20" class="right-progress"
:show-text="false" />
<span class="inner-text">{{ value.value[0] }}%</span>
</div>
</div>
</div>
</div>
<!-- 左侧进度条 -->
<!-- 左侧进度条 -->
</div>
</div>
<div>
</div>
......@@ -37,7 +85,7 @@
</div>
<SymmetryProgress :left-val="62" :right-val="88" />
......@@ -51,8 +99,11 @@ import * as echarts from "echarts";
import DivideHeader from "@/components/DivideHeader.vue";
import radarChart3 from '../js/radarChart3.js'
//科技实力按钮
const strengthBtn = ref('enterprise')
function handlestrengthBtn() {
}
// 绘制echarts图表
const setChart = (option, chartId) => {
let chartDom = document.getElementById(chartId);
......@@ -102,9 +153,9 @@ onMounted(() => {
/* ========== 一行两个 ========== */
.progress-row {
display: flex;
gap: 16px;
// gap: 16px;
align-items: center;
padding: 10px;
padding: 5px;
}
/* ========== 公共外壳 ========== */
......@@ -135,35 +186,93 @@ onMounted(() => {
white-space: nowrap;
}
.left-progress {
transform: scaleX(-1);
}
.left-progress :deep(.el-progress-bar__outer) {
border-radius: 10px 0 0 10px;
clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 100%, 0 100%);
background: #aed6ff;
border-radius: 0 var(--i) var(--i) 0;
clip-path: polygon(0px 0, 100% 0, 100% 100%, var(--i) 100%);
background: rgba(231, 243, 255, 1);
overflow: hidden;
/* 读行内传进来的变量 */
height: var(--i) !important;
margin-left: var(--j) !important
}
.left-progress :deep(.el-progress-bar__inner) {
border-radius: 10px 0 0 10px;
clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 100%, 0 100%);
background: #aed6ff;
border-radius: 0 var(--i) var(--i) 0;
clip-path: polygon(0px 0, 100% 0, 100% 100%, var(--i) 100%);
background: rgba(174, 214, 255, 1);
/* 读行内传进来的变量 */
height: var(--i) !important;
margin-left: var(--j) !important
}
/* ========== 右侧:左侧斜切 + 右侧圆角 ========== */
.right-progress :deep(.el-progress-bar__outer) {
border-radius: 0 10px 10px 0;
clip-path: polygon(10px 0, 100% 0, 100% 100%, 0 100%);
border-radius: 0 var(--i) var(--i) 0;
clip-path: polygon(var(--i) 0, 100% 0, 100% 100%, 0 100%);
background: #ffccc7;
overflow: hidden;
height: var(--i) !important;
}
.right-progress :deep(.el-progress-bar__inner) {
border-radius: 0 10px 10px 0;
clip-path: polygon(10px 0, 100% 0, 100% 100%, 0 100%);
border-radius: 0 var(--i) var(--i) 0;
clip-path: polygon(var(--i) 0, 100% 0, 100% 100%, 0 100%);
background: #ff7875;
height: var(--i) !important;
}
.title-box {
height: 100px;
width: 100%;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 4px;
background: rgba(247, 248, 249, 1);
.unite {
display: flex;
width: 33%;
align-items: center;
.unite-icon {
width: 40px;
padding: 5px;
}
}
.unite-title {
color: rgba(59, 65, 75, 1);
font-size: 24px;
font-weight: 700;
letter-spacing: 0px;
text-align: left;
}
}
.unite-title-small {
color: rgba(59, 65, 75, 1);
font-size: 18px;
font-weight: 700;
letter-spacing: 0px;
}
.resource-box {
height: 700px;
height: 800px;
}
.title-text {
......@@ -174,6 +283,14 @@ onMounted(() => {
text-align: center;
}
.title-text-small {
font-size: 24px;
font-weight: 700;
line-height: 42px;
margin: 40px;
text-align: center;
}
.title-img {
width: 100%;
height: 42px;
......@@ -182,7 +299,7 @@ onMounted(() => {
.resource-content {
/* 容器 480 */
width: 100%;
height: 450px;
height: 550px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: var(---, 10px);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论