这个大屏是我们中医大数据的另一个组成部分,展示了一套完整的中药和药方关系数据图谱方案,采用了 Vue 和 ECharts 前端技术,后端使用 Spring Boot 开发,数据通过 Scrapy 爬虫工程采集,形成了一个可视化的数据展示平台。
1 实现截图
数据大屏,数据大屏支持各种不同形式的展示
force图展示
环形图展示
图谱构造部分
neo4j截图部分
2 总体概述
整个大屏通过丰富的图表与数据展示了中医药材和药方的多维度信息,包括用户注册数量、中药药材和药方的记录数、热门词汇图、性味比例、中药产地分布及注册情况等。
详细部分
顶部区域:展示了系统的总体统计信息,包括平台总用户数、中药药材记录数和中药药方记录数,为用户提供整体数据的概览。
左上角图表:展示了各种古籍的收录排行,说明了中药材信息主要来源于哪些古籍,反映了古籍在中医药材数据中的重要性。
左下角图表:展示性味比例图,不同颜色的扇形代表不同性味的中药材数量占比,帮助用户直观了解中医药性味的分布情况。
中部主要区域:中药药方关系图谱展示了不同药方和药材之间的关系,节点以 “Book” 和 “Prescription” 两种颜色区分,青色节点代表书籍,橙色节点代表药方,各个节点之间的连线展示了它们之间的关系,帮助识别药材和药方的联系网络。
右上角图表:通过词云图展示了中药相关的大数据热词,可以用户快速了解当前中药领域的热点话题和研究方向。
右中部图表:中药产地分布图,通过辐射状的图形展示了中药材的主要产地分布信息,图上的不同区域代表不同省份,每个省份用不同的颜色标记。
右下角时间轴:展示了项目的设计过程和时间节点,包括服务器端开发、前端页面设计、数据爬取和大屏设计等步骤,帮助用户了解该项目的开发过程和时间线。
左下角登陆情况:折线图展示了用户登录的时间分布情况,通过数据点和连线观察用户访问的高峰和低谷时段。
这个大屏将复杂的中药材和药方数据通过可视化方式展示出来,为用户提供了一目了然的中药材数据查询和分析服务,充分展现了中医药数据的多样性和丰富性。
3 实现图谱的后端代码
java需要去读取neo4j 数据库
//返回知识图谱数据,要组装成echarts的关系图支持的格式,前端是vue+echarts实现的
@GetMapping("/testkg")
public ServerResponse getKg(@RequestParam(defaultValue = "") String keyword) throws Exception {
String ql = "MATCH (n)-[r:`收录方剂`]->(x) " +
"WHERE n.name =~ '.*" + keyword + ".*' RETURN n, x, r LIMIT 100";
Result result = neo4jClientService.exec(ql);
// 定义 ECharts 格式的 nodes、links 和 categories 列表
List<Map<String, Object>> nodes = new ArrayList<>();
List<Map<String, Object>> links = new ArrayList<>();
Map<Long, Map<String, Object>> nodeCache = new HashMap<>(); // 节点缓存,避免重复添加
List<Map<String, Object>> categories = new ArrayList<>();
Map<String, Integer> categoryMap = new HashMap<>(); // 用于追踪已添加的类别
// 处理查询结果
while (result.hasNext()) {
Record record = result.next();
Node nodeStart = record.get("n").asNode();
Node nodeEnd = record.get("x").asNode();
Relationship relationship = record.get("r").asRelationship();
// 添加起始节点
if (!nodeCache.containsKey(nodeStart.id())) {
Map<String, Object> startNode = new HashMap<>();
startNode.put("id", nodeStart.id());
startNode.put("name", nodeStart.get("name").asString());
// 获取起始节点的类别并添加至 categories
String startCategory = nodeStart.labels().iterator().next();
startNode.put("category", getCategoryIndex(startCategory, categories, categoryMap));
nodes.add(startNode);
nodeCache.put(nodeStart.id(), startNode);
}
// 添加终止节点
if (!nodeCache.containsKey(nodeEnd.id())) {
Map<String, Object> endNode = new HashMap<>();
endNode.put("id", nodeEnd.id());
endNode.put("name", nodeEnd.get("name").asString());
// 获取终止节点的类别并添加至 categories
String endCategory = nodeEnd.labels().iterator().next();
endNode.put("category", getCategoryIndex(endCategory, categories, categoryMap));
nodes.add(endNode);
nodeCache.put(nodeEnd.id(), endNode);
}
// 添加关系
Map<String, Object> link = new HashMap<>();
link.put("source", String.valueOf(nodeStart.id()));
link.put("target", String.valueOf(nodeEnd.id()));
link.put("label", relationship.type());
links.add(link);
}
// 将结果组合成 ECharts 支持的格式
Map<String, Object> graphData = new HashMap<>();
graphData.put("nodes", nodes);
graphData.put("links", links);
graphData.put("categories", categories);
return ServerResponse.ofSuccess(graphData);
}