一、编译软件环境准备——vscode/webstorm都可
二、echarts环境准备
1.打开下列网站复制所有内容到粘贴板
2.打开vscode或者webstorm界面化编译软件,创建一个文件夹(自定义文件名)并在文件夹里创建一个名为echarts.min.js文件,打开此文件粘贴上述复制到粘贴板上的内容。
三、创建html网页框架
1.在与上面相同的文件夹里创建hlm.html(文件名可自定义)快捷键"!"生成标准网页框架。
四、代码详细分析
1.HTML建立一个图示容器,并把echarts配置以JavaScript的链接方式导入
2.在body标签编写web前端代码(关系图容器、图例、搜索框)为网页显示功能做准备
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>红楼梦角色关系图</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Pacifico&display=swap">
</head>
<body>
<!-- 用一个 div 容器来放置关系图 -->
<div id="main" style="width: 800px;height:600px;"></div>
<!-- 用于显示图例的复选框 -->
<div>
<label><input type="checkbox" id="cb_person" checked> 人物</label>
<label><input type="checkbox" id="cb_place" checked> 地点</label>
<label><input type="checkbox" id="cb_event" checked> 事件</label>
</div>
<!-- 搜索框 -->
<div>
<input type="text" id="searchInput" placeholder="搜索节点">
<button onclick="search()">搜索</button>
</div>
<script src="echarts.min.js"></script>
</body>
</html>
3.紧接着新建一个script标签并写上以下中的代码(下述代码为完整代码,仅作参考,如需与步骤相符可直接选择性观看)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>红楼梦人物关系图</title>
<!-- 引入 ECharts -->
</head>
<body>
<!-- 用一个 div 容器来放置关系图 -->
<div id="main" style="width: 800px;height:600px;"></div>
<!-- 用于显示图例的复选框 -->
<div>
<label><input type="checkbox" id="cb_person" checked> 人物</label>
<label><input type="checkbox" id="cb_place" checked> 地点</label>
<label><input type="checkbox" id="cb_event" checked> 事件</label>
</div>
<!-- 搜索框 -->
<div>
<input type="text" id="searchInput" placeholder="搜索节点">
<button onclick="search()">搜索</button>
</div>
<script src="echarts.min.js"></script>
<script>
// 初始化关系图实例
var myChart = echarts.init(document.getElementById('main'));
// 准备数据
var data = {
nodes: [
{ name: '贾宝玉', category: '人物',draggable: true,symbolSize: [40, 40],itemStyle: {color: "green",},},
{ name: '林黛玉', category: '人物',draggable: true,symbolSize: [40, 40],itemStyle: {color: "green",},},
{ name: '薛宝钗', category: '人物',draggable: true,symbolSize: [40, 40],itemStyle: {color: "green",}, },
{ name: '贾母', category: '人物',draggable: true,symbolSize: [40, 40],itemStyle: {color: "green",}, },
{ name: '荣国府', category: '地点',draggable: true,symbolSize: [40, 40], itemStyle: {color: "yellow",},},
{ name: '荣国府大门', category: '地点',draggable: true,symbolSize: [40, 40],itemStyle: {color: "yellow",}, },
{ name: '元妃府', category: '地点',draggable: true,symbolSize: [40, 40], itemStyle: {color: "yellow",},},
{ name: '贾府', category: '地点',draggable: true,symbolSize: [40, 40],itemStyle: {color: "yellow",}, },
{ name: '贾府后院', category: '地点',draggable: true,symbolSize: [40, 40],itemStyle: {color: "yellow",}, },
{ name: '大观园', category: '地点',draggable: true,symbolSize: [40, 40],itemStyle: {color: "yellow",}, },
{ name: '荣国府事件', category: '事件',draggable: true,symbolSize: [40, 40],itemStyle: {color: "red",}, },
{ name: '贾府事件', category: '事件',draggable: true,symbolSize: [40, 40],itemStyle: {color: "red",}, },
{ name: '大观园事件', category: '事件',draggable: true,symbolSize: [40, 40],itemStyle: {color: "red",}, }
// 添加更多节点...
],
links: [
{ source: '贾宝玉', target: '林黛玉' },
{ source: '贾宝玉', target: '薛宝钗' },
{ source: '贾宝玉', target: '贾母' },
{ source: '贾母', target: '荣国府' },
{ source: '荣国府', target: '荣国府大门' },
{ source: '荣国府大门', target: '元妃府' },
{ source: '贾府', target: '贾府后院' },
{ source: '贾府后院', target: '大观园' },
{ source: '大观园', target: '林黛玉' },
{ source: '大观园', target: '薛宝钗' },
{ source: '贾宝玉', target: '荣国府事件' },
{ source: '贾母', target: '贾府事件' },
{ source: '大观园', target: '大观园事件' }
// 添加更多关系...
]
};
// 配置关系图
var option;
option = {
legend: {
selectedMode: true,
y: "bottom",
x: "center",
show: true,
data: [{name:"人物",itemStyle:{color:'green'}},
{name:"事件",itemStyle:{color:'red'}},
{name:"地点",itemStyle:{color:'yellow'}},
],
},
// backgroundColor: 'pink', // 背景颜色
title: {
// 图表标题
text: "红楼梦人物关系图", // 标题文本
left: "center", // 标题距离左侧边距
top: "0%", // 标题距顶部边距
textStyle: {
// 标题样式
color: "black", // 标题字体颜色
fontSize: "30", // 标题字体大小
fontFamily:'Pacifico, cursive',
},
},
tooltip: {
confine: true,
// 提示框的配置
formatter: function (param) {
//return param.data.category + ': ' + param.data.name;
return param.data.name;
},
},
series: [
{
cursor:'pointer',
legendHoverLink: true,
data: data.nodes, // 节点数据
links: data.links,
selectedMode: true,
type: "graph", // 系列类型:关系图
top: "10%", // 图表距离容器顶部的距离
roam: true, // 是否开启鼠标缩放和平移漫游。默认不开启。如果只想要开启缩放或者平移,可以设置成 'scale' 或者 'move'。设置成 true 为都开启
focusNodeAdjacency: true, // 是否在鼠标移到节点上的时候突出显示节点以及节点的边和邻接节点。[ default: false ]
force: {
// 力引导布局相关的配置项,力引导布局是模拟弹簧电荷模型在每两个节点之间添加一个斥力,每条边的两个节点之间添加一个引力,每次迭代节点会在各个斥力和引力的作用下移动位置,多次迭代后节点会静止在一个受力平衡的位置,达到整个模型的能量最小化。
// 力引导布局的结果有良好的对称性和局部聚合性,也比较美观。
repulsion: 100, // [ default: 50 ]节点之间的斥力因子(关系对象之间的距离)。支持设置成数组表达斥力的范围,此时不同大小的值会线性映射到不同的斥力。值越大则斥力越大
edgeLength: [100, 100], // [ default: 30 ]边的两个节点之间的距离(关系对象连接线两端对象的距离,会根据关系对象值得大小来判断距离的大小),
// 这个距离也会受 repulsion。支持设置成数组表达边长的范围,此时不同大小的值会线性映射到不同的长度。值越小则长度越长。如下示例:
// 值最大的边长度会趋向于 10,值最小的边长度会趋向于 50 edgeLength: [10, 50]
},
itemStyle:{
borderColor: "rgba(140, 67, 67, 1)"
},
layout: "circular", // 图的布局。[ default: 'none' ]circular/force
symbol: "roundRect",//'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'
lineStyle: {
// 关系边的公用线条样式。其中 lineStyle.color 支持设置为'source'或者'target'特殊值,此时边会自动取源节点或目标节点的颜色作为自己的颜色。
normal: {
textStyle:{
fontSize:10,
// color:red,
},
color: "black", // 线的颜色[ default: '#aaa' ]
width: 1, // 线宽[ default: 1 ]
type: "solid", // 线的类型[ default: solid ] 'dashed' 'dotted'
opacity: 0.5, // 图形透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。[ default: 0.5 ]
curveness: 0.4, // 边的曲度,支持从 0 到 1 的值,值越大曲度越大。[ default: 0 ]
},
},
label: {
// 关系对象上的标签
normal: {
show: true, // 是否显示标签
position: "inside", // 标签位置:'top''left''right''bottom''inside''insideLeft''insideRight''insideTop''insideBottom''insideTopLeft''insideBottomLeft''insideTopRight''insideBottomRight'
textStyle: {
// 文本样式
fontSize: 10,
// color:'red'
},
},
},
edgeLabel: {
// 连接两个关系对象的线上的标签
normal: {
show: true,
textStyle: {
fontSize: 14,
color: "red",
},
formatter: function (param) {
// 标签内容
return param.data.category;
},
},
},
categories: [
{
// 节点分类的类目,可选。如果节点有分类的话可以通过 data[i].category 指定每个节点的类目,类目的样式会被应用到节点样式上。图例也可以基于categories名字展现和筛选。
name: "人物", // 类目名称,用于和 legend 对应以及格式化 tooltip 的内容。
},
{
name: "事件",
},
{
name: "地点",
},
],
},
],
animationEasingUpdate: "quinticInOut", // 数据更新动画的缓动效果。[ default: cubicOut ] "quinticInOut"
animationDurationUpdate: 100, // 数据更新动画的时长。[ default: 300 ]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
<script src="hlm.js"></script>
</body>
</html>
4.在上一步的基础上同二.2建立一个hlm.js文件(文件名自定义),并以相同的方式导入此网页结构实现搜索功能
5.编写hlm.js内容——编写搜索功能的js代码
// 为复选框添加事件监听
var checkboxes = document.querySelectorAll('input[type="checkbox"]');
checkboxes.forEach(function (checkbox) {
checkbox.addEventListener("change", function () {
updateChart();
});
});
// 搜索功能
function search() {
var searchInput = document.getElementById('searchInput').value.trim().toLowerCase();
var matchedNodes = data.nodes.filter(function(node) {
return node.name.toLowerCase().includes(searchInput);
});
if (matchedNodes.length > 0) {
var matchedLinks = data.links.filter(function(link) {
return matchedNodes.some(function(node) {
return node.name === link.source || node.name === link.target;
});
});
// 找到搜索节点对应的所有关联节点
var relatedNodes = [];
matchedLinks.forEach(function(link) {
relatedNodes.push(link.source);
relatedNodes.push(link.target);
});
relatedNodes = Array.from(new Set(relatedNodes)); // 去重
// 将搜索到的节点以及其关联节点添加到结果中
matchedNodes.forEach(function(node) {
if (!relatedNodes.includes(node.name)) {
relatedNodes.push(node.name);
}
});
var matchedAndRelatedNodes = data.nodes.filter(function(node) {
return relatedNodes.includes(node.name);
});
var matchedAndRelatedLinks = data.links.filter(function(link) {
return matchedAndRelatedNodes.some(function(node) {
return node.name === link.source || node.name === link.target;
});
});
myChart.setOption({
series: [{
data: matchedAndRelatedNodes,
links: matchedAndRelatedLinks
}]
});
} else {
alert('未找到匹配节点。');
}
}
// 更新图表数据
function updateChart() {
var selectedCategories = [];
checkboxes.forEach(function (cb) {
if (cb.checked) {
selectedCategories.push(cb.id.replace("cb_", ""));
}
});
// 更新图表数据
var updatedNodes = data.nodes.filter(function (node) {
return selectedCategories.includes(node.category);
});
var updatedLinks = data.links.filter(function (link) {
return (
selectedCategories.includes(
updatedNodes.find((n) => n.name === link.source).category
) &&
selectedCategories.includes(
updatedNodes.find((n) => n.name === link.target).category
)
);
});
myChart.setOption({
series: [
{
data: updatedNodes,
links: updatedLinks,
},
],
});
}