提交 62a01ebb authored 作者: 张烨's avatar 张烨

Merge branch 'pre' into zy-dev

流水线 #297 已通过 于阶段
in 1 分 39 秒
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
"pdfjs-dist": "^5.5.207", "pdfjs-dist": "^5.5.207",
"pinia": "^3.0.4", "pinia": "^3.0.4",
"relation-graph-vue3": "^2.2.11",
"vue": "^3.4.0", "vue": "^3.4.0",
"vue-router": "^4.2.5" "vue-router": "^4.2.5"
}, },
...@@ -1208,9 +1209,6 @@ ...@@ -1208,9 +1209,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"libc": [
"glibc"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
...@@ -1231,9 +1229,6 @@ ...@@ -1231,9 +1229,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"libc": [
"musl"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
...@@ -1254,9 +1249,6 @@ ...@@ -1254,9 +1249,6 @@
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
"libc": [
"glibc"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
...@@ -1277,9 +1269,6 @@ ...@@ -1277,9 +1269,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"libc": [
"glibc"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
...@@ -1300,9 +1289,6 @@ ...@@ -1300,9 +1289,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"libc": [
"musl"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
...@@ -2764,6 +2750,15 @@ ...@@ -2764,6 +2750,15 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/base64-arraybuffer": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
"license": "MIT",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/baseline-browser-mapping": { "node_modules/baseline-browser-mapping": {
"version": "2.10.0", "version": "2.10.0",
"resolved": "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", "resolved": "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz",
...@@ -3161,6 +3156,15 @@ ...@@ -3161,6 +3156,15 @@
"layout-base": "^1.0.0" "layout-base": "^1.0.0"
} }
}, },
"node_modules/css-line-break": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz",
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
"license": "MIT",
"dependencies": {
"utrie": "^1.0.2"
}
},
"node_modules/cssesc": { "node_modules/cssesc": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
...@@ -4865,6 +4869,19 @@ ...@@ -4865,6 +4869,19 @@
"integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/html2canvas": {
"version": "1.4.1",
"resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz",
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
"license": "MIT",
"dependencies": {
"css-line-break": "^2.1.0",
"text-segmentation": "^1.0.3"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/iconv-lite": { "node_modules/iconv-lite": {
"version": "0.6.3", "version": "0.6.3",
"resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz", "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
...@@ -6788,6 +6805,16 @@ ...@@ -6788,6 +6805,16 @@
"resolved": "https://registry.npmmirror.com/regl/-/regl-1.7.0.tgz", "resolved": "https://registry.npmmirror.com/regl/-/regl-1.7.0.tgz",
"integrity": "sha512-bEAtp/qrtKucxXSJkD4ebopFZYP0q1+3Vb2WECWv/T8yQEgKxDxJ7ztO285tAMaYZVR6mM1GgI6CCn8FROtL1w==" "integrity": "sha512-bEAtp/qrtKucxXSJkD4ebopFZYP0q1+3Vb2WECWv/T8yQEgKxDxJ7ztO285tAMaYZVR6mM1GgI6CCn8FROtL1w=="
}, },
"node_modules/relation-graph-vue3": {
"version": "2.2.11",
"resolved": "https://registry.npmmirror.com/relation-graph-vue3/-/relation-graph-vue3-2.2.11.tgz",
"integrity": "sha512-2WyomsAwbIMuYNrfZhzGV63OXDNea24pRX6zwW91a9qmoDyVWOBoWWE4lOK6DYMW6soz4pFgET+G6j9qQ4S/SA==",
"license": "MIT",
"dependencies": {
"html2canvas": "^1.4.1",
"screenfull": "^5.1.0"
}
},
"node_modules/repeat-element": { "node_modules/repeat-element": {
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmmirror.com/repeat-element/-/repeat-element-1.1.4.tgz", "resolved": "https://registry.npmmirror.com/repeat-element/-/repeat-element-1.1.4.tgz",
...@@ -7021,6 +7048,18 @@ ...@@ -7021,6 +7048,18 @@
"url": "https://paulmillr.com/funding/" "url": "https://paulmillr.com/funding/"
} }
}, },
"node_modules/screenfull": {
"version": "5.2.0",
"resolved": "https://registry.npmmirror.com/screenfull/-/screenfull-5.2.0.tgz",
"integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/scule": { "node_modules/scule": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz", "resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz",
...@@ -7469,6 +7508,15 @@ ...@@ -7469,6 +7508,15 @@
"node": ">=10.13.0" "node": ">=10.13.0"
} }
}, },
"node_modules/text-segmentation": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz",
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
"license": "MIT",
"dependencies": {
"utrie": "^1.0.2"
}
},
"node_modules/thenify": { "node_modules/thenify": {
"version": "3.3.1", "version": "3.3.1",
"resolved": "https://mirrors.huaweicloud.com/repository/npm/thenify/-/thenify-3.3.1.tgz", "resolved": "https://mirrors.huaweicloud.com/repository/npm/thenify/-/thenify-3.3.1.tgz",
...@@ -7963,6 +8011,15 @@ ...@@ -7963,6 +8011,15 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/utrie": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz",
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
"license": "MIT",
"dependencies": {
"base64-arraybuffer": "^1.0.2"
}
},
"node_modules/uuid": { "node_modules/uuid": {
"version": "9.0.1", "version": "9.0.1",
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-9.0.1.tgz", "resolved": "https://registry.npmmirror.com/uuid/-/uuid-9.0.1.tgz",
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
"pdfjs-dist": "^5.5.207", "pdfjs-dist": "^5.5.207",
"pinia": "^3.0.4", "pinia": "^3.0.4",
"relation-graph-vue3": "^2.2.11",
"vue": "^3.4.0", "vue": "^3.4.0",
"vue-router": "^4.2.5" "vue-router": "^4.2.5"
}, },
......
...@@ -143,6 +143,7 @@ export function getChartAnalysis(data, options = {}) { ...@@ -143,6 +143,7 @@ export function getChartAnalysis(data, options = {}) {
: typeof options?.onInterpretationDelta === "function" : typeof options?.onInterpretationDelta === "function"
? options.onInterpretationDelta ? options.onInterpretationDelta
: null; : null;
const externalSignal = options?.signal;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let buffer = ""; let buffer = "";
let latestInterpretation = ""; let latestInterpretation = "";
...@@ -150,16 +151,32 @@ export function getChartAnalysis(data, options = {}) { ...@@ -150,16 +151,32 @@ export function getChartAnalysis(data, options = {}) {
let lastStreamedInterpretationLen = 0; let lastStreamedInterpretationLen = 0;
let settled = false; let settled = false;
const abortController = new AbortController(); const abortController = new AbortController();
const externalAbortHandler = () => {
abortController.abort();
};
if (externalSignal) {
if (externalSignal.aborted) {
abortController.abort();
} else {
externalSignal.addEventListener("abort", externalAbortHandler, { once: true });
}
}
const safeResolve = value => { const safeResolve = value => {
if (settled) return; if (settled) return;
settled = true; settled = true;
if (externalSignal) {
externalSignal.removeEventListener("abort", externalAbortHandler);
}
resolve(value); resolve(value);
}; };
const safeReject = err => { const safeReject = err => {
if (settled) return; if (settled) return;
settled = true; settled = true;
if (externalSignal) {
externalSignal.removeEventListener("abort", externalAbortHandler);
}
reject(err); reject(err);
}; };
...@@ -179,7 +196,8 @@ export function getChartAnalysis(data, options = {}) { ...@@ -179,7 +196,8 @@ export function getChartAnalysis(data, options = {}) {
}, },
body: JSON.stringify(data), body: JSON.stringify(data),
signal: abortController.signal, signal: abortController.signal,
openWhenHidden: true,
openWhenHidden: false,
retryDelay: 1000, retryDelay: 1000,
maxRetries: 2, maxRetries: 2,
onopen: response => { onopen: response => {
......
...@@ -56,11 +56,12 @@ export function getBillDyqk(params) { ...@@ -56,11 +56,12 @@ export function getBillDyqk(params) {
* @param {id,cRelated,currentPage,pageSize} * @param {id,cRelated,currentPage,pageSize}
* @header token * @header token
*/ */
export function getBillBackground(params) { export function getBillBackground(params, config = {}) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/api/billInfoBean/background/${params.id}`, url: `/api/billInfoBean/background/${params.id}`,
params, params,
signal: config.signal
}) })
} }
// 相关事件-根据法案ID获取相关事件信息 // 相关事件-根据法案ID获取相关事件信息
...@@ -107,11 +108,12 @@ export function getBillPersonAnalyzeDy(params) { ...@@ -107,11 +108,12 @@ export function getBillPersonAnalyzeDy(params) {
* @param {id} * @param {id}
* @header token * @header token
*/ */
export function getBillContentId(params) { export function getBillContentId(params, config = {}) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/api/billInfoBean/contentId/${params.id}`, url: `/api/billInfoBean/contentId/${params.id}`,
params, params,
signal: config.signal
}) })
} }
...@@ -120,11 +122,12 @@ export function getBillContentId(params) { ...@@ -120,11 +122,12 @@ export function getBillContentId(params) {
* @param {billId,id,cRelated,currentPage,pageSize,domainNameList,measuresNameList,content} * @param {billId,id,cRelated,currentPage,pageSize,domainNameList,measuresNameList,content}
* @header token * @header token
*/ */
export function getBillContentTk(params) { export function getBillContentTk(params, config = {}) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/api/billInfoBean/content/tk/${params.billId}/${params.id}`, url: `/api/billInfoBean/content/tk/${params.billId}/${params.id}`,
params, params,
signal: config.signal
}) })
} }
...@@ -133,11 +136,12 @@ export function getBillContentTk(params) { ...@@ -133,11 +136,12 @@ export function getBillContentTk(params) {
* @param {billId,versionId,cRelated} * @param {billId,versionId,cRelated}
* @header token * @header token
*/ */
export function getBillContentXzfs(params) { export function getBillContentXzfs(params, config = {}) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/api/billInfoBean/content/xzfs/${params.billId}/${params.versionId}`, url: `/api/billInfoBean/content/xzfs/${params.billId}/${params.versionId}`,
params, params,
signal: config.signal
}) })
} }
...@@ -146,11 +150,12 @@ export function getBillContentXzfs(params) { ...@@ -146,11 +150,12 @@ export function getBillContentXzfs(params) {
* @param {billId,versionId,cRelated} * @param {billId,versionId,cRelated}
* @header token * @header token
*/ */
export function getBillHyly(params) { export function getBillHyly(params, config = {}) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/api/billInfoBean/content/hyly/${params.billId}/${params.versionId}`, url: `/api/billInfoBean/content/hyly/${params.billId}/${params.versionId}`,
params, params,
signal: config.signal
}) })
} }
......
...@@ -3,8 +3,14 @@ import request from "@/api/request.js"; ...@@ -3,8 +3,14 @@ import request from "@/api/request.js";
// 涉华法案领域分布 // 涉华法案领域分布
/** /**
* @param {Object} params * @param {Object} params
* @param {string} params.year - 年份 * @param {string} params.year - 年份(2022-2026)
* @param {string} [params.status] - 状态:提出法案/通过法案 * @param {string} [params.status] - 法案状态:
* - 提案
* - 众议院通过
* - 参议院通过
* - 分歧已解决
* - 呈交总统
* - 完成立法
*/ */
export function getBillIndustry(params) { export function getBillIndustry(params) {
return request({ return request({
......
...@@ -10,4 +10,11 @@ export function search(data) { ...@@ -10,4 +10,11 @@ export function search(data) {
url: `/temporarySearch/search-info/es/page`, url: `/temporarySearch/search-info/es/page`,
data:data data:data
}) })
}
export function getThinkTankList() {
return request({
method: 'GET',
url: `/temporarySearch/search-info/all-organization-names`,
})
} }
\ No newline at end of file
...@@ -292,10 +292,10 @@ export function getSingleSanctionOverviewList(data) { ...@@ -292,10 +292,10 @@ export function getSingleSanctionOverviewList(data) {
* @param {string} params.sanRecordId - 制裁记录ID * @param {string} params.sanRecordId - 制裁记录ID
* @header token * @header token
*/ */
export function getSingleSanctionTotalCount(id) { export function getSingleSanctionTotalCount(sanTypeId, recordId) {
return request({ return request({
method: "GET", method: "GET",
url: `/api/sanctionList/statistics/total?sanTypeId=${id}`, url: `/api/sanctionList/statistics/total?sanTypeId=${sanTypeId}&sanRecordId=${recordId}`,
}); });
} }
......
import request from "@/api/request.js";
\ No newline at end of file
...@@ -91,7 +91,7 @@ export function getHylyList() { ...@@ -91,7 +91,7 @@ export function getHylyList() {
/** /**
* 智库概览/智库动态-智库报告、调查项目 * 智库概览/智库动态-智库报告
* GET /api/thinkTankOverview/report * GET /api/thinkTankOverview/report
* 常用 query:pageNum, pageSize, sortFun, domainIds, startDate, endDate, category(调查项目), thinkTankId(详情页), keyword(动态搜索) * 常用 query:pageNum, pageSize, sortFun, domainIds, startDate, endDate, category(调查项目), thinkTankId(详情页), keyword(动态搜索)
*/ */
...@@ -103,6 +103,81 @@ export function getThinkTankReport(params) { ...@@ -103,6 +103,81 @@ export function getThinkTankReport(params) {
}) })
} }
//智库概览调查项目
export function getThinkTankProjects(params) {
return request({
method: 'GET',
url: `/api/think-tank/projects`,
params
})
}
//智库概览页国会听证会
export function getThinkTankTestimonies(params) {
return request({
method: 'GET',
url: `/api/think-tank/testimonies`,
params
})
}
//智库调查项目详情主页
export function getThinkTankProjectsInfo(params) {
return request({
method: 'GET',
url: `/api/think-tank/projects/${params.id}`,
})
}
//智库国会听证会详情主页
export function getThinkTankHearingInfo(params) {
return request({
method: 'GET',
url: `/api/think-tank/testimonies/${params.id}`,
})
}
// 智库详情-调查项目(按智库 id)
export function getThinkTankProjectsByThinkTankId(params) {
return request({
method: 'GET',
url: `/api/think-tank/${params.thinkTankId}/projects`,
params: {
pageNum: params.pageNum,
pageSize: params.pageSize,
sortFun: params.sortFun,
sortField: params.sortField,
sortOrder: params.sortOrder,
domainIds: params.domainIds,
startDate: params.startDate,
endDate: params.endDate,
projectName: params.projectName,
}
})
}
// 智库动态-国会听证会(按智库 id)
export function getThinkTankTestimoniesByThinkTankId(params) {
return request({
method: 'GET',
url: `/api/think-tank/${params.thinkTankId}/testimonies`,
params: {
pageNum: params.pageNum,
pageSize: params.pageSize,
domainIds: params.domainIds,
startDate: params.startDate,
endDate: params.endDate,
title: params.title,
}
})
}
//智库调查项目详情作者
export function getThinkTankProjectsAuthors(params) {
return request({
method: 'GET',
url: `/api/think-tank/projects/${params.id}/team`,
})
}
// 智库概览:政策建议(资源库-政策建议) // 智库概览:政策建议(资源库-政策建议)
export function getThinkTankOverviewPolicy(params) { export function getThinkTankOverviewPolicy(params) {
return request({ return request({
...@@ -378,6 +453,15 @@ export const getThinkTankReportRelated = (params) => { ...@@ -378,6 +453,15 @@ export const getThinkTankReportRelated = (params) => {
} }
); );
} }
//调查项目:获取项目报告
export const getThinkTankProjectRelated = (params) => {
return request(
{
method: 'GET',
url: `/api/think-tank/projects/${params}/reports`,
}
);
}
//获取报告原文 //获取报告原文
export const getThinkTankReportcontentUrl = (params) => { export const getThinkTankReportcontentUrl = (params) => {
...@@ -424,7 +508,21 @@ export function getThinkTankReportViewpoint(params) { ...@@ -424,7 +508,21 @@ export function getThinkTankReportViewpoint(params) {
} }
}) })
} }
// 获取报告核心论点(支持关键字搜索)
export function getThinkTankHearingViewpoint(params) {
const { testimonyId, pageSize, keyword = '',pageNum } = params
return request({
method: 'GET',
url: `/api/think-tank/testimonies/qa`,
params: {
pageSize,
keyword,
pageNum,
testimonyId
}
})
}
//获取涉及科技领域 //获取涉及科技领域
export function getThinkTankReportIndustry(params) { export function getThinkTankReportIndustry(params) {
return request({ return request({
...@@ -440,6 +538,20 @@ export function getThinkTankReportIndustryCloud(params) { ...@@ -440,6 +538,20 @@ export function getThinkTankReportIndustryCloud(params) {
url: `/api/thinkTankReport/keyword/${params.id}`, url: `/api/thinkTankReport/keyword/${params.id}`,
}) })
} }
//获取调查项目词云
export function getThinkTankProjectCloud(params) {
return request({
method: 'GET',
url: `/api/think-tank/projects/${params.id}/word-cloud`,
})
}
//获取国会听证会词云
export function getThinkTankHearingCloud(params) {
return request({
method: 'GET',
url: `/api/think-tank/testimonies/${params.id}/wordcloud`,
})
}
//获取政策建议落实情况 //获取政策建议落实情况
export function getThinkTankReportPolicy(params) { export function getThinkTankReportPolicy(params) {
......
...@@ -33,7 +33,7 @@ const getGraphChart = (nodes, links, layoutType) => { ...@@ -33,7 +33,7 @@ const getGraphChart = (nodes, links, layoutType) => {
fontSize: 12 fontSize: 12
} }
}, },
animation: true, animation: false,
animationDuration: 1000, animationDuration: 1000,
animationEasing: 'cubicOut', animationEasing: 'cubicOut',
series: [{ series: [{
......
<template> <template>
<div class="graph-chart-wrapper" id="graph"> <div class="graph-chart-wrapper" id="graph"></div>
</div>
</template> </template>
<script setup> <script setup>
import { onMounted, onBeforeUnmount } from 'vue'; import { onMounted, onBeforeUnmount, watch } from "vue";
import setChart from '@/utils/setChart'; import setChart from "@/utils/setChart";
import getGraphChart from './graphChart'; import getGraphChart from "./graphChart";
const emits = defineEmits(["handleClickNode"]) const emits = defineEmits(["handleClickNode"]);
const props = defineProps({ const props = defineProps({
nodes: { nodes: {
type: Array, type: Array,
default: [] default: []
}, },
links: { links: {
type: Array, type: Array,
default: [] default: []
}, },
layoutType: { layoutType: {
type: String, type: String,
default: 'force' default: "force"
}, },
width: { width: {
type: String, type: String,
default: 'force' default: "force"
}, },
height: { height: {
type: String, type: String,
default: 'force' default: "force"
} }
}) });
let chart = null let chart = null;
onMounted(() => { onMounted(() => {
const graph = getGraphChart(props.nodes, props.links, props.layoutType) const graph = getGraphChart(props.nodes, props.links, props.layoutType);
chart = setChart(graph, 'graph') chart = setChart(graph, "graph");
chart.on("click", (event) => { emits("handleClickNode", event) }) chart.on("click", event => {
}) emits("handleClickNode", event);
});
});
onBeforeUnmount(() => { onBeforeUnmount(() => {
chart.off("click") chart.off("click");
chart.dispose() chart.dispose();
}) });
watch(
() => [props.nodes, props.links],
() => {
if (chart) {
const graph = getGraphChart(props.nodes, props.links, props.layoutType);
chart.setOption(graph, true);
}
},
{ deep: true }
);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.graph-chart-wrapper { .graph-chart-wrapper {
width: 100%; width: 100%;
height: 100%; height: 100%;
// width: 800px; // width: 800px;
// height: 500px; // height: 500px;
} }
</style> </style>
\ No newline at end of file
<template>
<RelationGraph style="width: 100%; height: 100%;" ref="graphRef" :options="graphOptions" @node-click="onNodeClick"
@line-click="onLineClick" />
</template>
<script setup>
import { defineComponent, ref, onMounted } from 'vue';
import RelationGraph from 'relation-graph-vue3';
// import type { RGJsonData, RGNode, RGLine, RGLink, RGUserEvent, RGOptions, RelationGraphComponent } from 'relation-graph-vue3';
const graphRef = ref(null);
const graphOptions = {
debug: true,
defaultNodeBorderWidth: 0,
defaultNodeColor: 'var(--color-primary-50)',
defaultNodeFontColor: 'var(--text-primary-80-color)',
allowSwitchLineShape: true,
allowSwitchJunctionPoint: true,
defaultLineShape: 1,
distance_coefficient: 1,
layouts: [
{
layoutName: 'center',
// 👇 关键参数:控制各层级之间的距离(值越大,连线越长,节点间距越大)
distance_coefficient: 1.8, // 默认值通常是 1.0,可以调到 1.5-3.0
// 👇 层级间的垂直间距
levelDistance: 80, // 单位:像素,默认约 80-100
// 👇 同一层级内节点之间的水平间距
nodeDistance: 100 // 单位:像素,默认约 100
}
],
defaultJunctionPoint: 'border',
// defaultNodeWidth: 120, // 全局默认节点宽度
// defaultNodeHeight: 120, // 全局默认节点高度
};
const showGraph = async () => {
const __graph_json_data = props.graphData;
const graphInstance = graphRef.value?.getInstance();
if (graphInstance) {
await graphInstance.setJsonData(__graph_json_data);
await graphInstance.moveToCenter();
// await graphInstance.zoomToFit();
await graphInstance.setZoom(65);
}
};
const emit = defineEmits(['nodeClick', 'lineClick'])
const onNodeClick = (nodeObject, $event) => {
console.log('onNodeClick:', nodeObject);
emit('nodeClick', nodeObject)
};
const onLineClick = (lineObject, linkObject, $event) => {
console.log('onLineClick:', lineObject);
emit('lineClick', lineObject)
};
const props = defineProps({
graphData: {
type: Object,
default: {
rootId: '2',
nodes: [
{ id: '1', text: 'Node-1' },
{ id: '2', text: 'Node-2' },
{ id: '3', text: 'Node-3' },
{ id: '4', text: 'Node-4' },
{ id: '6', text: 'Node-6' },
{ id: '7', text: 'Node-7' },
{ id: '8', text: 'Node-8' },
{ id: '9', text: 'Node-9' },
{ id: '71', text: 'Node-71' },
{ id: '72', text: 'Node-72' },
{ id: '73', text: 'Node-73' },
{ id: '81', text: 'Node-81' },
{ id: '82', text: 'Node-82' },
{ id: '83', text: 'Node-83' },
{ id: '84', text: 'Node-84' },
{ id: '85', text: 'Node-85' },
{ id: '91', text: 'Node-91' },
{ id: '92', text: 'Node-82' },
{ id: '51', text: 'Node-51' },
{ id: '52', text: 'Node-52' },
{ id: '53', text: 'Node-53' },
{ id: '54', text: 'Node-54' },
{ id: '55', text: 'Node-55' },
{ id: '5', text: 'Node-5' }
],
lines: [
{ from: '7', to: '71', text: 'Investment' },
{ from: '7', to: '72', text: 'Investment' },
{ from: '7', to: '73', text: 'Investment' },
{ from: '8', to: '81', text: 'Investment' },
{ from: '8', to: '82', text: 'Investment' },
{ from: '8', to: '83', text: 'Investment' },
{ from: '8', to: '84', text: 'Investment' },
{ from: '8', to: '85', text: 'Investment' },
{ from: '9', to: '91', text: 'Investment' },
{ from: '9', to: '92', text: 'Investment' },
{ from: '5', to: '51', text: 'Investment1' },
{ from: '5', to: '52', text: 'Investment' },
{ from: '5', to: '53', text: 'Investment3' },
{ from: '5', to: '54', text: 'Investment4' },
{ from: '5', to: '55', text: 'Investment' },
{ from: '1', to: '2', text: 'Investment' },
{ from: '3', to: '1', text: 'Executive' },
{ from: '4', to: '2', text: 'Executive' },
{ from: '6', to: '2', text: 'Executive' },
{ from: '7', to: '2', text: 'Executive' },
{ from: '8', to: '2', text: 'Executive' },
{ from: '9', to: '2', text: 'Executive' },
{ from: '1', to: '5', text: 'Investment' }
]
}
}
})
onMounted(() => {
showGraph();
});
</script>
<style scoped lang="scss"></style>
差异被折叠。
<template>
<RelationGraph
style="width: 100%; height: 100%"
ref="graphRef"
:options="graphOptions"
@node-click="onNodeClick"
@line-click="onLineClick"
>
<!-- 自定义节点插槽 - 这是官方推荐的方式 -->
<template #node="{ node }">
<div
class="custom-node"
:style="{
backgroundColor: node.color || 'var(--color-primary-50)'
}"
>
{{ console.log(node) }}
<!-- 在这里自由控制文字样式 -->
<div class="img" v-if="node.data.pic">
<img :src="node.data.pic" alt="" />
</div>
<span
class="text"
:style="{
color: node.fontColor || 'var(--text-primary-80-color)',
fontSize: node.customFontSize || '24px' // 可以从数据中读取
}"
>
{{ node.text }}
</span>
</div>
</template>
</RelationGraph>
</template>
<script setup>
import { onMounted, ref } from "vue";
import RelationGraph from "relation-graph-vue3";
const props = defineProps({
graphData: {
type: Object,
default: {}
}
});
const graphRef = ref(null);
const graphOptions = ref({
debug: false,
defaultNodeBorderWidth: 0,
allowSwitchLineShape: true,
allowSwitchJunctionPoint: true,
defaultNodeColor: "var(--color-primary-50)",
defaultNodeFontColor: "var(--text-primary-90-color)", // 默认文字颜色:深灰色
defaultLineShape: 1,
layout: {
layoutName: "force"
},
defaultJunctionPoint: "border"
// defaultNodeWidth: 150, // 全局默认节点宽度
// defaultNodeHeight: 150, // 全局默认节点高度
});
const showGraph = async () => {
const __graph_json_data = props.graphData;
const graphInstance = graphRef.value.getInstance();
if (graphInstance) {
await graphInstance.setJsonData(__graph_json_data);
await graphInstance.moveToCenter();
// await graphInstance.zoomToFit();
await graphInstance.setZoom(45);
}
};
const emit = defineEmits(["nodeClick", "lineClick"]);
const onNodeClick = (nodeObject, $event) => {
console.log("onNodeClick:", nodeObject);
emit("nodeClick", nodeObject);
};
const onLineClick = (lineObject, linkObject, $event) => {
console.log("onLineClick:", lineObject);
emit("lineClick", lineObject);
};
onMounted(() => {
showGraph();
});
</script>
<style lang="scss" scoped>
.custom-node {
width: 100%;
height: 100%;
border-radius: 50%;
padding: 10px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
.img {
position: absolute;
width: 50px;
height: 50px;
img {
width: 100%;
height: 100%;
}
}
.text {
font-weight: normal;
text-align: center;
word-break: break-word;
padding: 0 8px;
white-space: nowrap;
margin-top: 120px;
display: inline-block;
}
}
</style>
...@@ -18,13 +18,13 @@ const getWordCloudChart = data => { ...@@ -18,13 +18,13 @@ const getWordCloudChart = data => {
// 其他形状你可以使用形状路径 // 其他形状你可以使用形状路径
// shape: 'circle', // 示例 // shape: 'circle', // 示例
// 或者自定义路径 // 或者自定义路径
gridSize: 15, // 网格大小,影响词间距。 gridSize: 5, // 网格大小,影响词间距。
sizeRange: [16, 36], // 定义词云中文字大小的范围 sizeRange: [16, 36], // 定义词云中文字大小的范围
rotationRange: [0, 0], rotationRange: [0, 0],
// rotationRange: [-90, 90], // rotationRange: [-90, 90],
// rotationStep: 10, // rotationStep: 10,
drawOutOfBound: false, // 是否超出画布 drawOutOfBound: false, // 是否超出画布
shrinkToFit: true, // 是否自动缩小以适应容器 shrinkToFit: false, // 是否自动缩小以适应容器
// 字体 // 字体
textStyle: { textStyle: {
color: function (params) { color: function (params) {
......
...@@ -128,7 +128,19 @@ const homeTitleList = ref([ ...@@ -128,7 +128,19 @@ const homeTitleList = ref([
} }
]); ]);
const homeActiveTitleIndex = ref(0); const homeActiveTitleIndex = computed(() => {
let activeIndex = 1
if (route.fullPath.includes('/ZMOverView')) {
activeIndex = 0
} else if (route.fullPath.includes('/dataLibrary')) {
activeIndex = 3
} else if (route.fullPath.includes('/chat') || route.fullPath.includes('/writtingAsstaint')) {
activeIndex = 2
} else {
activeIndex = 1
}
return activeIndex
})
const isShowMenu = ref(false); const isShowMenu = ref(false);
const handleShowMenu = (index, isShow) => { const handleShowMenu = (index, isShow) => {
...@@ -148,79 +160,150 @@ const handleHoverMenu = isShow => { ...@@ -148,79 +160,150 @@ const handleHoverMenu = isShow => {
isShowMenu.value = isShow; isShowMenu.value = isShow;
}; };
const menuList = ref([ const menuList = computed(() => {
// { let menu = [
// title: "中美科技博弈概览", // {
// icon: Menu1, // title: "中美科技博弈概览",
// path: "/ZMOverView" // icon: Menu1,
// }, // path: "/ZMOverView"
{ // },
title: "科技法案", {
icon: Menu2, title: "科技法案",
path: "/billHome", icon: Menu2,
active: false path: "/billHome",
}, active: false
{ },
title: "科技政令", {
icon: Menu3, title: "科技政令",
path: "/decree", icon: Menu3,
active: false path: "/decree",
}, active: false
{ },
title: "美国科技智库", {
icon: Menu4, title: "美国科技智库",
path: "/thinkTank", icon: Menu4,
active: false path: "/thinkTank",
}, active: false
{ },
title: "出口管制", {
icon: Menu5, title: "出口管制",
path: "/exportControl", icon: Menu5,
active: false path: "/exportControl",
}, active: false
{ },
title: "科研合作限制", {
icon: Menu6, title: "科研合作限制",
path: "/cooperationRestrictions", icon: Menu6,
active: false path: "/cooperationRestrictions",
}, active: false
{ },
title: "投融资限制", {
icon: Menu7, title: "投融资限制",
path: "/finance", icon: Menu7,
active: false path: "/finance",
}, active: false
{ },
title: "市场准入限制", {
icon: Menu8, title: "市场准入限制",
path: "/marketAccessRestrictions", icon: Menu8,
active: false path: "/marketAccessRestrictions",
}, active: false
{ },
title: "规则限制", {
icon: Menu9, title: "规则限制",
path: "/ruleRestrictions", icon: Menu9,
active: false path: "/ruleRestrictions",
}, active: false
{ },
title: "美国科技人物观点", {
icon: Menu10, title: "美国科技人物观点",
path: "/technologyFigures", icon: Menu10,
active: false path: "/technologyFigures",
}, active: false
{ },
title: "美国主要创新主体动向", {
icon: Menu11, title: "美国主要创新主体动向",
path: "/innovationSubject", icon: Menu11,
active: false path: "/innovationSubject",
}, active: false
{ },
title: "美国科研资助体系", {
icon: Menu12, title: "美国科研资助体系",
path: "/scientificFunding", icon: Menu12,
active: false path: "/scientificFunding",
active: false
}
]
switch (route.fullPath) {
case '/billHome':
menu.forEach(item => {
item.active = false
})
menu[0].active = true
break
case '/decree':
menu.forEach(item => {
item.active = false
})
menu[1].active = true
break
case '/thinkTank':
menu.forEach(item => {
item.active = false
})
menu[2].active = true
break
case '/exportControl':
menu.forEach(item => {
item.active = false
})
menu[3].active = true
break
case '/cooperationRestrictions':
menu.forEach(item => {
item.active = false
})
menu[4].active = true
break
case '/finance':
menu.forEach(item => {
item.active = false
})
menu[5].active = true
break
case '/marketAccessRestrictions':
menu.forEach(item => {
item.active = false
})
menu[6].active = true
break
case '/ruleRestrictions':
menu.forEach(item => {
item.active = false
})
menu[7].active = true
break
case '/technologyFigures':
menu.forEach(item => {
item.active = false
})
menu[8].active = true
break
case '/innovationSubject':
menu.forEach(item => {
item.active = false
})
menu[9].active = true
break
case '/scientificFunding':
menu.forEach(item => {
item.active = false
})
menu[10].active = true
break
} }
]); return menu
})
const isShowTool = ref(false); const isShowTool = ref(false);
...@@ -243,10 +326,7 @@ const toolList = ref([ ...@@ -243,10 +326,7 @@ const toolList = ref([
]) ])
const handleToModule = (item, index) => { const handleToModule = (item, index) => {
window.sessionStorage.setItem('homeActiveTitleIndex', index)
if (index === 1) { if (index === 1) {
homeActiveTitleIndex.value = index
item.active = true
router.push({ router.push({
path: item.path path: item.path
}) })
...@@ -265,10 +345,7 @@ const handleToModule = (item, index) => { ...@@ -265,10 +345,7 @@ const handleToModule = (item, index) => {
}; };
const handleClickTitle = (item, index) => { const handleClickTitle = (item, index) => {
if (index === 0 || index === 3) { if (index === 0 || index === 3) {
window.sessionStorage.setItem('homeActiveTitleIndex', index)
homeActiveTitleIndex.value = index
router.push(item.path) router.push(item.path)
} }
}; };
...@@ -279,17 +356,8 @@ const handleClickToolBox = () => { ...@@ -279,17 +356,8 @@ const handleClickToolBox = () => {
onMounted(() => { onMounted(() => {
handleGetPersonType(); handleGetPersonType();
if (route.query.titleIndex) {
homeActiveTitleIndex.value = Number(route.query.titleIndex)
} else {
homeActiveTitleIndex.value = Number(window.sessionStorage.getItem('homeActiveTitleIndex'))
}
}); });
onUnmounted(() => {
window.sessionStorage.removeItem('homeActiveTitleIndex')
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
......
...@@ -69,7 +69,8 @@ router.beforeEach((to, from, next) => { ...@@ -69,7 +69,8 @@ router.beforeEach((to, from, next) => {
if (to.meta.title) { if (to.meta.title) {
if (to.meta.dynamicTitle) { if (to.meta.dynamicTitle) {
console.log('to', to); console.log('to', to);
document.title = window.sessionStorage.getItem("curTabName") || to.meta.title; const storageKey = to.meta.titleStorageKey || "curTabName";
document.title = window.sessionStorage.getItem(storageKey) || to.meta.title;
} else { } else {
document.title = to.meta.title document.title = to.meta.title
......
...@@ -20,7 +20,8 @@ const cooperationRestrictionsRoutes = [ ...@@ -20,7 +20,8 @@ const cooperationRestrictionsRoutes = [
component: CooperationRestrictionsDetail, component: CooperationRestrictionsDetail,
meta: { meta: {
title: "合作限制详情", title: "合作限制详情",
dynamicTitle: true dynamicTitle: true,
titleStorageKey: "cooperationRestrictionsTabName"
} }
}, },
......
...@@ -121,7 +121,7 @@ const exportControlRoutes = [ ...@@ -121,7 +121,7 @@ const exportControlRoutes = [
name: "commercialControlList", name: "commercialControlList",
component: () => import("@/views/exportControl/v2.0CommercialControlList/index.vue"), component: () => import("@/views/exportControl/v2.0CommercialControlList/index.vue"),
meta: { meta: {
title: "商业管制清单" title: "商业管制清单概览"
} }
} }
] ]
......
...@@ -41,17 +41,31 @@ const thinktankRoutes = [ ...@@ -41,17 +41,31 @@ const thinktankRoutes = [
path: "/thinkTank/reportOriginal/:id", path: "/thinkTank/reportOriginal/:id",
name: "ReportOriginal", name: "ReportOriginal",
component: ReportOriginal, component: ReportOriginal,
meta: {
title: "报告原文",
dynamicTitle: true,
titleStorageKey: "reportOriginalTabName"
}
}, },
{ {
path: "/thinkTank/SurveyProjectView/:id", path: "/thinkTank/SurveyProjectView/:id",
name: "SurveyProjectView", name: "SurveyProjectView",
component: SurveyProjectView, component: SurveyProjectView,
meta: {
title: "调查项目",
dynamicTitle: true,
titleStorageKey: "surveyProjectTabName"
}
}, },
{ {
path: "/thinkTank/CongressHearingView/:id", path: "/thinkTank/CongressHearingView/:id",
name: "CongressHearingView", name: "CongressHearingView",
component: CongressHearingView, component: CongressHearingView,
meta: {
title: "国会听证会",
dynamicTitle: true,
titleStorageKey: "congressHearingTabName"
}
}, },
{ {
path: "/thinkTank/allThinkTank", path: "/thinkTank/allThinkTank",
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
`}} `}}
</pre> </pre>
<div class="chart-box"> <div class="chart-box">
<GraphChart :nodes="nodes" :links="links" layoutType="force"> <GraphChart :nodes="nodes" :links="links" layoutType="none">
</GraphChart> </GraphChart>
</div> </div>
</el-col> </el-col>
......
<template>
<el-row class="wrapper layout-grid-line">
<el-col :span="span">
<pre>
{{
`
import RelationCenterChart from '@/components/base/RelationCenterChart/index.vue'
<RelationCenterChart :graph-data="graphData" />
`
}}
</pre>
<div class="chart-box">
<RelationCenterChart @line-click="handleClickLine" @node-click="handleClickNode" :graph-data="graphData" />
</div>
</el-col>
</el-row>
</template>
<script setup>
import { ref } from 'vue'
import '@/styles/common.scss'
import RelationCenterChart from '@/components/base/RelationCenterChart/index.vue'
const span = 24
import Img from '@/assets/icons/symbol.png'
const graphData = ref({
rootId: 'a',
nodes: [
{ id: 'a', text: '上海复龙鸿芯微系统技术有限公司', data: {
pic: Img,
name: "xxx图片"
} },
{ id: 'b', text: 'b' },
{ id: 'b1', text: 'b1' },
{ id: 'b1-1', text: 'b1-1' },
{ id: 'b1-2', text: 'b1-2' },
{ id: 'b1-3', text: 'b1-3' },
{ id: 'b1-4', text: 'b1-4' },
{ id: 'b2', text: 'b2' },
{ id: 'b2-1', text: 'b2-1' },
{ id: 'b2-2', text: 'b2-2' },
{ id: 'b2-3', text: 'b2-3' },
{ id: 'b2-4', text: 'b2-4' },
{ id: 'b3', text: 'b3' },
{ id: 'b3-1', text: 'b3-1' },
{ id: 'b3-2', text: 'b3-2' },
{ id: 'b3-3', text: 'b3-3' },
{ id: 'b3-4', text: 'b3-4' },
{ id: 'b3-5', text: 'b3-5' },
{ id: 'b4', text: 'b4' },
{ id: 'b4-1', text: 'b4-1' },
{ id: 'b4-2', text: 'b4-2' },
{ id: 'b4-3', text: 'b4-3' },
{ id: 'b4-4', text: 'b4-4' },
{ id: 'b4-5', text: 'b4-5' },
{ id: 'b4-6', text: 'b4-6' },
{ id: 'b4-7', text: 'b4-7' },
{ id: 'b4-8', text: 'b4-8' },
{ id: 'b4-9', text: 'b4-9' },
{ id: 'b5', text: 'b5' },
{ id: 'b5-1', text: 'b5-1' },
{ id: 'b5-2', text: 'b5-2' },
{ id: 'b5-3', text: 'b5-3' },
{ id: 'b5-4', text: 'b5-4' },
{ id: 'b6', text: 'b6' },
{ id: 'b6-1', text: 'b6-1' },
{ id: 'b6-2', text: 'b6-2' },
{ id: 'b6-3', text: 'b6-3' },
{ id: 'b6-4', text: 'b6-4' },
{ id: 'b6-5', text: 'b6-5' },
{ id: 'c', text: 'c' },
{ id: 'c1', text: 'c1' },
{ id: 'c1-1', text: 'c1-1' },
{ id: 'c1-2', text: 'c1-2' },
{ id: 'c1-3', text: 'c1-3' },
{ id: 'c1-4', text: 'c1-4' },
{ id: 'c1-5', text: 'c1-5' },
{ id: 'c1-6', text: 'c1-6' },
{ id: 'c1-7', text: 'c1-7' },
{ id: 'c2', text: 'c2' },
{ id: 'c2-1', text: 'c2-1' },
{ id: 'c2-2', text: 'c2-2' },
{ id: 'c3', text: 'c3' },
{ id: 'c3-1', text: 'c3-1' },
{ id: 'c3-2', text: 'c3-2' },
{ id: 'c3-3', text: 'c3-3' },
{ id: 'd', text: 'd' },
{ id: 'd1', text: 'd1' },
{ id: 'd1-1', text: 'd1-1' },
{ id: 'd1-2', text: 'd1-2' },
{ id: 'd1-3', text: 'd1-3' },
{ id: 'd1-4', text: 'd1-4' },
{ id: 'd1-5', text: 'd1-5' },
{ id: 'd1-6', text: 'd1-6' },
{ id: 'd1-7', text: 'd1-7' },
{ id: 'd1-8', text: 'd1-8' },
{ id: 'd2', text: 'd2' },
{ id: 'd2-1', text: 'd2-1' },
{ id: 'd2-2', text: 'd2-2' },
{ id: 'd3', text: 'd3' },
{ id: 'd3-1', text: 'd3-1' },
{ id: 'd3-2', text: 'd3-2' },
{ id: 'd3-3', text: 'd3-3' },
{ id: 'd3-4', text: 'd3-4' },
{ id: 'd3-5', text: 'd3-5' },
{ id: 'd4', text: 'd4' },
{ id: 'd4-1', text: 'd4-1' },
{ id: 'd4-2', text: 'd4-2' },
{ id: 'd4-3', text: 'd4-3' },
{ id: 'd4-4', text: 'd4-4' },
{ id: 'e', text: 'e' },
{ id: 'e1', text: 'e1' },
{ id: 'e1-1', text: 'e1-1' },
{ id: 'e1-2', text: 'e1-2' },
{ id: 'e1-3', text: 'e1-3' },
{ id: 'e1-4', text: 'e1-4' },
{ id: 'e2', text: 'e2' },
{ id: 'e2-1', text: 'e2-1' },
{ id: 'e2-2', text: 'e2-2' },
{ id: 'e2-3', text: 'e2-3' },
{ id: 'e2-4', text: 'e2-4' },
{ id: 'e2-5', text: 'e2-5' },
{ id: 'e2-6', text: 'e2-6' },
],
lines: [
{ from: 'a', to: 'b', text: '控股', fontColor:'red', textOffset_y: -8, color: 'orange', lineWidth: 5 },
{ from: 'b', to: 'b1' },
{ from: 'b1', to: 'b1-1' },
{ from: 'b1', to: 'b1-2' },
{ from: 'b1', to: 'b1-3' },
{ from: 'b1', to: 'b1-4' },
{ from: 'b1', to: 'b1-5' },
{ from: 'b1', to: 'b1-6' },
{ from: 'b', to: 'b2' },
{ from: 'b2', to: 'b2-1' },
{ from: 'b2', to: 'b2-2' },
{ from: 'b2', to: 'b2-3' },
{ from: 'b2', to: 'b2-4' },
{ from: 'b', to: 'b3' },
{ from: 'b3', to: 'b3-1' },
{ from: 'b3', to: 'b3-2' },
{ from: 'b3', to: 'b3-3' },
{ from: 'b3', to: 'b3-4' },
{ from: 'b3', to: 'b3-5' },
{ from: 'b', to: 'b4' },
{ from: 'b4', to: 'b4-1' },
{ from: 'b4', to: 'b4-2' },
{ from: 'b4', to: 'b4-3' },
{ from: 'b4', to: 'b4-4' },
{ from: 'b4', to: 'b4-5' },
{ from: 'b4', to: 'b4-6' },
{ from: 'b4', to: 'b4-7' },
{ from: 'b4', to: 'b4-8' },
{ from: 'b4', to: 'b4-9' },
{ from: 'b', to: 'b5' },
{ from: 'b5', to: 'b5-1' },
{ from: 'b5', to: 'b5-2' },
{ from: 'b5', to: 'b5-3' },
{ from: 'b5', to: 'b5-4' },
{ from: 'b', to: 'b6' },
{ from: 'b6', to: 'b6-1' },
{ from: 'b6', to: 'b6-2' },
{ from: 'b6', to: 'b6-3' },
{ from: 'b6', to: 'b6-4' },
{ from: 'b6', to: 'b6-5' },
{ from: 'a', to: 'c' },
{ from: 'c', to: 'c1' },
{ from: 'c1', to: 'c1-1' },
{ from: 'c1', to: 'c1-2' },
{ from: 'c1', to: 'c1-3' },
{ from: 'c1', to: 'c1-4' },
{ from: 'c1', to: 'c1-5' },
{ from: 'c1', to: 'c1-6' },
{ from: 'c1', to: 'c1-7' },
{ from: 'c', to: 'c2' },
{ from: 'c2', to: 'c2-1' },
{ from: 'c2', to: 'c2-2' },
{ from: 'c', to: 'c3' },
{ from: 'c3', to: 'c3-1' },
{ from: 'c3', to: 'c3-2' },
{ from: 'c3', to: 'c3-3' },
{ from: 'a', to: 'd' },
{ from: 'd', to: 'd1' },
{ from: 'd1', to: 'd1-1' },
{ from: 'd1', to: 'd1-2' },
{ from: 'd1', to: 'd1-3' },
{ from: 'd1', to: 'd1-4' },
{ from: 'd1', to: 'd1-5' },
{ from: 'd1', to: 'd1-6' },
{ from: 'd1', to: 'd1-7' },
{ from: 'd1', to: 'd1-8' },
{ from: 'd', to: 'd2' },
{ from: 'd2', to: 'd2-1' },
{ from: 'd2', to: 'd2-2' },
{ from: 'd', to: 'd3' },
{ from: 'd3', to: 'd3-1' },
{ from: 'd3', to: 'd3-2' },
{ from: 'd3', to: 'd3-3' },
{ from: 'd3', to: 'd3-4' },
{ from: 'd3', to: 'd3-5' },
{ from: 'd', to: 'd4' },
{ from: 'd4', to: 'd4-1' },
{ from: 'd4', to: 'd4-2' },
{ from: 'd4', to: 'd4-3' },
{ from: 'd4', to: 'd4-4' },
{ from: 'a', to: 'e' },
{ from: 'e', to: 'e1' },
{ from: 'e1', to: 'e1-1' },
{ from: 'e1', to: 'e1-2' },
{ from: 'e1', to: 'e1-3' },
{ from: 'e1', to: 'e1-4' },
{ from: 'e', to: 'e2' },
{ from: 'e2', to: 'e2-1' },
{ from: 'e2', to: 'e2-2' },
{ from: 'e2', to: 'e2-3' },
{ from: 'e2', to: 'e2-4' },
{ from: 'e2', to: 'e2-5' },
{ from: 'e2', to: 'e2-6' },
]
})
const handleClickNode = (value) => {
console.log('value', value);
alert('我点击了node-'+ value.text)
}
const handleClickLine = (value) => {
console.log('value', value);
alert('我点击了line-'+ value.text)
}
</script>
<style lang="scss" scoped>
.chart-box {
width: 1600px;
height: 600px;
}
</style>
\ No newline at end of file
<template>
<el-row class="wrapper layout-grid-line">
<el-col :span="span">
<pre>
{{
`
import RelationChart from '@/components/base/RelationChart/index.vue'
<div class="chart-box">
<RelationChart :is-vertical-chart="isVerticalChart" :graph-data="graphData" />
</div>
`
}}
</pre>
<div class="tab-box">
<el-radio-group v-model="currentCase" size="large" @change="tabChange">
<el-radio-button label="水平关系图" />
<el-radio-button label="竖直关系图" />
</el-radio-group>
</div>
<div class="chart-box">
<RelationChart @line-click="handleClickLine" @node-click="handleClickNode" :is-vertical-chart="isVerticalChart" :graph-data="graphData" />
</div>
</el-col>
</el-row>
</template>
<script setup>
import { ref } from "vue";
import "@/styles/common.scss";
import RelationChart from "@/components/base/RelationChart/index.vue";
const span = 24;
const currentCase = ref("水平关系图");
const isVerticalChart = ref(false);
const tabChange = () => {
if (currentCase.value === "水平关系图") {
isVerticalChart.value = false;
} else {
isVerticalChart.value = true;
}
};
const graphData = ref({
rootId: "a",
nodes: [
{ id: "a", text: "a" },
{ id: "b", text: "b" },
{ id: "b1", text: "b1" },
{ id: "b1-1", text: "b1-1" },
{ id: "b1-2", text: "b1-2" },
{ id: "b1-3", text: "b1-3" },
{ id: "b1-4", text: "b1-4" },
{ id: "b1-5", text: "b1-5" },
{ id: "b1-6", text: "b1-6" },
{ id: "b2", text: "b2" },
{ id: "b2-1", text: "b2-1" },
{ id: "b2-2", text: "b2-2" },
{ id: "b2-3", text: "b2-3" },
{ id: "b2-4", text: "b2-4" },
{ id: "b3", text: "b3" },
{ id: "b3-1", text: "b3-1" },
{ id: "b3-2", text: "b3-2" },
{ id: "b3-3", text: "b3-3" },
{ id: "b3-4", text: "b3-4" },
{ id: "b3-5", text: "b3-5" },
{ id: "b3-6", text: "b3-6" },
{ id: "b3-7", text: "b3-7" },
{ id: "b4", text: "b4" },
{ id: "b4-1", text: "上海复龙鸿芯微系统技术有限公司" },
{ id: "b4-2", text: "b4-2" },
{ id: "b4-3", text: "b4-3" },
{ id: "b4-4", text: "b4-4" },
{ id: "b4-5", text: "b4-5" },
{ id: "b4-6", text: "b4-6" },
{ id: "b4-7", text: "b4-7" },
{ id: "b4-8", text: "b4-8" },
{ id: "b4-9", text: "b4-9" },
{ id: "b5", text: "b5" },
{ id: "b5-1", text: "b5-1" },
{ id: "b5-2", text: "b5-2" },
{ id: "b5-3", text: "b5-3" },
{ id: "b5-4", text: "b5-4" },
{ id: "b6", text: "b6" },
{ id: "b6-1", text: "b6-1" },
{ id: "b6-2", text: "b6-2" },
{ id: "b6-3", text: "b6-3" },
{ id: "b6-4", text: "b6-4" },
{ id: "b6-5", text: "b6-5" },
{ id: "c", text: "c" },
{ id: "c1", text: "c1" },
{ id: "c1-1", text: "c1-1" },
{ id: "c1-2", text: "c1-2" },
{ id: "c1-3", text: "c1-3" },
{ id: "c1-4", text: "c1-4" },
{ id: "c1-5", text: "c1-5" },
{ id: "c1-6", text: "c1-6" },
{ id: "c1-7", text: "c1-7" },
{ id: "c2", text: "c2" },
{ id: "c2-1", text: "c2-1" },
{ id: "c2-2", text: "c2-2" },
{ id: "c3", text: "c3" },
{ id: "c3-1", text: "c3-1" },
{ id: "c3-2", text: "c3-2" },
{ id: "c3-3", text: "c3-3" },
{ id: "d", text: "d" },
{ id: "d1", text: "d1" },
{ id: "d1-1", text: "d1-1" },
{ id: "d1-2", text: "d1-2" },
{ id: "d1-3", text: "d1-3" },
{ id: "d1-4", text: "d1-4" },
{ id: "d1-5", text: "d1-5" },
{ id: "d1-6", text: "d1-6" },
{ id: "d1-7", text: "d1-7" },
{ id: "d1-8", text: "d1-8" },
{ id: "d2", text: "d2" },
{ id: "d2-1", text: "d2-1" },
{ id: "d2-2", text: "d2-2" },
{ id: "d3", text: "d3" },
{ id: "d3-1", text: "d3-1" },
{ id: "d3-2", text: "d3-2" },
{ id: "d3-3", text: "d3-3" },
{ id: "d3-4", text: "d3-4" },
{ id: "d3-5", text: "d3-5" },
{ id: "d4", text: "d4" },
{ id: "d4-1", text: "d4-1" },
{ id: "d4-2", text: "d4-2" },
{ id: "d4-3", text: "d4-3" },
{ id: "d4-4", text: "d4-4" },
{ id: "d4-5", text: "d4-5" },
{ id: "d4-6", text: "d4-6" },
{ id: "e", text: "e" },
{ id: "e1", text: "上海复龙鸿芯微系统技术鸿芯微系统技术有限公司" },
{ id: "e1-1", text: "上海复龙鸿芯微系统技术鸿芯微系统技术有限公司" },
{ id: "e1-2", text: "e1-2" },
{ id: "e1-3", text: "e1-3" },
{ id: "e1-4", text: "e1-4" },
{ id: "e1-5", text: "e1-5" },
{ id: "e1-6", text: "e1-6" },
{ id: "e2", text: "e2" },
{ id: "e2-1", text: "e2-1" },
{ id: "e2-2", text: "e2-2" },
{ id: "e2-3", text: "e2-3" },
{ id: "e2-4", text: "e2-4" },
{ id: "e2-5", text: "e2-5" },
{ id: "e2-6", text: "e2-6" },
{ id: "e2-7", text: "e2-7" },
{ id: "e2-8", text: "e2-8" },
{ id: "e2-9", text: "e2-9" }
],
lines: [
{ from: "a", to: "b", text: '从属', fontColor: 'var(--color-orange-100)', color: 'orange', textOffset_x: -20, lineWidth: 5},
{ from: "b", to: "b1" },
{ from: "b1", to: "b1-1" },
{ from: "b1", to: "b1-2" },
{ from: "b1", to: "b1-3" },
{ from: "b1", to: "b1-4" },
{ from: "b1", to: "b1-5" },
{ from: "b1", to: "b1-6" },
{ from: "b", to: "b2" },
{ from: "b2", to: "b2-1" },
{ from: "b2", to: "b2-2" },
{ from: "b2", to: "b2-3" },
{ from: "b2", to: "b2-4" },
{ from: "b", to: "b3" },
{ from: "b3", to: "b3-1" },
{ from: "b3", to: "b3-2" },
{ from: "b3", to: "b3-3" },
{ from: "b3", to: "b3-4" },
{ from: "b3", to: "b3-5" },
{ from: "b3", to: "b3-6" },
{ from: "b3", to: "b3-7" },
{ from: "b", to: "b4" },
{ from: "b4", to: "b4-1" },
{ from: "b4", to: "b4-2" },
{ from: "b4", to: "b4-3" },
{ from: "b4", to: "b4-4" },
{ from: "b4", to: "b4-5" },
{ from: "b4", to: "b4-6" },
{ from: "b4", to: "b4-7" },
{ from: "b4", to: "b4-8" },
{ from: "b4", to: "b4-9" },
{ from: "b", to: "b5" },
{ from: "b5", to: "b5-1" },
{ from: "b5", to: "b5-2" },
{ from: "b5", to: "b5-3" },
{ from: "b5", to: "b5-4" },
{ from: "b", to: "b6" },
{ from: "b6", to: "b6-1" },
{ from: "b6", to: "b6-2" },
{ from: "b6", to: "b6-3" },
{ from: "b6", to: "b6-4" },
{ from: "b6", to: "b6-5" },
{ from: "a", to: "c" },
{ from: "c", to: "c1" },
{ from: "c1", to: "c1-1" },
{ from: "c1", to: "c1-2" },
{ from: "c1", to: "c1-3" },
{ from: "c1", to: "c1-4" },
{ from: "c1", to: "c1-5" },
{ from: "c1", to: "c1-6" },
{ from: "c1", to: "c1-7" },
{ from: "c", to: "c2" },
{ from: "c2", to: "c2-1" },
{ from: "c2", to: "c2-2" },
{ from: "c", to: "c3" },
{ from: "c3", to: "c3-1" },
{ from: "c3", to: "c3-2" },
{ from: "c3", to: "c3-3" },
{ from: "a", to: "d" },
{ from: "d", to: "d1" },
{ from: "d1", to: "d1-1" },
{ from: "d1", to: "d1-2" },
{ from: "d1", to: "d1-3" },
{ from: "d1", to: "d1-4" },
{ from: "d1", to: "d1-5" },
{ from: "d1", to: "d1-6" },
{ from: "d1", to: "d1-7" },
{ from: "d1", to: "d1-8" },
{ from: "d", to: "d2" },
{ from: "d2", to: "d2-1" },
{ from: "d2", to: "d2-2" },
{ from: "d", to: "d3" },
{ from: "d3", to: "d3-1" },
{ from: "d3", to: "d3-2" },
{ from: "d3", to: "d3-3" },
{ from: "d3", to: "d3-4" },
{ from: "d3", to: "d3-5" },
{ from: "d", to: "d4" },
{ from: "d4", to: "d4-1" },
{ from: "d4", to: "d4-2" },
{ from: "d4", to: "d4-3" },
{ from: "d4", to: "d4-4" },
{ from: "d4", to: "d4-5" },
{ from: "d4", to: "d4-6" },
{ from: "a", to: "e" },
{ from: "e", to: "e1" },
{ from: "e1", to: "e1-1" },
{ from: "e1", to: "e1-2" },
{ from: "e1", to: "e1-3" },
{ from: "e1", to: "e1-4" },
{ from: "e1", to: "e1-5" },
{ from: "e1", to: "e1-6" },
{ from: "e", to: "e2" },
{ from: "e2", to: "e2-1" },
{ from: "e2", to: "e2-2" },
{ from: "e2", to: "e2-3" },
{ from: "e2", to: "e2-4" },
{ from: "e2", to: "e2-5" },
{ from: "e2", to: "e2-6" },
{ from: "e2", to: "e2-7" },
{ from: "e2", to: "e2-8" },
{ from: "e2", to: "e2-9" }
]
});
const handleClickNode = (value) => {
console.log('value', value);
alert('我点击了node-'+ value.text)
}
const handleClickLine = (value) => {
console.log('value', value);
alert('我点击了line-'+ value.text)
}
</script>
<style lang="scss" scoped>
.tab-box {
margin-top: 20px;
margin-left: 20px;
}
.chart-box {
width: 1600px;
height: 500px;
}
</style>
\ No newline at end of file
<template>
<el-row class="wrapper layout-grid-line">
<el-col :span="span">
<pre>
{{
`
import RelationForceChart from '@/components/base/RelationForceChart/index.vue'
<div class="chart-box">
<RelationForceChart :graph-data="graphData" />
</div>
`
}}
</pre>
<div class="chart-box">
<RelationForceChart @line-click="handleClickLine" @node-click="handleClickNode" :graph-data="graphData" />
</div>
</el-col>
</el-row>
</template>
<script setup>
import { ref } from "vue";
import "@/styles/common.scss";
import RelationForceChart from "@/components/base/RelationForceChart/index.vue";
const span = 24;
import Img from "@/assets/icons/symbol.png";
const graphData = ref({
rootId: "a",
nodes: [
{
id: "a",
text: "root",
data: {
pic: Img,
name: "xxx图片"
}
},
{ id: "b", text: "b" },
{
id: "b1",
text: "上海复龙鸿芯微系统技术有限公司",
data: {
pic: Img,
name: "xxx图片"
}
},
{ id: "b1-1", text: "b1-1" },
{ id: "b1-2", text: "b1-2" },
{ id: "b1-3", text: "b1-3" },
{ id: "b1-4", text: "b1-4" },
{ id: "b1-5", text: "b1-5" },
{ id: "b1-6", text: "b1-6" },
{ id: "b2", text: "b2" },
{ id: "b2-1", text: "b2-1" },
{ id: "b2-2", text: "b2-2" },
{ id: "b2-3", text: "b2-3" },
{ id: "b2-4", text: "b2-4" },
{ id: "b3", text: "b3" },
{ id: "b3-1", text: "b3-1" },
{ id: "b3-2", text: "b3-2" },
{ id: "b3-3", text: "b3-3" },
{ id: "b3-4", text: "b3-4" },
{ id: "b3-5", text: "b3-5" },
{ id: "b3-6", text: "b3-6" },
{ id: "b3-7", text: "b3-7" },
{ id: "b4", text: "b4" },
{ id: "b4-1", text: "b4-1" },
{ id: "b4-2", text: "b4-2" },
{ id: "b4-3", text: "b4-3" },
{ id: "b4-4", text: "b4-4" },
{ id: "b4-5", text: "b4-5" },
{ id: "b4-6", text: "b4-6" },
{ id: "b4-7", text: "b4-7" },
{ id: "b4-8", text: "b4-8" },
{ id: "b4-9", text: "b4-9" },
{ id: "b5", text: "b5" },
{ id: "b5-1", text: "b5-1" },
{ id: "b5-2", text: "b5-2" },
{ id: "b5-3", text: "b5-3" },
{ id: "b5-4", text: "b5-4" },
{ id: "b6", text: "b6" },
{ id: "b6-1", text: "b6-1" },
{ id: "b6-2", text: "b6-2" },
{ id: "b6-3", text: "b6-3" },
{ id: "b6-4", text: "b6-4" },
{ id: "b6-5", text: "b6-5" },
{ id: "c", text: "c" },
{ id: "c1", text: "c1" },
{ id: "c1-1", text: "c1-1" },
{ id: "c1-2", text: "c1-2" },
{ id: "c1-3", text: "c1-3" },
{ id: "c1-4", text: "c1-4" },
{ id: "c1-5", text: "c1-5" },
{ id: "c1-6", text: "c1-6" },
{ id: "c1-7", text: "c1-7" },
{ id: "c2", text: "c2" },
{ id: "c2-1", text: "c2-1" },
{ id: "c2-2", text: "c2-2" },
{ id: "c3", text: "c3" },
{ id: "c3-1", text: "c3-1" },
{ id: "c3-2", text: "c3-2" },
{ id: "c3-3", text: "c3-3" },
{ id: "d", text: "d" },
{ id: "d1", text: "d1" },
{ id: "d1-1", text: "d1-1" },
{ id: "d1-2", text: "d1-2" },
{ id: "d1-3", text: "d1-3" },
{ id: "d1-4", text: "d1-4" },
{ id: "d1-5", text: "d1-5" },
{ id: "d1-6", text: "d1-6" },
{ id: "d1-7", text: "d1-7" },
{ id: "d1-8", text: "d1-8" },
{ id: "d2", text: "d2" },
{ id: "d2-1", text: "d2-1" },
{ id: "d2-2", text: "d2-2" },
{ id: "d3", text: "d3" },
{ id: "d3-1", text: "d3-1" },
{ id: "d3-2", text: "d3-2" },
{ id: "d3-3", text: "d3-3" },
{ id: "d3-4", text: "d3-4" },
{ id: "d3-5", text: "d3-5" },
{ id: "d4", text: "d4" },
{ id: "d4-1", text: "d4-1" },
{ id: "d4-2", text: "d4-2" },
{ id: "d4-3", text: "d4-3" },
{ id: "d4-4", text: "d4-4" },
{ id: "d4-5", text: "d4-5" },
{ id: "d4-6", text: "d4-6" },
{ id: "e", text: "e" },
{ id: "e1", text: "e1" },
{ id: "e1-1", text: "e1-1" },
{ id: "e1-2", text: "e1-2" },
{ id: "e1-3", text: "e1-3" },
{ id: "e1-4", text: "e1-4" },
{ id: "e1-5", text: "e1-5" },
{ id: "e1-6", text: "e1-6" },
{ id: "e2", text: "e2" },
{ id: "e2-1", text: "e2-1" },
{ id: "e2-2", text: "e2-2" },
{ id: "e2-3", text: "e2-3" },
{ id: "e2-4", text: "e2-4" },
{ id: "e2-5", text: "e2-5" },
{ id: "e2-6", text: "e2-6" },
{ id: "e2-7", text: "e2-7" },
{ id: "e2-8", text: "e2-8" },
{ id: "e2-9", text: "e2-9" }
],
lines: [
{ from: "a", to: "b", text:'控股', color: 'orange',fontColor:'red', lineWidth: 5, textOffset_y: -8, },
{ from: "b", to: "b1" },
{ from: "b1", to: "b1-1" },
{ from: "b1", to: "b1-2" },
{ from: "b1", to: "b1-3" },
{ from: "b1", to: "b1-4" },
{ from: "b1", to: "b1-5" },
{ from: "b1", to: "b1-6" },
{ from: "b", to: "b2" },
{ from: "b2", to: "b2-1" },
{ from: "b2", to: "b2-2" },
{ from: "b2", to: "b2-3" },
{ from: "b2", to: "b2-4" },
{ from: "b", to: "b3" },
{ from: "b3", to: "b3-1" },
{ from: "b3", to: "b3-2" },
{ from: "b3", to: "b3-3" },
{ from: "b3", to: "b3-4" },
{ from: "b3", to: "b3-5" },
{ from: "b3", to: "b3-6" },
{ from: "b3", to: "b3-7" },
{ from: "b", to: "b4" },
{ from: "b4", to: "b4-1" },
{ from: "b4", to: "b4-2" },
{ from: "b4", to: "b4-3" },
{ from: "b4", to: "b4-4" },
{ from: "b4", to: "b4-5" },
{ from: "b4", to: "b4-6" },
{ from: "b4", to: "b4-7" },
{ from: "b4", to: "b4-8" },
{ from: "b4", to: "b4-9" },
{ from: "b", to: "b5" },
{ from: "b5", to: "b5-1" },
{ from: "b5", to: "b5-2" },
{ from: "b5", to: "b5-3" },
{ from: "b5", to: "b5-4" },
{ from: "b", to: "b6" },
{ from: "b6", to: "b6-1" },
{ from: "b6", to: "b6-2" },
{ from: "b6", to: "b6-3" },
{ from: "b6", to: "b6-4" },
{ from: "b6", to: "b6-5" },
{ from: "a", to: "c" },
{ from: "c", to: "c1" },
{ from: "c1", to: "c1-1" },
{ from: "c1", to: "c1-2" },
{ from: "c1", to: "c1-3" },
{ from: "c1", to: "c1-4" },
{ from: "c1", to: "c1-5" },
{ from: "c1", to: "c1-6" },
{ from: "c1", to: "c1-7" },
{ from: "c", to: "c2" },
{ from: "c2", to: "c2-1" },
{ from: "c2", to: "c2-2" },
{ from: "c", to: "c3" },
{ from: "c3", to: "c3-1" },
{ from: "c3", to: "c3-2" },
{ from: "c3", to: "c3-3" },
{ from: "a", to: "d" },
{ from: "d", to: "d1" },
{ from: "d1", to: "d1-1" },
{ from: "d1", to: "d1-2" },
{ from: "d1", to: "d1-3" },
{ from: "d1", to: "d1-4" },
{ from: "d1", to: "d1-5" },
{ from: "d1", to: "d1-6" },
{ from: "d1", to: "d1-7" },
{ from: "d1", to: "d1-8" },
{ from: "d", to: "d2" },
{ from: "d2", to: "d2-1" },
{ from: "d2", to: "d2-2" },
{ from: "d", to: "d3" },
{ from: "d3", to: "d3-1" },
{ from: "d3", to: "d3-2" },
{ from: "d3", to: "d3-3" },
{ from: "d3", to: "d3-4" },
{ from: "d3", to: "d3-5" },
{ from: "d", to: "d4" },
{ from: "d4", to: "d4-1" },
{ from: "d4", to: "d4-2" },
{ from: "d4", to: "d4-3" },
{ from: "d4", to: "d4-4" },
{ from: "d4", to: "d4-5" },
{ from: "d4", to: "d4-6" },
{ from: "a", to: "e" },
{ from: "e", to: "e1" },
{ from: "e1", to: "e1-1" },
{ from: "e1", to: "e1-2" },
{ from: "e1", to: "e1-3" },
{ from: "e1", to: "e1-4" },
{ from: "e1", to: "e1-5" },
{ from: "e1", to: "e1-6" },
{ from: "e", to: "e2" },
{ from: "e2", to: "e2-1" },
{ from: "e2", to: "e2-2" },
{ from: "e2", to: "e2-3" },
{ from: "e2", to: "e2-4" },
{ from: "e2", to: "e2-5" },
{ from: "e2", to: "e2-6" },
{ from: "e2", to: "e2-7" },
{ from: "e2", to: "e2-8" },
{ from: "e2", to: "e2-9" }
]
});
const handleClickNode = (value) => {
console.log('value', value);
alert('我点击了node-'+ value.text)
}
const handleClickLine = (value) => {
console.log('value', value);
alert('我点击了line-'+ value.text)
}
</script>
<style lang="scss" scoped>
.chart-box {
width: 1600px;
height: 600px;
}
</style>
\ No newline at end of file
...@@ -61,6 +61,15 @@ ...@@ -61,6 +61,15 @@
<el-tab-pane label="词云图" lazy> <el-tab-pane label="词云图" lazy>
<WordCloudChart /> <WordCloudChart />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="关系图" lazy>
<RelationChart />
</el-tab-pane>
<el-tab-pane label="中心关系图" lazy>
<RelationCenterChart />
</el-tab-pane>
<el-tab-pane label="引力关系图" lazy>
<RelationForceChart />
</el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</el-space> </el-space>
...@@ -91,6 +100,9 @@ import NewsPage from './News/index.vue' ...@@ -91,6 +100,9 @@ import NewsPage from './News/index.vue'
import TimeTabPane from './TimeTabPane/index.vue' import TimeTabPane from './TimeTabPane/index.vue'
import AiInfo from './Ai/AiInfo/index.vue' import AiInfo from './Ai/AiInfo/index.vue'
import AiSummary from './Ai/AiSummary/index.vue' import AiSummary from './Ai/AiSummary/index.vue'
import RelationChart from './RelationChart/index.vue'
import RelationCenterChart from './RelationCenterChart/index.vue'
import RelationForceChart from './RelationForceChart/index.vue'
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
......
const getQuarterRange = (quatarNum) => { const getQuarterRange = (year, quatarNum) => {
const quarters = { const quarters = {
1: ['2025-01-01', '2025-03-31'], 1: [year+ '-01-01', year+ '-03-31'],
2: ['2025-04-01', '2025-06-30'], 2: [year+ '-04-01', year+ '-06-30'],
3: ['2025-07-01', '2025-09-30'], 3: [year+ '-07-01', year+ '-09-30'],
4: ['2025-10-01', '2025-12-31'] 4: [year+ '-10-01', year+ '-12-31']
}; };
return quarters[quatarNum]; return quarters[quatarNum];
......
...@@ -16,67 +16,51 @@ const setChart = (option, chartId, allowClick, selectParam) => { ...@@ -16,67 +16,51 @@ const setChart = (option, chartId, allowClick, selectParam) => {
chart.on('click', function (params) { chart.on('click', function (params) {
switch (selectParam.moduleType) { switch (selectParam.moduleType) {
case '国会法案': case '国会法案':
// 判断点击的是否为饼图的数据项 if (selectParam.key === 1) {
if (params.componentType === 'series' && params.seriesType === 'pie') { // console.log('当前点击', selectParam, params.seriesName, params.name);
console.log('点击的扇形名称:', params.name); selectParam.selectedStatus = params.seriesName
if (selectParam.key === '领域') { selectParam.selectedDate = JSON.stringify(getMonthRange(params.name))
selectParam.domains = params.name const route = router.resolve({
path: "/dataLibrary/countryBill",
query: selectParam
});
window.open(route.href, "_blank");
return
} else if (selectParam.key === 2) {
selectParam.domains = params.name
const route = router.resolve({
path: "/dataLibrary/countryBill",
query: selectParam
});
window.open(route.href, "_blank");
return
} else if (selectParam.key === 3) {
if (params.name === '众议院' || params.name === '参议院') {
selectParam.selectedCongress = params.name
selectParam.selectedOrg = '全部委员会'
if (selectParam.selectedDate.length === 4) { if (selectParam.selectedDate.length === 4) {
selectParam.selectedDate = JSON.stringify([selectParam.selectedDate + '-01-01', selectParam.selectedDate + '-12-31']) selectParam.selectedDate = JSON.stringify([selectParam.selectedDate + '-01-01', selectParam.selectedDate + '-12-31'])
} }
} else if (selectParam.key === '议院委员会') { } else {
if (params.name === '众议院' || params.name === '参议院') { selectParam.selectedOrg = params.name
selectParam.selectedCongress = params.name selectParam.selectedCongress = '全部议院'
selectParam.selectedOrg = '' if (selectParam.selectedDate.length === 4) {
if (selectParam.selectedDate.length === 4) { selectParam.selectedDate = JSON.stringify([selectParam.selectedDate + '-01-01', selectParam.selectedDate + '-12-31'])
selectParam.selectedDate = JSON.stringify([selectParam.selectedDate + '-01-01', selectParam.selectedDate + '-12-31'])
}
} else {
selectParam.selectedOrg = params.name
selectParam.selectedCongress = ''
if (selectParam.selectedDate.length === 4) {
selectParam.selectedDate = JSON.stringify([selectParam.selectedDate + '-01-01', selectParam.selectedDate + '-12-31'])
}
} }
} }
const route = router.resolve({ const route = router.resolve({
path: "/dataLibrary/countryBill", path: "/dataLibrary/countryBill",
query: selectParam query: selectParam
}); });
window.open(route.href, "_blank"); window.open(route.href, "_blank");
} else if (params.componentType === 'series' && params.seriesType === 'bar') { return
if (params.name === '已立法') { } else {
selectParam.selectedStatus = 1 selectParam.selectedStatus = params.name
} else {
selectParam.selectedStatus = 0
}
if (selectParam.selectedDate.length === 4) {
selectParam.selectedDate = JSON.stringify([selectParam.selectedDate + '-01-01', selectParam.selectedDate + '-12-31'])
}
const route = router.resolve({ const route = router.resolve({
path: "/dataLibrary/countryBill", path: "/dataLibrary/countryBill",
query: selectParam query: selectParam
}); });
window.open(route.href, "_blank"); window.open(route.href, "_blank");
} else {
console.log('当前点击', selectParam, params.seriesName, params.name);
if (params.seriesName !== '通过率') {
selectParam.selectedDate = JSON.stringify(getMonthRange(params.name))
if (params.seriesName === '通过法案') {
selectParam.selectedStatus = 1
} else {
selectParam.selectedStatus = null
}
const route = router.resolve({
path: "/dataLibrary/countryBill",
query: selectParam
});
window.open(route.href, "_blank");
}
} }
break break
...@@ -89,16 +73,38 @@ const setChart = (option, chartId, allowClick, selectParam) => { ...@@ -89,16 +73,38 @@ const setChart = (option, chartId, allowClick, selectParam) => {
}); });
window.open(route.href, "_blank"); window.open(route.href, "_blank");
} else if (params.componentType === 'series' && params.seriesType === 'bar') { } else if (params.componentType === 'series' && params.seriesType === 'bar') {
const year = params.name.slice(0, 4)
const quatarNum = Number(params.name[params.name.length - 1]) const quatarNum = Number(params.name[params.name.length - 1])
selectParam.selectedDate = JSON.stringify(getQuarterRange(quatarNum)) selectParam.selectedDate = JSON.stringify(getQuarterRange(year, quatarNum))
const route = router.resolve({ const route = router.resolve({
path: "/dataLibrary/dataDecree", path: "/dataLibrary/dataDecree",
query: selectParam query: selectParam
}); });
window.open(route.href, "_blank"); window.open(route.href, "_blank");
} }
break
case '科技智库报告':
if (selectParam.key === 1) {
selectParam.domains = params.seriesName
const year = params.name.slice(0, 4)
const quatarNum = Number(params.name[params.name.length - 1])
selectParam.selectedDate = JSON.stringify(getQuarterRange(year, quatarNum))
const route = router.resolve({
path: "/dataLibrary/dataThinkTank",
query: selectParam
});
window.open(route.href, "_blank");
return
} else if (selectParam.key === 2) {
selectParam.domains = params.name
const route = router.resolve({
path: "/dataLibrary/dataThinkTank",
query: selectParam
});
window.open(route.href, "_blank");
return
}
} }
}); });
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<el-button :type="box1Btn2Type" plain @click="handleClickBox1Btn(2)">全部背景</el-button> <el-button :type="box1Btn2Type" plain @click="handleClickBox1Btn(2)">全部背景</el-button>
</div> </div>
</template> </template>
<div class="box1-main"> <div class="box1-main" v-loading="backgroundLoading">
<div class="box1-main-center"> <div class="box1-main-center">
<div class="box1-main-item" v-for="item in backgroundDisplayList" :key="item.id"> <div class="box1-main-item" v-for="item in backgroundDisplayList" :key="item.id">
<div class="id">{{ item.displayIndex }}</div> <div class="id">{{ item.displayIndex }}</div>
...@@ -198,6 +198,8 @@ const handleClickBox2Btn = index => { ...@@ -198,6 +198,8 @@ const handleClickBox2Btn = index => {
const aboutUserList = ref([]); const aboutUserList = ref([]);
const backgroundList = ref([]); const backgroundList = ref([]);
const backgroundLoading = ref(false);
let backgroundAbortController = null;
const eventList = ref([]); const eventList = ref([]);
...@@ -244,6 +246,12 @@ const nextIconColor = computed(() => (currentIndex.value < personList.value.leng ...@@ -244,6 +246,12 @@ const nextIconColor = computed(() => (currentIndex.value < personList.value.leng
// 获取立法背景内容 // 获取立法背景内容
const handleGetBillBackground = async () => { const handleGetBillBackground = async () => {
if (backgroundAbortController) {
backgroundAbortController.abort();
}
const controller = new AbortController();
backgroundAbortController = controller;
const cRelated = box1BtnActive.value === 1 ? "Y" : "N"; const cRelated = box1BtnActive.value === 1 ? "Y" : "N";
const params = { const params = {
cRelated: cRelated, cRelated: cRelated,
...@@ -251,11 +259,21 @@ const handleGetBillBackground = async () => { ...@@ -251,11 +259,21 @@ const handleGetBillBackground = async () => {
currentPage: currentPage.value - 1, currentPage: currentPage.value - 1,
pageSize: 10 pageSize: 10
}; };
backgroundLoading.value = true;
try { try {
const res = await getBillBackground(params); const res = await getBillBackground(params, { signal: controller.signal });
backgroundList.value = res.data.content; backgroundList.value = res.data.content;
total.value = res.data.totalElements; // 假设API返回totalElements total.value = res.data.totalElements; // 假设API返回totalElements
} catch (error) { } } catch (error) {
if (error?.name !== "AbortError" && error?.code !== "ERR_CANCELED") {
console.error(error);
}
} finally {
if (backgroundAbortController === controller) {
backgroundLoading.value = false;
backgroundAbortController = null;
}
}
}; };
// 获取相关事件 // 获取相关事件
......
...@@ -49,7 +49,8 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData, ...@@ -49,7 +49,8 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData,
containLabel: true containLabel: true
}, },
legend: { legend: {
data: ['提出法案', '通过法案', '众议院通过', '参议院通过', '双院通过'], // 图例顺序:提出法案、众议院通过、参议院通过、解决分歧、完成立法
data: ['提出法案', '众议院通过', '参议院通过', '解决分歧', '完成立法'],
show: true, show: true,
top: 10, top: 10,
icon: 'circle', icon: 'circle',
...@@ -126,7 +127,8 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData, ...@@ -126,7 +127,8 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData,
data: proposedData data: proposedData
}, },
{ {
name: '通过法案', // 众议院通过
name: '众议院通过',
type: 'line', type: 'line',
smooth: true, smooth: true,
symbol: 'emptyCircle', symbol: 'emptyCircle',
...@@ -137,10 +139,11 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData, ...@@ -137,10 +139,11 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData,
itemStyle: { itemStyle: {
color: lineColors[1] color: lineColors[1]
}, },
data: passData data: houseData
}, },
{ {
name: '众议院通过', // 参议院通过
name: '参议院通过',
type: 'line', type: 'line',
smooth: true, smooth: true,
symbol: 'emptyCircle', symbol: 'emptyCircle',
...@@ -151,10 +154,11 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData, ...@@ -151,10 +154,11 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData,
itemStyle: { itemStyle: {
color: lineColors[2] color: lineColors[2]
}, },
data: houseData data: senateData
}, },
{ {
name: '参议院通过', // 解决分歧
name: '解决分歧',
type: 'line', type: 'line',
smooth: true, smooth: true,
symbol: 'emptyCircle', symbol: 'emptyCircle',
...@@ -165,10 +169,11 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData, ...@@ -165,10 +169,11 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData,
itemStyle: { itemStyle: {
color: lineColors[3] color: lineColors[3]
}, },
data: senateData data: hsData
}, },
{ {
name: '双院通过', // 完成立法
name: '完成立法',
type: 'line', type: 'line',
smooth: true, smooth: true,
symbol: 'emptyCircle', symbol: 'emptyCircle',
...@@ -179,7 +184,7 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData, ...@@ -179,7 +184,7 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData,
itemStyle: { itemStyle: {
color: lineColors[4] color: lineColors[4]
}, },
data: hsData data: passData
} }
] ]
} }
......
...@@ -27,29 +27,17 @@ ...@@ -27,29 +27,17 @@
</div> </div>
<div class="left-box-bottom" v-if="showTabs"> <div class="left-box-bottom" v-if="showTabs">
<template v-if="isLoading"> <div class="left-box-bottom-item"
<div class="left-box-bottom-item is-skeleton" v-for="n in 4" :key="n"> :class="{ leftBoxBottomItemActive: activeTitle === item.name }" v-for="item in tabs"
<div class="icon"> :key="item.path" @click="emit('tab-click', item)">
<el-skeleton-item class="skeleton-tab-icon" variant="text" /> <div class="icon">
</div> <img v-if="activeTitle === item.name" :src="item.activeIcon" alt="" />
<div class="name"> <img v-else :src="item.icon" alt="" />
<el-skeleton-item class="skeleton-tab-text" variant="text" />
</div>
</div> </div>
</template> <div class="name" :class="{ nameActive: activeTitle === item.name }">
<template v-else> {{ item.name }}
<div class="left-box-bottom-item"
:class="{ leftBoxBottomItemActive: activeTitle === item.name }" v-for="item in tabs"
:key="item.path" @click="emit('tab-click', item)">
<div class="icon">
<img v-if="activeTitle === item.name" :src="item.activeIcon" alt="" />
<img v-else :src="item.icon" alt="" />
</div>
<div class="name" :class="{ nameActive: activeTitle === item.name }">
{{ item.name }}
</div>
</div> </div>
</template> </div>
</div> </div>
</div> </div>
...@@ -73,30 +61,18 @@ ...@@ -73,30 +61,18 @@
</div> </div>
<div class="right-box-bottom" v-if="showActions"> <div class="right-box-bottom" v-if="showActions">
<template v-if="isLoading"> <div class="btn2" @click="emit('open-analysis', 'forsee')">
<div class="btn3 is-skeleton"> <div class="icon">
<div class="icon"> <img :src="btnIconForsee" alt="" />
<el-skeleton-item class="skeleton-action-icon" variant="text" />
</div>
<div class="text">
<el-skeleton-item class="skeleton-action-text" variant="text" />
</div>
</div> </div>
</template> <div class="text">{{ "进展预测" }}</div>
<template v-else> </div>
<div class="btn2" @click="emit('open-analysis', 'forsee')"> <div class="btn3" @click="emit('open-analysis', 'analysis')">
<div class="icon"> <div class="icon">
<img :src="btnIconForsee" alt="" /> <img :src="btnIconAnalysis" alt="" />
</div>
<div class="text">{{ "进展预测" }}</div>
</div>
<div class="btn3" @click="emit('open-analysis', 'analysis')">
<div class="icon">
<img :src="btnIconAnalysis" alt="" />
</div>
<div class="text">{{ "分析报告" }}</div>
</div> </div>
</template> <div class="text">{{ "分析报告" }}</div>
</div>
</div> </div>
</div> </div>
</div> </div>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论