知识谱系图表(Knowledge Graph)在 Highcharts 中使用力导向网络图(networkgraph) ,专门用来可视化演化谱系树 。核心特点是:根节点统一、子分支同色、自动布局,完美呈现语言从原始母语分化到现代语言的过程。

一份完整可直接运行的 HTML 代码 ,包含了印欧语系语言树 的所有配置、依赖和样式。你只需复制保存为 .html 文件,双击打开浏览器就能看到图表。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Indo-European Language Tree</title>
<!-- 引入 Highcharts 核心库 -->
<script src="https://code.highcharts.com/highcharts.js"></script>
<!-- 引入网络图模块 -->
<script src="https://code.highcharts.com/modules/networkgraph.js"></script>
<!-- 引入无障碍模块(可选) -->
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<style>
/* 让图表占满屏幕 */
html, body, #container {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<!-- 图表容器 -->
<div id="container"></div>
<script>
// 节点颜色自动配置逻辑
Highcharts.addEvent(
Highcharts.Series,
'afterSetOptions',
function (e) {
const colors = Highcharts.getOptions().colors,
nodes = {};
let i = 0;
if (
this instanceof Highcharts.Series.types.networkgraph &&
e.options.id === 'lang-tree'
) {
e.options.data.forEach(function (link) {
if (link[0] === 'Proto Indo-European') {
nodes['Proto Indo-European'] = {
id: 'Proto Indo-European',
marker: { radius: 20 }
};
nodes[link[1]] = {
id: link[1],
marker: { radius: 10 },
color: colors[i++]
};
} else if (nodes[link[0]] && nodes[link[0]].color) {
nodes[link[1]] = {
id: link[1],
color: nodes[link[0]].color
};
}
});
e.options.nodes = Object.keys(nodes).map(function (id) {
return nodes[id];
});
}
}
);
// 渲染图表
Highcharts.chart('container', {
chart: {
type: 'networkgraph',
height: '100%'
},
title: {
text: 'The Indo-European Language Tree',
align: 'left'
},
subtitle: {
text: 'A Force-Directed Network Graph in Highcharts',
align: 'left'
},
plotOptions: {
networkgraph: {
keys: ['from', 'to'],
layoutAlgorithm: {
maxIterations: 72,
enableSimulation: true,
friction: -0.9,
gravitationalConstant:
document.getElementById('container').scrollWidth < 500 ? 0.2 : 0.06
}
}
},
series: [{
accessibility: { enabled: false },
dataLabels: {
enabled: true,
linkFormat: '',
style: {
fontSize: '0.8em',
fontWeight: 'normal'
}
},
id: 'lang-tree',
data: [
['Proto Indo-European', 'Balto-Slavic'],
['Proto Indo-European', 'Germanic'],
['Proto Indo-European', 'Celtic'],
['Proto Indo-European', 'Italic'],
['Proto Indo-European', 'Hellenic'],
['Proto Indo-European', 'Anatolian'],
['Proto Indo-European', 'Indo-Iranian'],
['Proto Indo-European', 'Tocharian'],
['Indo-Iranian', 'Dardic'],
['Indo-Iranian', 'Indic'],
['Indo-Iranian', 'Iranian'],
['Iranian', 'Old Persian'],
['Old Persian', 'Middle Persian'],
['Indic', 'Sanskrit'],
['Italic', 'Osco-Umbrian'],
['Italic', 'Latino-Faliscan'],
['Latino-Faliscan', 'Latin'],
['Celtic', 'Brythonic'],
['Celtic', 'Goidelic'],
['Germanic', 'North Germanic'],
['Germanic', 'West Germanic'],
['Germanic', 'East Germanic'],
['North Germanic', 'Old Norse'],
['North Germanic', 'Old Swedish'],
['North Germanic', 'Old Danish'],
['West Germanic', 'Old English'],
['West Germanic', 'Old Frisian'],
['West Germanic', 'Old Dutch'],
['West Germanic', 'Old Low German'],
['West Germanic', 'Old High German'],
['Old Norse', 'Old Icelandic'],
['Old Norse', 'Old Norwegian'],
['Old Norwegian', 'Middle Norwegian'],
['Old Swedish', 'Middle Swedish'],
['Old Danish', 'Middle Danish'],
['Old English', 'Middle English'],
['Old Dutch', 'Middle Dutch'],
['Old Low German', 'Middle Low German'],
['Old High German', 'Middle High German'],
['Balto-Slavic', 'Baltic'],
['Balto-Slavic', 'Slavic'],
['Slavic', 'East Slavic'],
['Slavic', 'West Slavic'],
['Slavic', 'South Slavic'],
['Proto Indo-European', 'Phrygian'],
['Proto Indo-European', 'Armenian'],
['Proto Indo-European', 'Albanian'],
['Proto Indo-European', 'Thracian'],
['Tocharian', 'Tocharian A'],
['Tocharian', 'Tocharian B'],
['Anatolian', 'Hittite'],
['Anatolian', 'Palaic'],
['Anatolian', 'Luwic'],
['Anatolian', 'Lydian'],
['Iranian', 'Balochi'],
['Iranian', 'Kurdish'],
['Iranian', 'Pashto'],
['Iranian', 'Sogdian'],
['Old Persian', 'Pahlavi'],
['Middle Persian', 'Persian'],
['Hellenic', 'Greek'],
['Dardic', 'Dard'],
['Sanskrit', 'Sindhi'],
['Sanskrit', 'Romani'],
['Sanskrit', 'Urdu'],
['Sanskrit', 'Hindi'],
['Sanskrit', 'Bihari'],
['Sanskrit', 'Assamese'],
['Sanskrit', 'Bengali'],
['Sanskrit', 'Marathi'],
['Sanskrit', 'Gujarati'],
['Sanskrit', 'Punjabi'],
['Sanskrit', 'Sinhalese'],
['Osco-Umbrian', 'Umbrian'],
['Osco-Umbrian', 'Oscan'],
['Latino-Faliscan', 'Faliscan'],
['Latin', 'Portugese'],
['Latin', 'Spanish'],
['Latin', 'French'],
['Latin', 'Romanian'],
['Latin', 'Italian'],
['Latin', 'Catalan'],
['Latin', 'Franco-Provençal'],
['Latin', 'Rhaeto-Romance'],
['Brythonic', 'Welsh'],
['Brythonic', 'Breton'],
['Brythonic', 'Cornish'],
['Brythonic', 'Cuymbric'],
['Goidelic', 'Modern Irish'],
['Goidelic', 'Scottish Gaelic'],
['Goidelic', 'Manx'],
['East Germanic', 'Gothic'],
['Middle Low German', 'Low German'],
['Middle High German', '(High) German'],
['Middle High German', 'Yiddish'],
['Middle English', 'English'],
['Middle Dutch', 'Hollandic'],
['Middle Dutch', 'Flemish'],
['Middle Dutch', 'Dutch'],
['Middle Dutch', 'Limburgish'],
['Middle Dutch', 'Brabantian'],
['Middle Dutch', 'Rhinelandic'],
['Old Frisian', 'Frisian'],
['Middle Danish', 'Danish'],
['Middle Swedish', 'Swedish'],
['Middle Norwegian', 'Norwegian'],
['Old Norse', 'Faroese'],
['Old Icelandic', 'Icelandic'],
['Baltic', 'Old Prussian'],
['Baltic', 'Lithuanian'],
['Baltic', 'Latvian'],
['West Slavic', 'Polish'],
['West Slavic', 'Slovak'],
['West Slavic', 'Czech'],
['West Slavic', 'Wendish'],
['East Slavic', 'Bulgarian'],
['East Slavic', 'Old Church Slavonic'],
['East Slavic', 'Macedonian'],
['East Slavic', 'Serbo-Croatian'],
['East Slavic', 'Slovene'],
['South Slavic', 'Russian'],
['South Slavic', 'Ukrainian'],
['South Slavic', 'Belarusian'],
['South Slavic', 'Rusyn']
]
}]
});
</script>
</body>
</html>
知识谱系图表整体功能
- 展示目标 :印欧语系从原始印欧语一步步分化为各大语族、再到古代 / 现代语言的演化关系
- 图表类型 :力导向网络图(节点 + 连线,自动物理布局)
- 视觉规则 :
- 根节点(原始印欧语)最大
- 每个一级子语族用独立颜色
- 同一语族的所有后代节点继承父节点颜色
- 交互:节点自动散开、自适应屏幕大小
核心逻辑(最重要)
这段代码最厉害的地方是自动给语言树上色:
- 原始印欧语 = 根节点(最大)
- 它的直接子节点(日耳曼语族、斯拉夫语族、意大利语族等)= 各用一个颜色
- 所有孙节点、曾孙节点(后代语言)= 继承父语族的颜色
- 最终形成:一个语族 = 一种颜色 的清晰谱系树
代码逐段解析
1. 事件监听:自动给节点上色 + 设置大小(核心)
javascript
javascript
Highcharts.addEvent(Highcharts.Series, 'afterSetOptions', function (e) {
const colors = Highcharts.getOptions().colors;
const nodes = {};
let i = 0;
// 只对 id="lang-tree" 的网络图生效
if (this instanceof Highcharts.Series.types.networkgraph && e.options.id === 'lang-tree') {
// 遍历所有连线数据
e.options.data.forEach(function (link) {
// 1. 根节点:原始印欧语
if (link[0] === 'Proto Indo-European') {
nodes['Proto Indo-European'] = { id: 'Proto Indo-European', marker: { radius: 20 } };
// 2. 一级子节点:分配独立颜色 + 小一点的尺寸
nodes[link[1]] = {
id: link[1],
marker: { radius: 10 },
color: colors[i++]
};
}
// 3. 孙/曾孙节点:继承父节点颜色
else if (nodes[link[0]] && nodes[link[0]].color) {
nodes[link[1]] = { id: link[1], color: nodes[link[0]].color };
}
});
// 把节点配置注入图表
e.options.nodes = Object.keys(nodes).map(id => nodes[id]);
}
});
作用总结:
- 自动识别父子关系
- 自动分配颜色
- 自动继承颜色
- 自动设置节点大小
- 完全不用手动给每个语言写样式
2. 图表基础配置
javascript
javascript
chart: {
type: 'networkgraph', // 力导向网络图
height: '100%' // 占满容器高度
}
3. 布局算法(物理自动排版)
javascript
javascript
layoutAlgorithm: {
maxIterations: 72, // 布局计算次数
enableSimulation: true, // 开启物理模拟
friction: -0.9, // 摩擦系数(控制散开力度)
gravitationalConstant: 屏幕<500? 0.2 : 0.06 // 手机/电脑自适应引力
}
- 让节点自动散开不重叠
- 手机上更紧凑,电脑上更舒展
- 这是网络图 "好看不乱" 的关键
4. 数据格式(连线关系)
javascript
javascript
keys: ['from', 'to']
data: [
['原始印欧语', '日耳曼语族'],
['日耳曼语族', '北日耳曼语支'],
['北日耳曼语支', '古诺尔斯语'],
...
]
- 每一行 = 一条父子连线
- 整个数据就是完整的语言演化树
图表视觉效果规则
| 节点类型 | 大小 | 颜色 | 示例 |
|---|---|---|---|
| 根节点 | 最大(radius=20) | 默认 | 原始印欧语 |
| 一级语族 | 中(radius=10) | 独立配色 | 日耳曼、斯拉夫、凯尔特、意大利、伊朗... |
| 后代语言 | 小 | 继承父语族 | 英语、德语、法语、西班牙语、俄语、印地语 |
类似适用的场景
- 历史文化谱系展示
- 家族树、组织架构、分类树可视化
- 向量知识图谱、演化关系图