提交 88b6f73b authored 作者: 付康's avatar 付康

合并分支 'lzl-dev' 到 'master'

法案详情页面的接口联调和样式优化 查看合并请求 !48
......@@ -94,4 +94,39 @@ export function getProcessSummary(params) {
url: `/api/billDeepDive/processSummary/${params.id}`,
params,
})
}
\ No newline at end of file
}
// 获取党派政治献金
/**
* @param {id, personCongress}
*/
export function getBillPoliContribution(params) {
return request({
method: 'GET',
url: `/api/billDeepDive/processAnalyze/totalxj/${params.id}`,
params
})
}
// 获取主要议员政治献金
/**
* @param {id, personCongress}
*/
export function getBillMainPoliContribution(params) {
return request({
method: 'GET',
url: `/api/billDeepDive/processAnalyze/xj/${params.id}`,
params
})
}
// 根据法案ID获取人员政治献金来源及行业领域分布
/**
* @param {id, personId}
*/
export function getBillPersonPoliContribution(params) {
return request({
method: 'GET',
url: `/api/billDeepDive/processAnalyze/xj/${params.id}/${params.personId}`
})
}
......@@ -30,4 +30,17 @@ export function getHylyList() {
method: 'GET',
url: `/api/billImpactAnalysis/industry/hylyList`,
})
}
// 获取公司详情
/**
* @param {billId,companyId,id}
*/
export function getCompanyDetail(params) {
return request({
method: 'GET',
url: `/api/billImpactAnalysis/industry/companyDetail/${params.billId}/${params.id}/${params.companyId}`,
params,
})
}
\ No newline at end of file
......@@ -2523,6 +2523,7 @@ onUnmounted(() => {});
font-size: 14px;
font-weight: 400;
line-height: 22px;
overflow: hidden;
}
}
.right-footer {
......@@ -2606,6 +2607,7 @@ onUnmounted(() => {});
img {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.right {
......
......@@ -212,7 +212,7 @@ onMounted(() => {
height: 1016px;
background: rgba(249, 250, 252, 1);
position: relative;
margin: 0 auto;
// margin: 0 auto;
.layout-header {
width: 1920px;
height: 64px;
......
......@@ -6,8 +6,12 @@
<div class="icon"></div>
<div class="title">{{ "主要议员" }}</div>
<div class="btn-box">
<div class="btn" :class="{ btnActive: activeBtnIndex === 0 }">{{ "参议院" }}</div>
<div class="btn" :class="{ btnActive: activeBtnIndex === 1 }">{{ "众议院" }}</div>
<div class="btn" :class="{ btnActive: activeBtnIndex === 0 }" @click="activeBtnIndex = 0">
{{ "参议院" }}
</div>
<div class="btn" :class="{ btnActive: activeBtnIndex === 1 }" @click="activeBtnIndex = 1">
{{ "众议院" }}
</div>
</div>
<div class="header-right">
<div class="right-icon">
......@@ -20,7 +24,7 @@
</div>
<div class="box1-main">
<div class="box1-main-top">
<div class="top-item" v-for="(item, index) in majorList[activeBtnIndex].data1" :key="index">
<div class="top-item" v-for="(item, index) in partyContributionList" :key="index">
<div class="icon">
<img :src="item.img" alt="" />
</div>
......@@ -33,28 +37,29 @@
<div
class="item"
:class="{ itemActive: itemActiveIndex === index }"
v-for="(item, index) in majorList[activeBtnIndex].data2"
v-for="(item, index) in mainPoliContribution"
:key="index"
@click="handlePersonClick(item, index)"
>
<div class="item-left">
<img :src="item.img" alt="" />
<img :src="item.image || Img1" alt="" />
</div>
<div class="item-center">
<div class="center-top">
<div class="name">{{ item.name }}</div>
<div class="icon1">
<img :src="item.dangpai" alt="" />
<img :src="item.dp === 'Republican' ? Ghd : Mzd" alt="" />
</div>
<div class="icon2">
<img :src="item.yuanbie" alt="" />
<img :src="activeBtnIndex === 0 ? Cyy : Zyy" alt="" />
</div>
</div>
<div class="center-footer">
{{ item.zhiwei }}
{{ item.zw }}
</div>
</div>
<div class="item-right">
{{ item.num }}
{{ item.formattedTotalJe }}
</div>
</div>
</div>
......@@ -67,6 +72,9 @@
<div class="icon"></div>
<div class="title">{{ "政治献金流向" }}</div>
<div class="header-right">
<div class="more-btn" v-if="fullSourceList.length > 5" @click="toggleSankeyData">
{{ showAllSankeyData ? '收起' : '更多+' }}
</div>
<div class="right-icon">
<img src="@/assets/icons/box-header-icon1.png" alt="" />
</div>
......@@ -84,9 +92,7 @@
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="box-footer-center">
{{
"马尔科·卢比奥的政治资金主要依赖于一个由亿万富翁、特定行业利益集团及通过​“超级政治行动委员会”​​ 运作的大额捐款网络。"
}}
{{ currentPersonName }}的政治资金主要依赖于一个由亿万富翁、特定行业利益集团及通过​“超级政治行动委员会”​​ 运作的大额捐款网络。
</div>
<div class="box-footer-right">
<img src="@/assets/icons/box-footer-right-icon.png" alt="" />
......@@ -116,7 +122,7 @@
<div class="id">{{ index + 1 }}</div>
<div class="name">{{ item.name }}</div>
<div class="line">
<div class="inner-line" :style="{width: (item.num / areaList[0].num)* 100 + '%' }"></div>
<div class="inner-line" :style="{ width: (item.num / areaList[0].num) * 100 + '%' }"></div>
</div>
<div class="num">{{ item.numtext }}</div>
<div class="more">{{ `${item.insNum}家机构 >` }}</div>
......@@ -128,9 +134,7 @@
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="box-footer-center">
{{
"马尔科·卢比奥的政治资金主要依赖于一个由亿万富翁、特定行业利益集团及通过​“超级政治行动委员会”​​ 运作的大额捐款网络。"
}}
{{ currentPersonName }}的政治资金主要依赖于一个由亿万富翁、特定行业利益集团及通过​“超级政治行动委员会”​​ 运作的大额捐款网络。
</div>
<div class="box-footer-right">
<img src="@/assets/icons/box-footer-right-icon.png" alt="" />
......@@ -142,12 +146,13 @@
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ref, onMounted, watch, computed } from "vue";
import { getBillPoliContribution, getBillMainPoliContribution, getBillPersonPoliContribution } from "@/api/deepdig";
import setChart from "@/utils/setChart";
import getPieChart from "./utils/piechart";
import getSankeyChart from "./utils/sankey"
import getSankeyChart from "./utils/sankey";
import Img1 from "./assets/images/1.png";
import Img2 from "./assets/images/2.png";
......@@ -168,196 +173,474 @@ import Mzd from "@/assets/icons/mzd.png";
const activeBtnIndex = ref(0);
const itemActiveIndex = ref(0);
const majorList = ref([
{
name: "参议院",
data1: [
{
name: "共和党",
img: Ghd,
num: "$1,550,000"
},
{
name: "民主党",
img: Mzd,
num: "$298,000"
}
],
data2: [
{
img: Img1,
name: "马尔科·卢比奥",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$1,550,000"
},
{
img: Img2,
name: "史蒂夫·戴恩斯",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$820,000"
},
{
img: Img3,
name: "伯尼·莫雷诺",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$50,000"
},
{
img: Img4,
name: "戴夫·麦考密克",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$50,000"
},
{
img: Img5,
name: "蒂姆·希伊",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$35,000"
},
{
img: Img6,
name: "史蒂夫·戴恩斯",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$35,000"
},
{
img: Img7,
name: "皮特·赫格塞思",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$35,000"
},
{
img: Img8,
name: "安妮·海瑟薇",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$35,000"
},
{
img: Img9,
name: "贾米森·格里尔",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$35,000"
},
{
img: Img10,
name: "迈克·华尔兹",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$35,000"
}
]
const currentPersonName = computed(() => {
if (mainPoliContribution.value && mainPoliContribution.value[itemActiveIndex.value]) {
return mainPoliContribution.value[itemActiveIndex.value].name;
}
]);
return "";
});
const chart1Data = ref(
// const majorList = ref([
// {
// name: "参议院",
// data1: [
// {
// name: "共和党",
// img: Ghd,
// num: "$1,550,000"
// },
// {
// name: "民主党",
// img: Mzd,
// num: "$298,000"
// }
// ],
// data2: [
// {
// img: Img1,
// name: "马尔科·卢比奥",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$1,550,000"
// },
// {
// img: Img2,
// name: "史蒂夫·戴恩斯",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$820,000"
// },
// {
// img: Img3,
// name: "伯尼·莫雷诺",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$50,000"
// },
// {
// img: Img4,
// name: "戴夫·麦考密克",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$50,000"
// },
// {
// img: Img5,
// name: "蒂姆·希伊",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img6,
// name: "史蒂夫·戴恩斯",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img7,
// name: "皮特·赫格塞思",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img8,
// name: "安妮·海瑟薇",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img9,
// name: "贾米森·格里尔",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img10,
// name: "迈克·华尔兹",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// }
// ]
// },
// {
// name: "众议院",
// data1: [
// {
// name: "共和党",
// img: Ghd,
// num: "$1,550,000"
// },
// {
// name: "民主党",
// img: Mzd,
// num: "$298,000"
// }
// ],
// data2: [
// {
// img: Img1,
// name: "马尔科·卢比奥",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$1,550,000"
// },
// {
// img: Img2,
// name: "史蒂夫·戴恩斯",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$820,000"
// },
// {
// img: Img3,
// name: "伯尼·莫雷诺",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$50,000"
// },
// {
// img: Img4,
// name: "戴夫·麦考密克",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$50,000"
// },
// {
// img: Img5,
// name: "蒂姆·希伊",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img6,
// name: "史蒂夫·戴恩斯",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img7,
// name: "皮特·赫格塞思",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img8,
// name: "安妮·海瑟薇",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img9,
// name: "贾米森·格里尔",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img10,
// name: "迈克·华尔兹",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// }
// ]
// }
// ]);
)
const chart1Data = ref();
const areaList = ref([
{
name: "半导体",
num: 186000,
numtext: "$186,000",
insNum: 8
},
{
name: "电子设备",
num: 180000,
numtext: "$180,000",
insNum: 5
},
{
name: "显示技术",
num: 171000,
numtext: "$171,000",
insNum: 2
},
{
name: "新能源",
num: 75000,
numtext: "$75,000",
insNum: 3
},
{
name: "通信设备",
num: 70000,
numtext: "$70,000",
insNum: 2
},
const areaList = ref([]);
const chart2Data = ref([]);
const chart2ColorList = ref(["#4096FF", "#FFA39E", "#ADC6FF", "#FFC069", "#B5F5EC", "#B37FEB", "#D6E4FF"]);
const sankeyColors = [
"#5470c6",
"#91cc75",
"#fac858",
"#ee6666",
"#73c0de",
"#3ba272",
"#fc8452",
"#9a60b4",
"#ea7ccc",
"#a2c0f1",
"#f596aa",
"#e6b422",
"#4b2c20"
];
const partyContributionList = ref([
{
name: "汽车",
num: 52000,
numtext: "$52,000",
insNum: 2
name: "共和党",
img: Ghd,
num: "$0"
},
{
name: "其他",
num: 36000,
numtext: "$36,000",
insNum: 1
name: "民主党",
img: Mzd,
num: "$0"
}
]);
const chart2Data = ref([
{
name: "半导体",
value: 50
},
{
name: "电子设备",
value: 46
},
{
name: "显示技术",
value: 40
},
{
name: "新能源",
value: 32
},
{
name: "通信设备",
value: 31
},
{
name: "汽车",
value: 30
},
{
name: "其他",
value: 24
// 获取党派政治献金
const poliContribution = ref();
const getPoliContribution = async () => {
const currentType = activeBtnIndex.value === 0 ? "参议院" : "众议院";
const params = {
id: window.sessionStorage.getItem("billId"),
personCongress: currentType
};
try {
const res = await getBillPoliContribution(params);
if (res.code === 200) {
poliContribution.value = res.data;
// 重置为默认值
partyContributionList.value = [
{ name: "共和党", img: Ghd, num: "$0" },
{ name: "民主党", img: Mzd, num: "$0" }
];
if (res.data && res.data.length > 0) {
res.data.forEach(item => {
const totalAmount = item.totalJe || 0;
if (item.dp === "Republican") {
partyContributionList.value[0].num = `$${totalAmount.toLocaleString()}`;
} else {
partyContributionList.value[1].num = `$${totalAmount.toLocaleString()}`;
}
});
} else {
partyContributionList.value[0].num = "$0";
partyContributionList.value[1].num = "$0";
}
} else {
partyContributionList.value = [
{ name: "共和党", img: Ghd, num: "$0" },
{ name: "民主党", img: Mzd, num: "$0" }
];
}
} catch (error) {
partyContributionList.value = [
{ name: "共和党", img: Ghd, num: "$0" },
{ name: "民主党", img: Mzd, num: "$0" }
];
}
]);
};
const chart2ColorList = ref(["#4096FF", "#FFA39E", "#ADC6FF", "#FFC069", "#B5F5EC", "#B37FEB", "#D6E4FF"]);
watch(activeBtnIndex, () => {
itemActiveIndex.value = 0;
getPoliContribution();
getMainPoliContribution();
});
onMounted(() => {
let chart1 = getSankeyChart()
setChart(chart1, 'chart1')
// 获取主要议员政治献金
const mainPoliContribution = ref();
const clearPersonDetails = () => {
personPoliContribution.value = null;
fullSourceList.value = [];
renderSankeyChart();
let chart2 = getPieChart(chart2Data.value, chart2ColorList.value);
chart2Data.value = [];
areaList.value = [];
let chart2 = getPieChart([], chart2ColorList.value);
setChart(chart2, "chart2");
};
const getMainPoliContribution = async () => {
const currentType = activeBtnIndex.value === 0 ? "参议院" : "众议院";
const params = {
id: window.sessionStorage.getItem("billId"),
personCongress: currentType
};
try {
const res = await getBillMainPoliContribution(params);
// 打印主要议员政治献金
console.log("主要议员政治献金:", res);
if (res.code === 200) {
mainPoliContribution.value = res.data.map(item => ({
...item,
formattedTotalJe: `$${(item.totalJe || 0).toLocaleString()}`
}));
// 默认选中第一个人
if (mainPoliContribution.value.length > 0) {
handlePersonClick(mainPoliContribution.value[0], 0);
} else {
clearPersonDetails();
}
} else {
mainPoliContribution.value = [];
clearPersonDetails();
}
} catch (error) {
mainPoliContribution.value = [];
clearPersonDetails();
}
};
// Sankey data state
const fullSourceList = ref([]);
const showAllSankeyData = ref(false);
const renderSankeyChart = () => {
const sourceList = showAllSankeyData.value ? fullSourceList.value : fullSourceList.value.slice(0, 5);
if (sourceList.length > 0) {
const currentPerson = mainPoliContribution.value[itemActiveIndex.value];
const personName = currentPerson ? currentPerson.name : "Person";
const totalAmount = sourceList.reduce((sum, item) => sum + (item.amount || 0), 0);
const nodes = [
{
name: personName,
value: totalAmount,
label: { position: 'left' },
itemStyle: {
color: '#FF1493'
}
},
...sourceList.map((item, index) => ({
name: item.orgName,
value: item.amount,
itemStyle: {
color: sankeyColors[index % sankeyColors.length]
}
}))
];
const links = sourceList.map(item => ({
source: item.orgName,
target: personName,
value: item.amount
}));
let chart1 = getSankeyChart(nodes, links);
setChart(chart1, "chart1");
} else {
let chart1 = getSankeyChart([], []);
setChart(chart1, "chart1");
}
};
const toggleSankeyData = () => {
showAllSankeyData.value = !showAllSankeyData.value;
renderSankeyChart();
};
// 获取人员政治献金来源及行业领域分布
const personPoliContribution = ref();
const getPersonPoliContribution = async (personId) => {
if (!personId) return;
const params = {
id: window.sessionStorage.getItem("billId"),
personId: personId
};
try {
const res = await getBillPersonPoliContribution(params);
// 打印人员政治献金
console.log("人员政治献金:", res);
if (res.code === 200 && res.data) {
personPoliContribution.value = res.data;
fullSourceList.value = res.data.sourceList || [];
showAllSankeyData.value = false; // Reset to default (top 5)
renderSankeyChart();
// Update Industry List (Chart 2 and List)
const industries = res.data.industryList || [];
// Update Chart 2 Data
chart2Data.value = industries.map(item => ({
name: item.industryName,
value: item.amount
}));
// Re-render Chart 2
let chart2 = getPieChart(chart2Data.value, chart2ColorList.value);
setChart(chart2, "chart2");
// Update List Data
// Sort by amount desc to ensure first item is max for progress bar
const sortedIndustries = [...industries].sort((a, b) => (b.amount || 0) - (a.amount || 0));
areaList.value = sortedIndustries.map(item => ({
name: item.industryName,
num: item.amount,
numtext: `$${(item.amount || 0).toLocaleString()}`,
insNum: item.orgNum
}));
} else {
personPoliContribution.value = [];
fullSourceList.value = [];
renderSankeyChart();
chart2Data.value = [];
areaList.value = [];
let chart2 = getPieChart([], chart2ColorList.value);
setChart(chart2, "chart2");
}
} catch (error) {
console.error(error);
personPoliContribution.value = [];
fullSourceList.value = [];
renderSankeyChart();
chart2Data.value = [];
areaList.value = [];
let chart2 = getPieChart([], chart2ColorList.value);
setChart(chart2, "chart2");
}
};
const handlePersonClick = (item, index) => {
itemActiveIndex.value = index;
if (item && item.personid) {
getPersonPoliContribution(item.personid);
}
};
onMounted(() => {
getPoliContribution();
getMainPoliContribution();
let chart1 = getSankeyChart();
setChart(chart1, "chart1");
let chart2 = getPieChart(chart2Data.value, chart2ColorList.value);
setChart(chart2, "chart2");
});
</script>
......@@ -405,6 +688,7 @@ onMounted(() => {
border-radius: 4px;
background: var(--btn-plain-bg-color);
border: 1px solid var(--btn-plain-border-color);
cursor: pointer;
}
.btnActive {
color: var(--btn-active-text-color);
......@@ -417,10 +701,19 @@ onMounted(() => {
right: 12px;
top: 14px;
display: flex;
gap: 4px;
gap: 16px;
.more-btn {
color: rgba(5, 95, 194, 1);
font-size: 14px;
cursor: pointer;
margin-top: 2px;
&:hover {
opacity: 0.8;
}
}
.right-icon {
width: 28px;
height: 28px;
width: 24px;
height: 24px;
img {
width: 100%;
height: 100%;
......@@ -551,6 +844,7 @@ onMounted(() => {
margin-top: 6px;
width: 498px;
height: 640px;
overflow: auto;
.item {
display: flex;
position: relative;
......@@ -672,7 +966,7 @@ onMounted(() => {
.box3-main-right {
width: 518px;
margin-left: 10px;
overflow: hidden;
overflow: auto;
.box3-main-right-item {
height: 60px;
width: 518px;
......@@ -707,7 +1001,7 @@ onMounted(() => {
width: 166px;
height: 8px;
.inner-line {
height: 8px;
height: 8px;
border-radius: 0px 4px 4px 0px;
background: linear-gradient(270deg, rgba(5, 95, 194, 1), rgba(5, 95, 194, 0) 100%);
}
......
......@@ -14,14 +14,19 @@ const getPieChart = (data,colorList) => {
},
label: {
alignTo: 'edge',
formatter: '{name|{b}}\n{time|{c} 条 {d}%}',
formatter: '{name|{b}}\n{time|{d}%}',
minMargin: 5,
edgeDistance: 10,
lineHeight: 15,
rich: {
time: {
fontSize: 10,
color: '#999'
fontSize: 12,
color: '#666'
},
name: {
fontSize: 14,
color: '#333',
fontWeight: 'bold'
}
}
},
......
const getSankeyChart = () => {
const getSankeyChart = (data = [], links = []) => {
const option = {
tooltip: {
trigger: 'item',
triggerOn: 'mousemove'
},
series: {
type: 'sankey',
layout: 'none',
left: '5%',
right: '5%',
left: '1%',
right: '1%',
top: '5%',
bottom: '5%',
emphasis: {
focus: 'adjacency'
},
nodeWidth: 50,
nodeGap: 2,
layoutIterations: 32,
lineStyle: {
color: 'source',
curveness: 0.5
},
label: {
show: true,
formatter: function (params) {
return `${params.name} $${params.value}`;
return `${params.name} $${params.value.toLocaleString()}`;
},
position: 'right',
textStyle: {
fontSize: '16px',
color: '#555'
}
fontSize: 16,
color: '#555'
},
data: [
{
name: '马尔科·卢比奥',
label: {
position: 'left'
}
},
{
name: '成长俱乐部'
},
{
name: '埃利奥特管理公司'
},
{
name: '高盛集团'
},
{
name: '黑石集团'
},
{
name: '佛罗里达水晶'
},
{
name: '美国银行'
}
],
links: [
{
source: '成长俱乐部',
target: '马尔科·卢比奥',
value: 680751
},
{
source: '埃利奥特管理公司',
target: '马尔科·卢比奥',
value: 440120
},
{
source: '高盛集团',
target: '马尔科·卢比奥',
value: 371517
},
{
source: '黑石集团',
target: '马尔科·卢比奥',
value: 259321
},
{
source: '佛罗里达水晶',
target: '马尔科·卢比奥',
value: 203775
},
{
source: '美国银行',
target: '马尔科·卢比奥',
value: 150892
}
]
data: data,
links: links
}
};
......
......@@ -95,58 +95,117 @@
<div class="box3-main-center-header-box6">关键议员</div>
</div>
<div class="box3-main-center-content">
<div class="box3-main-center-content-box">
<div class="item" v-for="(item, index) in voteAnalysisList1" :key="index">
<div class="box3-main-center-content-box" v-for="item in voteAnalysisList" :key="item.actionId">
<div class="item">
<div class="item-box1">
<div class="box1-left">
<div class="icon" v-if="item.nameIcon">
<img :src="item.nameIcon" alt="" />
</div>
<div style="height: 80px;">
<div class="name" :class="{ nameBlod: item.nameBold }">
{{ item.name }}
<div style="width: 100%; display: flex; flex-direction: column; align-items: flex-end;">
<div class="name nameBlod" :title="item.actionTitle" style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;">
{{ item.actionTitle }}
</div>
<div class="time">
{{ item.time }}
{{ formatDate(item.actionDate) }}
</div>
</div>
</div>
<div class="box1-right">
<div class="box1-right-top">
<el-progress :percentage="item.supportRate" :show-text="false"> </el-progress>
<el-progress :percentage="Number(item.agreePercent)" :show-text="false" color="#1677FF"> </el-progress>
</div>
<div class="box1-right-bottom">
<el-progress :percentage="item.againistRate" :show-text="false"> </el-progress>
<el-progress :percentage="Number(item.againstPercent)" :show-text="false" color="#FF9054"> </el-progress>
</div>
</div>
</div>
<div class="item-box2">
<div class="box2-1">{{ item.support + "票" }}</div>
<div class="box2-2">{{ item.againist + "票" }}</div>
<div class="box2-1" style="color: #1677FF">{{ item.agreeCount + "票" }}</div>
<div class="box2-2" style="color: #FF9054">{{ item.againstCount + "票" }}</div>
</div>
<div class="item-box3">
<div class="box3-1">{{ item.supportRank }}</div>
<div class="box3-2">{{ item.againistRank }}</div>
<div class="box3-1"></div>
<div class="box3-2"></div>
</div>
<div class="item-box4">
<div class="box4-1">{{ item.supportRate + "%" }}</div>
<div class="box4-2">{{ item.againistRate + "%" }}</div>
<div class="box4-1" style="color: #1677FF">{{ item.agreePercent + "%" }}</div>
<div class="box4-2" style="color: #FF9054">{{ item.againstPercent + "%" }}</div>
</div>
<div class="item-box5"></div>
<div class="item-box6">
<el-icon size="20" color="#555"><ArrowDownBold /></el-icon>
</div>
</div>
<div class="item">
<div class="item-box1">
<div class="box1-left">
<div class="icon">
<img :src="MZD" alt="" />
</div>
<div class="name">民主党</div>
</div>
<div class="box1-right">
<div class="box1-right-top">
<el-progress :percentage="Number(item.dagreePercent)" :show-text="false" color="#85b4ff"> </el-progress>
</div>
<div class="box1-right-bottom">
<el-progress :percentage="Number(item.dagainstPercent)" :show-text="false" color="#FF9054"> </el-progress>
</div>
</div>
</div>
<div class="item-box2">
<div class="box2-1" style="color: #1677FF">{{ item.dagreeCount + "票" }}</div>
<div class="box2-2" style="color: #FF9054">{{ item.dagainstCount + "票" }}</div>
</div>
<div class="item-box3"></div>
<div class="item-box4">
<div class="box4-1" style="color: #1677FF">{{ item.dagreePercent + "%" }}</div>
<div class="box4-2" style="color: #FF9054">{{ item.dagainstPercent + "%" }}</div>
</div>
<div class="item-box5">
<div class="box5-1" v-if="item.people">{{ item.people+' 人' }}</div>
<div class="box5-2" v-if="item.peopleRank">{{ `( ${item.peopleRank} )` }}</div>
<div class="box5-1" style="color: #CE4F51">{{ item.dreverseCount + "人" }}</div>
</div>
<div class="item-box6">
<div class="img-box" v-if="item.keyUser">
<img :src="item.keyUser" alt="" />
<div class="img-box" v-if="item.dpersonImageUrl">
<img :src="item.dpersonImageUrl" alt="" />
</div>
<div v-else>
<el-icon size="20" color="#555"><ArrowDownBold /></el-icon>
</div>
</div>
<div class="item">
<div class="item-box1">
<div class="box1-left">
<div class="icon">
<img :src="GHD" alt="" />
</div>
<div class="name">共和党</div>
</div>
<div class="box1-right">
<div class="box1-right-top">
<el-progress :percentage="Number(item.ragreePercent)" :show-text="false" color="#1677FF"> </el-progress>
</div>
<div class="box1-right-bottom">
<el-progress :percentage="Number(item.ragainstPercent)" :show-text="false" color="#ffdcc8"> </el-progress>
</div>
</div>
</div>
<div class="item-box2">
<div class="box2-1" style="color: #1677FF">{{ item.ragreeCount + "票" }}</div>
<div class="box2-2" style="color: #FF9054">{{ item.ragainstCount + "票" }}</div>
</div>
<div class="item-box3"></div>
<div class="item-box4">
<div class="box4-1" style="color: #1677FF">{{ item.ragreePercent + "%" }}</div>
<div class="box4-2" style="color: #FF9054">{{ item.ragainstPercent + "%" }}</div>
</div>
<div class="item-box5">
<div class="box5-1" style="color: #CE4F51">{{ item.rreverseCount + "人" }}</div>
</div>
<div class="item-box6">
<div class="img-box" v-if="item.rpersonImageUrl">
<img :src="item.rpersonImageUrl" alt="" />
</div>
</div>
</div>
</div>
<div class="box3-main-center-content-box">
<!-- <div class="box3-main-center-content-box">
<div class="item" v-for="(item, index) in voteAnalysisList2" :key="index">
<div class="item-box1">
<div class="box1-left">
......@@ -196,8 +255,8 @@
</div>
</div>
</div>
</div>
<div class="box3-main-center-content-box">
</div> -->
<!-- <div class="box3-main-center-content-box">
<div class="item" v-for="(item, index) in voteAnalysisList3" :key="index">
<div class="item-box1">
<div class="box1-left">
......@@ -298,7 +357,7 @@
</div>
</div>
</div>
</div>
</div> -->
</div>
</div>
<div class="box3-main-footer">
......@@ -597,6 +656,15 @@ const handleGetBillAmeAnalyzeCount = async () => {
};
// 获取投票分析
const voteAnalysisList = ref([]);
const formatDate = (dateStr) => {
if (!dateStr) return "";
const date = new Date(dateStr);
const y = date.getFullYear();
const m = date.getMonth() + 1;
const d = date.getDate();
return `${y}年${m}月${d}日`;
};
const handleGetBillVoteAnalyze = async () => {
const params = {
id: window.sessionStorage.getItem("billId")
......@@ -604,6 +672,7 @@ const handleGetBillVoteAnalyze = async () => {
try {
const res = await getBillTp(params);
console.log("投票分析", res);
voteAnalysisList.value = res.data;
} catch (error) {
console.error("投票分析 error", error);
}
......@@ -1152,8 +1221,10 @@ onMounted(async () => {
}
}
.box3-main-center-content {
height: 682px;
overflow: auto;
.box3-main-center-content-box {
width: 830px;
width: 805px;
height: 160px;
box-sizing: border-box;
border: 1px solid rgba(243, 243, 244, 1);
......
......@@ -35,12 +35,12 @@
<div
class="item"
:class="{ itemActive: companyActiveIndex === idx }"
@click="handleClickCompany(idx)"
@click="handleClickCompany(val, idx)"
v-for="(val, idx) in curCompanyList"
:key="idx"
>
<div class="id">{{ idx + 1 }}</div>
<div class="title" :class="{ titleActive: companyActiveIndex === idx }">
<div class="id">{{ (currentPage - 1) * pageSize + idx + 1 }}</div>
<div class="title" :class="{ titleActive: companyActiveIndex === ((currentPage - 1) * pageSize + idx) }">
{{ val.name }}
</div>
<div class="icon">
......@@ -169,12 +169,12 @@
<div class="dialog-box1">
<div class="dialog-box1-header">
<div class="icon">
<img :src="companyInfo.data1.icon" alt="" />
<img :src="companyInfo.data1?.icon" alt="" />
</div>
<div class="dialog-box1-title">{{ companyInfo.data1.title }}</div>
<div class="dialog-box1-title">{{ companyInfo.data1?.title }}</div>
</div>
<div class="dialog-box1-main">
<div class="item" v-for="(val, idx) in companyInfo.data1.list" :key="idx">
<div class="item" v-for="(val, idx) in companyInfo.data1?.list" :key="idx">
<div class="item-left">
<!-- <img :src="uncheckIcon" alt=""> -->
<img :src="checkedIcon" alt="" />
......@@ -186,18 +186,18 @@
<div class="dialog-box2">
<div class="dialog-box2-header">
<div class="icon">
<img :src="companyInfo.data2.icon" alt="" />
<img :src="companyInfo.data2?.icon" alt="" />
</div>
<div class="dialog-box2-title">{{ companyInfo.data2.title }}</div>
<div class="dialog-box2-title">{{ companyInfo.data2?.title }}</div>
</div>
<div class="dialog-box2-main" id="chart2"></div>
</div>
<div class="dialog-box3">
<div class="dialog-box3-header">
<div class="icon">
<img :src="companyInfo.data3.icon" alt="" />
<img :src="companyInfo.data3?.icon" alt="" />
</div>
<div class="dialog-box3-title">{{ companyInfo.data3.title }}</div>
<div class="dialog-box3-title">{{ companyInfo.data3?.title }}</div>
</div>
<div class="dialog-box3-main" id="chart3"></div>
</div>
......@@ -210,7 +210,7 @@
<script setup>
import { ref, onMounted, nextTick, computed } from "vue";
import * as echarts from "echarts";
import { getCompanyList, getIndustryHyly, getHylyList } from "@/api/influence";
import { getCompanyList, getIndustryHyly, getHylyList, getCompanyDetail } from "@/api/influence";
import getBarChart from "./utils/barChart";
import getLineChart from "./utils/lineChart";
import getBarChart1 from "./utils/barChart1";
......@@ -232,19 +232,20 @@ import Fishbone from "./components/fishbone.vue";
import CompanyImg from "./assets/images/symbol.png";
const isShowCompanyDialog = ref(true);
const isShowCompanyDialog = ref(false);
const box1BtnActive = ref(0);
const handleClickBox1Btn = (industry, index) => {
box1BtnActive.value = index;
curHylyId.value = industry.hylyid;
curHylyId.value = industry.id;
handleGetCompanyListById();
};
// 绘制echarts图表
const setChart = (option, chartId) => {
let chartDom = document.getElementById(chartId);
if (!chartDom) return;
chartDom.removeAttribute("_echarts_instance_");
let chart = echarts.init(chartDom);
chart.setOption(option);
......@@ -252,34 +253,45 @@ const setChart = (option, chartId) => {
};
const chart1Data = ref({
// name: ["新能源", "半导体", "跨境电商", "金融业", "军工", "贸易"],
// value: [109, 95, 79, 25, 21, 50],
name: [],
value: [],
});
const industryActiveIndex = ref(0);
const companyActiveIndex = ref(0);
const showAllChart1 = ref(false);
const fullChart1Data = ref({ name: [], value: [] });
const handleClickCompany = index => {
companyActiveIndex.value = index;
isShowCompanyDialog.value = true;
// const handleToggleChart1 = () => {
// showAllChart1.value = !showAllChart1.value;
// renderChart1();
// };
const renderChart1 = () => {
let dataName = fullChart1Data.value.name;
let dataValue = fullChart1Data.value.value;
// if (!showAllChart1.value && dataName.length > 5) {
// dataName = dataName.slice(0, 5);
// dataValue = dataValue.slice(0, 5);
// }
setTimeout(() => {
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]
};
let chart1 = getBarChart(dataName, dataValue);
setChart(chart1, "chart1");
};
let chart2 = getLineChart(chart2Data.dataX, chart2Data.dataY);
setChart(chart2, "chart2");
const industryActiveIndex = ref(0);
const companyActiveIndex = ref(0);
const curCompanyId = ref("");
const chart3Data = {
name: ["2023Q3", "2023Q4", "2024Q1", "2024Q2", "2024Q3", "2024Q4", "2025Q1", "2025Q2"],
value: [49, 53, 52, 54, 52, 50, 51, 54]
};
const handleClickCompany = (val, index) => {
companyActiveIndex.value = (currentPage.value - 1) * pageSize.value + index;
if (val) {
curCompanyId.value = val.id;
handleGetCompanyDetail();
companyInfo.value.name = val.name;
companyInfo.value.status = val.status || companyInfo.value.status;
}
isShowCompanyDialog.value = true;
let chart3 = getBarChart1(chart3Data.name, chart3Data.value);
setChart(chart3, "chart3");
}, 100);
};
const pageSize = ref(10);
......@@ -307,44 +319,46 @@ const industryList = ref([
]);
const companyInfo = ref({
logo: CompanyLogo,
name: "宁德时代新能源科技股份有限公司",
status: "down",
changeRate: 0.16,
data1: {
icon: icon1,
title: "影响条款",
list: [
"严格限制外国敏感实体(FEOC)参与补贴",
"取消电动汽车补贴(2025年底生效)",
"任何实体若与被禁止外国实体签订超100万美元的关键技术许可协议,则不得向其提供联邦补贴"
]
},
data2: {
icon: icon2,
title: "融资情况",
data: {
time: ["2025-06", "2025-07", "2025-08"],
value: [1.12, 1.42, 1.5]
}
},
data3: {
icon: icon3,
title: "研发投入",
data: {
time: ["2023Q3", "2023Q4", "2024Q1", "2024Q2", "2024Q3", "2024Q4", "2025Q1", "2025Q2"],
value: [50, 53, 52, 54, 58, 60, 51, 56, 64]
}
}
// logo: CompanyLogo,
// name: "宁德时代新能源科技股份有限公司",
// status: "down",
// changeRate: 0.16,
// data1: {
// icon: icon1,
// title: "影响条款",
// list: [
// "严格限制外国敏感实体(FEOC)参与补贴",
// "取消电动汽车补贴(2025年底生效)",
// "任何实体若与被禁止外国实体签订超100万美元的关键技术许可协议,则不得向其提供联邦补贴"
// ]
// },
// data2: {
// icon: icon2,
// title: "融资情况",
// data: {
// time: ["2025-06", "2025-07", "2025-08"],
// value: [1.12, 1.42, 1.5]
// }
// },
// data3: {
// icon: icon3,
// title: "研发投入",
// data: {
// time: ["2023Q3", "2023Q4", "2024Q1", "2024Q2", "2024Q3", "2024Q4", "2025Q1", "2025Q2"],
// value: [50, 53, 52, 54, 58, 60, 51, 56, 64]
// }
// }
});
// 获取行业领域列表
const handleGetHylyList = async () => {
try {
const res = await getHylyList();
console.log("行业领域字典列表", res);
industryList.value = res.data.slice(0,6)
curHylyId.value = res.data[0].id;
// console.log("行业领域字典列表", res);
industryList.value = res.data
if (res.data && res.data.length > 0) {
curHylyId.value = res.data[0].id;
}
} catch (error) {}
};
......@@ -353,14 +367,17 @@ const curHylyId = ref("");
// 根据行业领域id获取公司列表
const handleGetCompanyListById = async () => {
const params = {
// id: curHylyId.value
id: '0100'
id: curHylyId.value
};
try {
const res = await getCompanyList(params);
// console.log('根据行业id获取公司里列表', res);
if (res.code === 200 && res.data.length) {
companyList.value = res.data;
currentPage.value = 1;
nextTick(() => {
handleClickCompany(companyList.value[0], 0);
});
} else {
companyList.value = [];
}
......@@ -370,173 +387,325 @@ const handleGetCompanyListById = async () => {
// 根据法案ID 获取行业领域统计
const handleGetIndustryHyly = async () => {
const params = {
id: 1
id: window.sessionStorage.getItem("billId")
};
try {
const res = await getIndustryHyly(params);
// console.log('行业领域统计', res);
chart1Data.value.name = res.data.map(item => {
const data = res.data || [];
data.sort((a, b) => b.companyNum - a.companyNum);
fullChart1Data.value.name = data.map(item => {
return item.hylyName;
});
chart1Data.value.value = res.data.map(item => {
fullChart1Data.value.value = data.map(item => {
return item.companyNum;
});
renderChart1();
} catch (error) {}
};
// 根据法案id,公司id,行业领域id获取公司的详情
const handleGetCompanyDetail = async () => {
const params = {
billId: window.sessionStorage.getItem("billId"),
companyId: curCompanyId.value,
id: curHylyId.value
};
try {
const res = await getCompanyDetail(params);
console.log('根据法案id,公司id,行业领域id获取公司的详情', res);
if (res.code === 200 && res.data) {
const data = res.data;
companyInfo.value = {
logo: data.imageUrl || CompanyLogo,
name: data.name || "",
status: "", // 接口未返回,暂时留空或保留默认
changeRate: 0, // 接口未返回,暂时留空
data1: {
icon: icon1,
title: "影响条款",
list: (data.tkContentList || []).filter(item => item) // 过滤掉 null
},
data2: {
icon: icon2,
title: "融资情况",
data: {
time: (data.marketCapList || []).map(item => item.time),
value: (data.marketCapList || []).map(item => item.marketCap)
}
},
data3: {
icon: icon3,
title: "研发投入",
data: {
time: (data.investmentList || []).map(item => item.time),
value: (data.investmentList || []).map(item => item.investment)
}
}
};
// 更新左侧关系图表数据
const relationList = data.relationNameList || [];
// 更新树形图数据
const treeChildren = relationList.map((name, index) => ({
id: index,
name: name,
symbolSize: 30,
value: 5,
symbol: `image://${CompanyImg}`
}));
treeData.value = [{
id: relationList.length,
name: data.name,
symbolSize: 50,
value: 10,
symbol: `image://${CompanyImg}`,
children: treeChildren
}];
if (relationList.length > 0) {
const centerNode = {
id: relationList.length, // 中心节点 ID
name: data.name,
symbolSize: 50,
value: 10, // 权重
symbol: `image://${CompanyImg}`,
x: 400, // 假设容器宽度800,中心点x坐标
y: 300, // 假设容器高度600,中心点y坐标
fixed: true // 固定中心点位置
};
const radius = 200; // 圆的半径
const newNodes = relationList.map((name, index) => {
const angle = (index / relationList.length) * 2 * Math.PI; // 计算每个节点的角度
return {
id: index,
name: name,
symbolSize: 30,
value: 5,
symbol: `image://${CompanyImg}`,
x: 400 + radius * Math.cos(angle), // 计算x坐标
y: 300 + radius * Math.sin(angle), // 计算y坐标
fixed: true // 固定位置,形成圆形布局
};
});
newNodes.push(centerNode);
const newLinks = relationList.map((_, index) => ({
source: index,
target: relationList.length // 指向中心节点
}));
nodes.value = newNodes;
links.value = newLinks;
} else {
// 列表为空,只展示中心节点
nodes.value = [{
id: 0,
name: data.name,
symbolSize: 50,
value: 10,
symbol: `image://${CompanyImg}`,
x: 400,
y: 300,
fixed: true
}];
links.value = [];
}
// 重新渲染图表
nextTick(() => {
const chart2Data = companyInfo.value.data2.data;
if (chart2Data.time && chart2Data.time.length > 0) {
let chart2 = getLineChart(chart2Data.time, chart2Data.value);
setChart(chart2, "chart2");
} else {
let chartDom = document.getElementById("chart2");
if (chartDom) {
echarts.dispose(chartDom);
chartDom.innerHTML = ""; // 清空容器内容
}
}
const chart3Data = companyInfo.value.data3.data;
if (chart3Data.time && chart3Data.time.length > 0) {
let chart3 = getBarChart1(chart3Data.time, chart3Data.value);
setChart(chart3, "chart3");
} else {
let chartDom = document.getElementById("chart3");
if (chartDom) {
echarts.dispose(chartDom);
chartDom.innerHTML = ""; // 清空容器内容
}
}
let graphChart = getGraphChart(nodes.value, links.value);
setChart(graphChart, "graphChart");
});
} else {
companyInfo.value = {};
}
} catch (error) {}
};
const nodes = ref([
{
id: 0,
name: "泰丰先行",
// category: 0,
symbolSize: 30,
value: 8,
symbol: `image://${CompanyImg}`
},
{
id: 1,
name: "国轩高科",
// category: 0,
symbolSize: 30,
value: 9,
symbol: `image://${CompanyImg}`
},
{
id: 2,
name: "智方纳米",
// category: 2,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
},
{
id: 3,
name: "香百科技",
// category: 1,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 4,
name: "格林滨",
// category: 2,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 5,
name: "江西紫宸",
// category: 2,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
},
{
id: 6,
name: "紫江企业",
// category: 4,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 7,
name: "大而美法案",
// category: 4,
symbolSize: 50,
value: 5,
symbol: `image://${CompanyImg}`
},
{
id: 8,
name: "比亚迪",
// category: 0,
symbolSize: 30,
value: 10,
symbol: `image://${CompanyImg}`
},
{
id: 9,
name: "铜陵有色",
// category: 3,
symbolSize: 30,
value: 8,
symbol: `image://${CompanyImg}`
},
{
id: 10,
name: "长盛精密",
// category: 1,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
},
{
id: 11,
name: "天合光能",
// category: 0,
symbolSize: 30,
value: 8,
symbol: `image://${CompanyImg}`
},
{
id: 12,
name: "昆仑化学",
// category: 2,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 13,
name: "嘉源科技",
// category: 1,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 14,
name: "华阳集团",
// category: 4,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
},
{
id: 15,
name: "海辰智能",
// category: 1,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
}
// {
// id: 0,
// name: "泰丰先行",
// // category: 0,
// symbolSize: 30,
// value: 8,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 1,
// name: "国轩高科",
// // category: 0,
// symbolSize: 30,
// value: 9,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 2,
// name: "智方纳米",
// // category: 2,
// symbolSize: 30,
// value: 7,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 3,
// name: "香百科技",
// // category: 1,
// symbolSize: 30,
// value: 6,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 4,
// name: "格林滨",
// // category: 2,
// symbolSize: 30,
// value: 6,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 5,
// name: "江西紫宸",
// // category: 2,
// symbolSize: 30,
// value: 7,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 6,
// name: "紫江企业",
// // category: 4,
// symbolSize: 30,
// value: 6,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 7,
// name: "大而美法案",
// // category: 4,
// symbolSize: 50,
// value: 5,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 8,
// name: "比亚迪",
// // category: 0,
// symbolSize: 30,
// value: 10,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 9,
// name: "铜陵有色",
// // category: 3,
// symbolSize: 30,
// value: 8,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 10,
// name: "长盛精密",
// // category: 1,
// symbolSize: 30,
// value: 7,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 11,
// name: "天合光能",
// // category: 0,
// symbolSize: 30,
// value: 8,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 12,
// name: "昆仑化学",
// // category: 2,
// symbolSize: 30,
// value: 6,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 13,
// name: "嘉源科技",
// // category: 1,
// symbolSize: 30,
// value: 6,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 14,
// name: "华阳集团",
// // category: 4,
// symbolSize: 30,
// value: 7,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 15,
// name: "海辰智能",
// // category: 1,
// symbolSize: 30,
// value: 7,
// symbol: `image://${CompanyImg}`
// }
]);
const links = ref([
{ source: 0, target: 7 },
{ source: 1, target: 7 },
{ source: 1, target: 7 },
{ source: 8, target: 7 },
{ source: 8, target: 7 },
{ source: 2, target: 7 },
{ source: 2, target: 7 },
{ source: 3, target: 7 },
{ source: 3, target: 7 },
{ source: 3, target: 7 },
{ source: 4, target: 7 },
{ source: 4, target: 7 },
{ source: 5, target: 7 },
{ source: 6, target: 7 },
{ source: 9, target: 7 },
{ source: 10, target: 7 },
{ source: 11, target: 7 },
{ source: 12, target: 7 },
{ source: 13, target: 7 },
{ source: 14, target: 7 },
{ source: 15, target: 7 }
// { source: 0, target: 7 },
// { source: 1, target: 7 },
// { source: 1, target: 7 },
// { source: 8, target: 7 },
// { source: 8, target: 7 },
// { source: 2, target: 7 },
// { source: 2, target: 7 },
// { source: 3, target: 7 },
// { source: 3, target: 7 },
// { source: 3, target: 7 },
// { source: 4, target: 7 },
// { source: 4, target: 7 },
// { source: 5, target: 7 },
// { source: 6, target: 7 },
// { source: 9, target: 7 },
// { source: 10, target: 7 },
// { source: 11, target: 7 },
// { source: 12, target: 7 },
// { source: 13, target: 7 },
// { source: 14, target: 7 },
// { source: 15, target: 7 }
// { source: 0, target: 1, value: 1 },
// { source: 1, target: 8, value: 2 },
// { source: 1, target: 2, value: 1 },
......@@ -558,138 +727,7 @@ const links = ref([
// { source: 12, target: 14, value: 1 },
]);
const treeData = ref([
{
id: 7,
name: "大而美法案",
// category: 4,
symbolSize: 50,
value: 5,
symbol: `image://${CompanyImg}`,
children: [
{
id: 0,
name: "泰丰先行",
// category: 0,
symbolSize: 30,
value: 8,
symbol: `image://${CompanyImg}`
},
{
id: 1,
name: "国轩高科",
// category: 0,
symbolSize: 30,
value: 9,
symbol: `image://${CompanyImg}`
},
{
id: 2,
name: "智方纳米",
// category: 2,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
},
{
id: 3,
name: "香百科技",
// category: 1,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 4,
name: "格林滨",
// category: 2,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 5,
name: "江西紫宸",
// category: 2,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
},
{
id: 6,
name: "紫江企业",
// category: 4,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 8,
name: "比亚迪",
// category: 0,
symbolSize: 30,
value: 10,
symbol: `image://${CompanyImg}`
},
{
id: 9,
name: "铜陵有色",
// category: 3,
symbolSize: 30,
value: 8,
symbol: `image://${CompanyImg}`
},
{
id: 10,
name: "长盛精密",
// category: 1,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
},
{
id: 11,
name: "天合光能",
// category: 0,
symbolSize: 30,
value: 8,
symbol: `image://${CompanyImg}`
},
{
id: 12,
name: "昆仑化学",
// category: 2,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 13,
name: "嘉源科技",
// category: 1,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 14,
name: "华阳集团",
// category: 4,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
},
{
id: 15,
name: "海辰智能",
// category: 1,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
}
]
}
]);
const treeData = ref([]);
const handleChangeChart = index => {
if (index === 0) {
......@@ -707,8 +745,9 @@ onMounted(async () => {
await handleGetHylyList();
handleGetCompanyListById();
await handleGetIndustryHyly();
let chart1 = getBarChart(chart1Data.value.name, chart1Data.value.value);
setChart(chart1, "chart1");
// let chart1 = getBarChart(chart1Data.value.name, chart1Data.value.value);
// setChart(chart1, "chart1");
});
</script>
......@@ -745,6 +784,12 @@ onMounted(async () => {
display: flex;
justify-content: flex-end;
gap: 4px;
.more-btn {
font-size: 14px;
color: #1677ff;
cursor: pointer;
line-height: 28px;
}
.icon {
width: 28px;
height: 28px;
......@@ -776,6 +821,7 @@ onMounted(async () => {
margin-left: 17px;
overflow-x: hidden;
width: 445px;
overflow-x: auto;
.left-center-btn-box {
width: 1000px;
margin-top: 10px;
......@@ -785,7 +831,7 @@ onMounted(async () => {
.left-center-btn {
margin-right: 4px;
height: 28px;
width: 70px;
// width: 70px;
text-align: center;
padding: 0 5px;
box-sizing: border-box;
......@@ -798,7 +844,7 @@ onMounted(async () => {
font-weight: 400;
line-height: 28px;
cursor: pointer;
overflow: hidden;
// overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
......
......@@ -3,24 +3,65 @@ import * as echarts from "echarts";
const getBarChart = (nameList, valueList) => {
const colorList = ['#b37feb', '#ffc53e', '#36cfc9', '#5c80f7', '#ff7d7a', '#4a9cff']
const option = {
tooltip: {},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
top: '3%',
right: '7%',
bottom: '1%',
left: '1%',
top: '5%',
right: '15%',
bottom: '5%',
left: '3%',
containLabel: true
},
dataZoom: [
{
type: 'slider',
show: valueList.length > 5,
yAxisIndex: 0,
width: 8,
right: 10,
top: 20,
bottom: 20,
startValue: 0,
endValue: 4, // Show 5 items (0-4)
fillerColor: 'rgba(167,183,204,0.4)',
borderColor: 'transparent',
handleSize: 0,
showDetail: false,
brushSelect: false
},
{
type: 'inside',
yAxisIndex: 0,
startValue: 0,
endValue: 4,
zoomOnMouseWheel: false,
moveOnMouseWheel: true,
moveOnTouch: true
}
],
xAxis: {
type: 'value',
splitLine: {
show: false
},
show: false
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
}
},
yAxis: {
type: 'category',
data: nameList,
inverse: true, // Display from top to bottom
splitLine: {
show: false
},
......@@ -31,60 +72,43 @@ const getBarChart = (nameList, valueList) => {
show: false
},
axisLabel: {
show: true
show: true,
color: '#333',
fontSize: 14,
width: 100, // Limit width to handle long names
overflow: 'truncate',
ellipsis: '...'
}
},
series: [{
type: 'bar',
data: valueList.map((item,index) => {
data: valueList.map((item, index) => {
// Cycle through colors if more data than colors
const colorIndex = index % colorList.length;
const color = colorList[colorIndex];
return {
value: item,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: 'rgba(255,255,255,0)' }, // Transparent start
{ offset: 1, color: color } // Solid end
]),
borderRadius: [0, 10, 10, 0]
},
label: {
textStyle: {
color: colorList[index]
}
show: true,
position: 'right',
color: color,
fontSize: 16,
offset: [5, 0] // Add some space between bar and label
}
};
}
),
barWidth: 8,
label: {
show: true,
position: [365, 0],
formatter: function(params) {
return params.value
}
},
itemStyle: {
color: function (params) {
var colorList = [
['#fff', '#b37feb'],
['#fff', '#ffc53e'],
['#fff', '#36cfc9'],
['#fff', '#5c80f7'],
['#fff', '#ff7d7a'],
['#fff', '#4a9cff'],
];
var index = params.dataIndex;
if (params.dataIndex >= colorList.length) {
index = params.dataIndex - colorList.length;
}
return new echarts.graphic.LinearGradient(0, 0, 1, 0,
[{
offset: 0,
color: colorList[index][0]
},
{
offset: 1,
color: colorList[index][1]
}
]);
},
barBorderRadius: 4,
}
}),
barWidth: 10,
showBackground: false
}]
}
return option
}
export default getBarChart
\ No newline at end of file
export default getBarChart
......@@ -49,7 +49,7 @@ const getBarChart1 = (nameList, valueList) => {
offset: 1,
color: 'rgba(22,119,255,0)' // 结束颜色:浅色且透明度降低
}]),
barBorderRadius: 4,
borderRadius: 4,
}
}]
}
......
......@@ -41,7 +41,7 @@ const getGraphChart = (nodes, links) => {
itemStyle: {
color: '#73C0DE'
},
layout: 'force',
layout: 'none',
data: nodes,
links: links,
// categories: categories,
......
......@@ -319,7 +319,7 @@
新闻动态
</div>
<div class="btn" :class="{ btnActive: dialogBoxBtnActive === 1 }" @click="handleClcikDialogBoxBtn(1)">
任务履历
人物履历
</div>
</div>
<div class="inner-right-main">
......@@ -1411,6 +1411,11 @@ onMounted(() => {
font-size: 14px;
font-weight: 400;
line-height: 22px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
text-overflow: ellipsis;
}
.timeline-content1 {
color: rgba(132, 136, 142, 1);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论