提交 d28bc11c authored 作者: huhuiqing's avatar huhuiqing

研发投入

上级 7f64a15a
<template>
<div class="page-content">
<!-- 公司导航栏 -->
<div class="company-nav">
<div class="company-logo-title">
<img :src="data.company.logo" alt="华为logo" class="logo-img">
<div class="title-group">
<h1 class="company-name">{{ data.company.name }}</h1>
<p class="company-english">{{ data.company.englishName }}</p>
</div>
</div>
<div class="main-tabs">
<div v-for="(tab, index) in tabList" :key="index" :class="activeTab === tab ? 'tab-active' : 'tab'"
@click="switchTab(tab)">
<img :src="`src/assets/icons/company${index + 1}.svg`" alt="tab图标" class="icon mail-icon" />
{{ tab }}
</div>
</div>
</div>
<!-- 主体内容区 -->
<div class="main-content">
<!-- 左侧信息栏 -->
<div class="left-sidebar">
<img :src="data.company.logo" alt="华为logo" class="sidebar-logo">
<h2 class="sidebar-company-name">{{ data.company.name }}</h2>
<div class="contact-list">
<div class="contact-item">
<img src="../../assets/icons/shutter.svg" alt="网址" class="contact-icon">
<span>{{ data.contactInfo.website }}</span>
</div>
<div class="contact-item">
<img src="../../assets/icons/location.svg" alt="地址" class="contact-icon">
<span>{{ data.contactInfo.address }}</span>
</div>
<div class="contact-item">
<img src="../../assets/icons/call.svg" alt="电话" class="contact-icon">
<span>{{ data.contactInfo.phone }}</span>
</div>
<div class="contact-item">
<img src="../../assets/icons/mail.svg" alt="邮箱" class="contact-icon">
<span>{{ data.contactInfo.email }}</span>
</div>
</div>
<!-- 左侧数据根据标签切换 -->
<div class="financial-list" v-if="activeTab === '基础信息'">
<div class="financial-item" v-for="(item, idx) in data.financialData" :key="idx">
<p class="financial-value">{{ item.value }}</p>
<p class="financial-label">{{ item.label }}</p>
</div>
</div>
<div class="financial-list" v-if="activeTab === '研发实力'">
<div class="financial-item" v-for="(value, key) in rndData.rndInfo" :key="key">
<p class="financial-value">{{ value }}</p>
<p class="financial-label">{{ key }}</p>
</div>
</div>
</div>
<!-- 右侧内容区 -->
<div class="right-content">
<!-- 基础信息标签内容 -->
<div v-if="activeTab === '基础信息'">
<!-- 子标签栏 -->
<div class="sub-tabs">
<span v-for="(tab, idx) in data.company.subTabs" :key="idx"
:class="['sub-tab', data.company.activeSubTab === tab ? 'active' : '']">
{{ tab }}
</span>
<div class="action-icons">
<img src="../../assets/icons/download.png" alt="下载" class="action-icon">
<img src="../../assets/icons/shoucang.png" alt="收藏" class="action-icon">
</div>
</div>
<!-- 企业概况内容 -->
<div class="overview-content">
<div class="info-grid">
<div class="info-card">
<h3 class="section-title">类别分布</h3>
<ul class="info-list">
<li v-for="(value, key) in data.categoryDist" :key="key" style="display: flex;align-items: center;">
<div class="li-icon"></div>
<span class="info-key">{{ key }}</span>
<span class="info-value">{{ value }}</span>
</li>
</ul>
</div>
<div class="info-card">
<h3 class="section-title">经营信息</h3>
<ul class="info-list">
<li v-for="(value, key) in data.businessInfo" :key="key" style="display: flex;align-items: center;">
<div class="li-icon"></div>
<span class="info-key">{{ key }}</span>
<span class="info-value">{{ value }}</span>
</li>
</ul>
</div>
</div>
</div>
<!-- 主要人员 -->
<div class="section">
<div class="section-header" style="margin-top: 24px;">
<div class="section-icon"></div>
<h3 class="section-title">主要人员</h3>
</div>
<div class="personnel-grid">
<div class="personnel-card" v-for="(person, idx) in data.mainPersonnel" :key="idx">
<div class="personnel-card-header">
<img :src="person.avatar" alt="头像" class="person-avatar">
<div class="person-info">
<h4 class="person-name">{{ person.name }}</h4>
<p class="person-position">{{ person.position }}</p>
</div>
</div>
<p class="person-desc">{{ person.desc }}</p>
</div>
</div>
</div>
<!-- 分支机构 -->
<div class="section">
<div class="section-header">
<div class="section-icon"></div>
<h3 class="section-title">分支机构</h3>
</div>
<div class="branches-grid">
<div class="branch-item" v-for="(branch, idx) in data.branches" :key="idx">
<span>{{ branch }}</span>
<img src="../../assets/icons/open.png" alt="箭头" class="branch-arrow">
</div>
</div>
</div>
</div>
<!-- 研发实力标签内容 -->
<div v-if="activeTab === '研发实力'">
<!-- 研发子标签栏 -->
<div class="sub-tabs">
<span class="sub-tab active">研发投入</span>
<span class="sub-tab">专利布局</span>
<span class="sub-tab">技术突破</span>
<div class="action-icons">
<img src="../../assets/icons/download.png" alt="下载" class="action-icon">
<img src="../../assets/icons/shoucang.png" alt="收藏" class="action-icon">
</div>
</div>
<!-- 研发投入图表区域 -->
<div class="rnd-charts">
<div class="chart-card">
<div class="section-header">
<div class="section-icon"></div>
<h3 class="section-title">年度研发投入(单位:亿美元)</h3>
</div>
<div id="rndInvestmentChart" class="chart-container"></div>
</div>
<div class="chart-card">
<div class="section-header">
<div class="section-icon"></div>
<h3 class="section-title">专利技术分布</h3>
</div>
<div id="patentDistChart" class="chart-container"></div>
</div>
</div>
<!-- 研发核心人员 -->
<div class="section">
<div class="section-header">
<div class="section-icon"></div>
<h3 class="section-title">研发核心人员</h3>
</div>
<div class="personnel-grid">
<div class="personnel-card" v-for="(person, idx) in rndData.rndPersonnel" :key="idx">
<div class="personnel-card-header">
<img :src="person.avatar" alt="头像" class="person-avatar">
<div class="person-info">
<h4 class="person-name">{{ person.name }}</h4>
<p class="person-position">{{ person.position }}</p>
</div>
</div>
<p class="person-desc">{{ person.desc }}</p>
</div>
</div>
</div>
<!-- 核心技术突破 -->
<div class="section">
<div class="section-header">
<div class="section-icon"></div>
<h3 class="section-title">核心技术突破</h3>
</div>
<div class="branches-grid">
<div class="branch-item" v-for="(tech, idx) in rndData.techBreakthrough" :key="idx">
<span>{{ tech }}</span>
<img src="../../assets/icons/open.png" alt="箭头" class="branch-arrow">
</div>
</div>
</div>
</div>
<!-- 被制裁情况标签内容 -->
<div v-if="activeTab === '被制裁情况'">
<div class="sub-tabs">
<span class="sub-tab active">制裁概况</span>
<div class="action-icons">
<img src="../../assets/icons/download.png" alt="下载" class="action-icon">
<img src="../../assets/icons/shoucang.png" alt="收藏" class="action-icon">
</div>
</div>
<div class="section" style="padding: 20px;text-align: center;color: #86909c;">
被制裁情况模块待开发...
</div>
</div>
<!-- 供应链情况标签内容 -->
<div v-if="activeTab === '供应链情况'">
<div class="sub-tabs">
<span class="sub-tab active">供应链概况</span>
<div class="action-icons">
<img src="../../assets/icons/download.png" alt="下载" class="action-icon">
<img src="../../assets/icons/shoucang.png" alt="收藏" class="action-icon">
</div>
</div>
<div class="section" style="padding: 20px;text-align: center;color: #86909c;">
供应链情况模块待开发...
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue'
// 引入数据文件
import data from './data/huaweiData.json'
import rndData from './data/huaweiRndData.json'
// 引入抽离的图表组件
import getRndInvestmentChart from './charts/rndInvestmentChart.js'
import getPatentDistChart from './charts/patentDistChart.js'
import initEchart from './charts/chartInit.js'
// 标签列表和激活状态
const tabList = ref(['基础信息', '研发实力', '被制裁情况', '供应链情况'])
const activeTab = ref('基础信息')
// 切换标签方法
const switchTab = (tab) => {
activeTab.value = tab
// 切换到研发实力时初始化图表
if (tab === '研发实力') {
// 确保DOM渲染完成后初始化图表
setTimeout(initRndCharts, 100)
}
}
// 初始化研发相关图表
const initRndCharts = () => {
// 1. 初始化研发投入折线图
const investmentOption = getRndInvestmentChart(rndData.rndInvestment)
initEchart('rndInvestmentChart', investmentOption)
// 2. 初始化专利分布饼图
const patentOption = getPatentDistChart(rndData.patentDist)
initEchart('patentDistChart', patentOption)
}
// 监听标签切换
watch(activeTab, (newVal) => {
if (newVal === '研发实力') {
setTimeout(initRndCharts, 100)
}
})
// 页面挂载时初始化
onMounted(() => {
if (activeTab.value === '研发实力') {
initRndCharts()
}
})
</script>
<style scoped>
/* 基础样式 */
.page-content {
font-family: "Microsoft Yahei", "PingFang SC", sans-serif;
background-color: #f5f7fa;
min-height: 100vh;
}
/* 公司导航栏 */
.company-nav {
height: 124px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
padding: 0 160px;
box-shadow: 0px 4px 4px 0px rgba(129, 128, 128, 0.25);
background: rgba(255, 255, 255, 1);
}
.company-logo-title {
display: flex;
align-items: center;
gap: 12px;
padding: 5px;
}
.logo-img {
width: 60px;
height: 60px;
object-fit: contain;
}
.title-group {
display: flex;
flex-direction: column;
}
.company-name {
font-size: 18px;
color: #1d2129;
margin: 0;
}
.company-english {
font-size: 12px;
color: #86909c;
margin: 0;
}
.main-tabs {
height: 48px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
gap: 32px;
padding: 0px 16px 0px 0px;
width: 100%;
}
.tab {
color: rgba(59, 65, 75, 1);
height: 48px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
box-sizing: border-box;
border-bottom: 0px solid rgba(5, 95, 194, 1);
margin: 6px 30px 0 0;
cursor: pointer;
gap: 8px;
}
.tab-active {
color: rgba(5, 95, 194, 1);
height: 48px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
box-sizing: border-box;
border-bottom: 2px solid rgba(5, 95, 194, 1);
margin: 6px 30px 0 0;
cursor: pointer;
gap: 8px;
}
/* 主体内容区 */
.main-content {
margin: 16px 160px;
width: calc(100% - 320px);
display: flex;
gap: 16px;
}
/* 左侧信息栏 */
.left-sidebar {
width: 360px;
background-color: #fff;
border-radius: 6px;
padding: 30px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.sidebar-logo {
width: 132px;
height: 124px;
object-fit: contain;
margin: 60px auto 0;
display: block;
}
.sidebar-company-name {
text-align: center;
margin: 48px 0 20px;
padding-bottom: 15px;
color: rgba(10, 18, 30, 1);
font-family: Microsoft YaHei;
font-size: 24px;
font-weight: 700;
line-height: 32px;
letter-spacing: 0px;
border-bottom: 1px solid #ebebeb;
}
.contact-list {
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #ebebeb;
}
.contact-item {
display: flex;
align-items: center;
gap: 8px;
font-size: 16px;
color: rgba(59, 65, 75, 1);
margin-bottom: 12px;
font-weight: 400;
line-height: 30px;
}
.contact-icon {
width: 14px;
height: 14px;
flex-shrink: 0;
}
.financial-list {
padding-top: 15px;
}
.financial-item {
text-align: center;
padding: 12px 0;
border-bottom: 1px solid #ebebeb;
}
.financial-item:last-child {
border-bottom: none;
}
.financial-value {
font-size: 20px;
color: #1890ff;
font-weight: 600;
margin: 0 0 5px;
}
.financial-label {
font-size: 12px;
color: #86909c;
margin: 0;
}
/* 右侧内容区 */
.right-content {
width: 100%;
flex: 1;
background-color: #fff;
border-radius: 6px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
}
/* 子标签栏 */
.sub-tabs {
height: 56px;
padding: 12px 24px;
display: flex;
align-items: center;
gap: 8px;
border-bottom: 1px solid #ebebeb;
}
.sub-tab {
width: 80px;
height: 28px;
color: rgba(59, 65, 75, 1);
font-size: 16px;
font-weight: 400;
line-height: 30px;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
border: 1px solid rgba(59, 65, 75, 1);
border-radius: 4px;
background: rgba(246, 250, 255, 1);
cursor: pointer;
}
.sub-tab.active {
color: rgba(5, 95, 194, 1);
border: 1px solid rgba(5, 95, 194, 1);
background: rgba(246, 250, 255, 1);
}
.action-icons {
display: flex;
gap: 15px;
margin-left: auto;
}
.action-icon {
width: 28px;
height: 28px;
cursor: pointer;
}
/* 信息网格 */
.info-grid {
display: flex;
gap: 16px;
padding: 24px;
}
.info-card {
flex: 1;
background-color: #f9fafb;
border-radius: 6px;
padding: 12px 16px;
}
.section-title {
font-size: 16px;
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
font-weight: 700;
line-height: 24px;
letter-spacing: 1px;
margin: 0 0 16px 0;
}
.info-list {
list-style: none;
padding: 0;
margin: 0;
}
.info-list li {
font-size: 16px;
margin-bottom: 12px;
line-height: 24px;
display: flex;
align-items: center;
}
.li-icon {
width: 4px;
height: 4px;
background: rgba(59, 65, 75, 1);
border-radius: 50%;
flex-shrink: 0;
}
.info-key {
width: 100px;
color: rgba(59, 65, 75, 1);
font-size: 16px;
font-weight: 700;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
margin-left: 22px;
}
.info-value {
color: rgba(59, 65, 75, 1);
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: justify;
flex: 1;
}
/* 通用区块样式 */
.section {
margin: 0 24px 24px;
}
.section-header {
display: flex;
align-items: center;
margin-bottom: 16px;
}
.section-icon {
width: 7px;
height: 18px;
border-radius: 0 4px 4px 0;
background: rgba(5, 95, 194, 1);
margin-right: 17px;
}
/* 人员网格 */
.personnel-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 15px;
}
.personnel-card {
height: 150px;
box-sizing: border-box;
border: 1px solid rgba(223, 232, 239, 1);
border-radius: 4px;
background: rgba(255, 255, 255, 1);
}
.personnel-card-header {
display: flex;
height: 78px;
background: rgba(246, 249, 250, 1);
padding: 11px 15px;
}
.person-avatar {
width: 50px;
height: 50px;
border-radius: 50%;
object-fit: cover;
flex-shrink: 0;
}
.person-info {
flex: 1;
margin: 0 16px;
}
.person-name {
margin: 0;
color: rgba(10, 18, 30, 1);
font-size: 18px;
font-weight: 700;
line-height: 24px;
}
.person-position {
margin: 0;
color: rgba(10, 18, 30, 1);
font-size: 14px;
font-weight: 400;
line-height: 24px;
}
.person-desc {
padding: 16px 8px;
margin: 0;
color: rgba(95, 101, 108, 1);
font-size: 16px;
font-weight: 400;
line-height: 24px;
}
/* 分支机构/技术突破 */
.branches-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0 10px;
}
.branch-item {
height: 54px;
display: flex;
align-items: center;
color: rgba(59, 65, 75, 1);
font-size: 16px;
font-weight: 400;
line-height: 30px;
cursor: pointer;
padding: 12px 16px;
box-sizing: border-box;
border-top: 1px solid rgba(234, 236, 238, 1);
border-bottom: 1px solid rgba(234, 236, 238, 1);
margin-bottom: -1px;
border-radius: 4px;
background: rgba(255, 255, 255, 1);
}
.branch-item:hover {
background-color: #f0f2f5;
}
.branch-arrow {
width: 12px;
height: 12px;
margin-left: auto;
}
/* 研发图表样式 */
.rnd-charts {
display: flex;
gap: 16px;
padding: 24px;
flex-wrap: wrap;
}
.chart-card {
flex: 1;
min-width: 400px;
background: #f9fafb;
border-radius: 6px;
padding: 16px;
}
.chart-container {
width: 100%;
height: 300px;
margin-top: 10px;
}
/* 响应式适配 */
@media (max-width: 1440px) {
.main-content {
margin: 16px 80px;
width: calc(100% - 160px);
}
.company-nav {
padding: 0 80px;
}
}
@media (max-width: 1200px) {
.personnel-grid {
grid-template-columns: repeat(2, 1fr);
}
.branches-grid {
grid-template-columns: repeat(2, 1fr);
}
.chart-card {
min-width: 300px;
}
}
@media (max-width: 768px) {
.main-content {
flex-direction: column;
margin: 16px 20px;
width: calc(100% - 40px);
}
.left-sidebar {
width: 100%;
}
.company-nav {
padding: 0 20px;
height: auto;
padding: 16px 20px;
}
.main-tabs {
flex-wrap: wrap;
height: auto;
gap: 16px;
}
.info-grid {
flex-direction: column;
}
.personnel-grid {
grid-template-columns: 1fr;
}
.branches-grid {
grid-template-columns: 1fr;
}
.rnd-charts {
flex-direction: column;
}
.chart-card {
min-width: 100%;
}
}
</style>
\ No newline at end of file
<template>
<div class="box-content">
<div class="tab-box">
<div v-for="(tab, index) in tabList" :class="activeTab === tab ? 'tab-active' : 'tab'" @click="activeTab = tab">
{{ tab }}
<div class="arrow-active">
</div>
</div>
</div>
<!--/*头部总览 */-->
<div class="total">
<div v-for="(item) in totalData" class="total-box">
<div class="line">
</div>
<div class="total-label">
{{ item.label }}
</div>
<div class="total-content">
<div class="total-value">
{{ item.value }}
</div>
<div class="total-unit">
{{ item.unit }}
</div>
</div>
</div>
</div>
<!--/*图表 */-->
<div class="chart">
<div class="chart-content">
<div class="section-header" style=" margin-top: 24px;">
<div style="display: flex;">
<div class="section-icon"></div>
<h3 class="section-title">年度研发投入对比</h3>
</div>
<div class="action-icons">
<img src="@/assets/icons/download.png" alt="下载" class="action-icon">
<img src="@/assets/icons/shoucang.png" alt="收藏" class="action-icon">
</div>
</div>
<div id="chart1" class="chart-box">
</div>
<div class="chart-text">
<img src="@/assets/icons/model.png" style="width: 19px;height: 20px;">
<div>
近五年来,华为的研发投入在绝对金额和投入强度上均持续攀升。尤其是在收入因外部制裁而经历波动时,研发投入依然保持强劲增长,使其投入强度达到了历史高位。
</div>
<div class="arrow-2">
</div>
</div>
</div>
<div class="chart-content">
<div class="section-header" style=" margin-top: 24px;">
<div style="display: flex;">
<div class="section-icon"></div>
<h3 class="section-title">研发投入增长对比</h3>
</div>
<div class="action-icons">
<img src="@/assets/icons/download.png" alt="下载" class="action-icon">
<img src="@/assets/icons/shoucang.png" alt="收藏" class="action-icon">
</div>
</div>
<div id="chart2" class="chart-box">
</div>
<div class="chart-text">
<img src="@/assets/icons/model.png" style="width: 19px;height: 20px;">
<div>
华为在巨大的外部压力下,研发投入不仅在绝对金额上持续增长,其占收入的比重更是大幅提升,特别是2021年后形成的“剪刀差”,体现了公司最高优先级的战略抉择。 </div>
<div class="arrow-2">
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import getBarChart from "../js/barChart.js";
import * as echarts from "echarts";
import getLineChart from "../js/lineChart.js";
const tabList = ref(['研发投入', '研究人员', '专利情况'])
const activeTab = ref('研发投入')
const totalData = ref([
{
"label": "累计研发投入",
"value": 9854,
"unit": "亿元"
},
{
"label": "年度研发投入",
"value": 2153.9,
"unit": "亿元"
},
{
"label": "研发强度",
"value": 22.9,
"unit": "%"
},
{
"label": "研发投入排名",
"value": "Top",
"unit": ""
}
])
//年度研发投入对比
const chart1Data = ref({
name: ['2020', '2021', '2022', '2023', '2024', '2025'],
value: [50, 100, 150, 200, 250, 300, 350, 400]
});
//研发投入增长对比
const chart2Data = {
dataX: ["2025-01", "2025-02", "2025-03", "2025-04", "2025-05", "2025-06", "2025-07", "2025-08"],
dataY: [1.2, 1.5, 1.4, 1.8, 1.3, 1.5, 1.6, 1.4]
};
// 绘制echarts图表
const setChart = (option, chartId) => {
let chartDom = document.getElementById(chartId);
console.log(chartDom, "chartDomchartDomchartDom");
chartDom.removeAttribute("_echarts_instance_");
let chart = echarts.init(chartDom);
chart.setOption(option);
return chart;
};
onMounted(() => {
let char1 = getBarChart(chart1Data.value.name, chart1Data.value.value, true);
setChart(char1, "chart1");
let chart2 = getLineChart(chart2Data.dataX, chart2Data.dataY);
setChart(chart2, "chart2");
// let char2 = radarChart();
// setChart(char2, "char2");
});
</script>
<style scoped>
.box-content {
width: 100%;
height: calc(100vh - 220px);
overflow: auto;
}
.tab-box {
/* 左侧导航 */
width: 112px;
height: 128px;
position: absolute;
left: 0;
margin: 20px;
/* 自动布局 */
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
gap: 16;
.tab {
color: rgba(59, 65, 75, 1);
height: 48px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
box-sizing: border-box;
border-bottom: 0px solid rgba(5, 95, 194, 1);
margin: 6px 30px 0 0;
}
.tab-active {
/* 容器 7 */
width: 104px;
height: 32px;
display: flex;
align-items: center;
box-sizing: border-box;
border-bottom: 2px solid rgba(5, 95, 194, 1);
margin: 6px 30px 0 0;
border-radius: 16px;
background: rgba(5, 95, 194, 1);
color: rgba(255, 255, 255, 1);
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
padding: 4px 12px;
}
.arrow-active {
width: 0;
height: 0;
border-style: solid;
border-width: 4px 0 4px 6px;
margin-left: 5px;
/* 上 右 下 左 */
border-color: transparent transparent transparent #ffffff;
/* 只给左边上色 */
/* background: rgba(255, 255, 255, 1); */
}
}
/*头部总览 */
.total {
height: 80px;
display: flex;
gap: 16px;
}
.total-box {
border-radius: 4px;
background: rgba(255, 255, 255, 1);
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
.line {
/* 矩形 214 */
width: 4px;
height: 49px;
background: rgba(5, 95, 194, 1);
}
.total-label {
color: rgba(59, 65, 75, 1);
margin: 0px 30px;
font-size: 16px;
font-weight: 700;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
.total-content {
display: flex;
margin-right: 35px;
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
letter-spacing: 0px;
text-align: right;
.total-value {
font-size: 24px;
font-weight: 700;
line-height: 24px;
}
.total-unit {
font-size: 16px;
font-weight: 500;
line-height: 16px;
margin-top: 8px;
}
}
}
.chart {
margin-top: 16px;
height: calc(100vh - 320px);
display: flex;
gap: 16px;
.chart-content {
border-radius: 4px;
background: rgba(255, 255, 255, 1);
flex: 1;
justify-content: space-between;
.section-header {
display: flex;
width: 100%;
justify-content: space-between;
}
.section-icon {
width: 7px;
height: 18px;
border-radius: 0 4px 4px 0;
background: rgba(5, 95, 194, 1);
margin-right: 17px;
}
.section-title {
font-size: 18px;
color: #1d2129;
margin: 0;
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
font-weight: 700;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
}
.action-icons {
display: flex;
margin-left: auto;
}
.action-icon {
/* 收藏按钮 */
width: 28px;
height: 28px;
cursor: pointer;
margin-right: 12px;
}
.chart-box {
width: 100%;
height: calc(100% - 130px);
}
.chart-text {
/* 大模型对话结果 */
height: 52px;
margin: 12px 20px;
/* 自动布局 */
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 10;
padding: 0px 12px 0px 12px;
box-sizing: border-box;
border: 1px solid rgba(231, 243, 255, 1);
border-radius: 4px;
background: rgba(246, 251, 255, 1);
color: rgba(5, 95, 194, 1);
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: justify;
gap: 13px;
}
.arrow-2 {
border-radius: 50%;
width: 24px;
height: 24px;
font-size: 24px;
background: rgba(231, 243, 255, 1);
}
}
</style>
\ No newline at end of file
import * as echarts from "echarts";
const getColumnChart = (nameList, valueList, isPer) => {
const colorList = ['rgb(46, 165, 255)']
return {
tooltip: {},
grid: { top: '10%', right: '3%', bottom: '15%', left: '3%', containLabel: true },
color: colorList,
xAxis: {
type: 'category',
data: nameList,
axisLine: { show: false },
axisTick: { show: false },
axisLabel: {
show: true,
color: '#666',
fontSize: 14
}
},
yAxis: {
type: 'value',
axisLine: { show: false },
axisTick: { show: false },
axisLabel: { show: true, color: '#666' }, // ② Y 轴文字
splitLine: {
show: true, lineStyle: {
type: "dashed",
color: "#E7F3FF"
}
}
},
series: [{
type: 'bar',
data: valueList.map((v, i) => ({
value: v,
label: { show: false, position: 'top', color: 'rgb(46, 165, 255)' }
})),
barWidth: 16,
itemStyle: {
borderRadius: [8, 8, 0, 0],
color: params => {
const colors = ['rgb(46, 165, 255)', 'rgba(255,255,255,0)']
return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: colors[0] },
{ offset: 1, color: colors[1] }
])
}
},
label: {
show: true,
position: 'top',
formatter: v => (isPer ? v.value + '%' : v.value)
}
}]
}
}
export default getColumnChart
\ No newline at end of file
import * as echarts from 'echarts'
const getLineChart = (dataX, dataY) => {
return {
grid: {
left: '2%',
top: '8%',
right: '2%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
splitLine: {
show: false
},
axisLine: {
show: false
},
data: dataX
},
yAxis: {
type: 'value',
splitLine: {
show: true, lineStyle: {
type: "dashed",
color: "#E7F3FF"
}
},
axisLine: {
show: false
},
},
color: ['rgb(255, 172, 77)'],
series: [
{
data: dataY,
type: 'line',
emphasis: {
focus: 'series'
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(255, 172, 77, 0.5)' // 起始颜色:深色
}, {
offset: 1,
color: 'rgba(255, 172, 77,0)' // 结束颜色:浅色且透明度降低
}])
},
}
]
}
}
export default getLineChart;
\ No newline at end of file
...@@ -22,9 +22,11 @@ const getColumnChart = (nameList, valueList, isPer) => { ...@@ -22,9 +22,11 @@ const getColumnChart = (nameList, valueList, isPer) => {
axisLine: { show: false }, axisLine: { show: false },
axisTick: { show: false }, axisTick: { show: false },
axisLabel: { show: true, color: '#666' }, // ② Y 轴文字 axisLabel: { show: true, color: '#666' }, // ② Y 轴文字
splitLine: { // ③ 横向参考线 splitLine: {
show: true, show: true, lineStyle: {
lineStyle: { color: '#ebebeb', width: 1 } type: "dashed",
color: "#E7F3FF"
}
} }
}, },
series: [{ series: [{
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论