当青训营遇上码上掘金
我选择主题2:遇见。
将青训营的所有小伙伴们的绘制到了一张可视化知识图谱上,以小伙伴们之间的关注作为节点间的联系。
展示效果如下:
1. 数据来源
本文以关注过 青训营官方账号 的前 100 个用户集合作为研究对象,主要需要他们的用户名、头像等信息(这些都是公开的数据信息)。
1.1. 用户信息
获取某个掘金账户粉丝的 API 请求格式如下:
GET https://api.juejin.cn/user_api/v1/follow/followers?user_id=3386151545092589&cursor=20
user_id表示要获取哪个用户的粉丝。cursor是偏移,相当于页号的功能,接口一次返回最多 20 条数据,需要滚动翻页。3386151545092589是 青训营官方账号 的user_id。
获取到的数据格式如下:
{
"err_no": 0,
"err_msg": "success",
"data": {
"count": 8160,
"cursor": "40",
"data": [
{
"user_id": "xxxxxxxxxxxxxx",
"user_name": "xxx",
"avatar_large": "xxxxxxxx",
"level": 2,
"description": "",
"isfollowed": false,
// ...
},
// ...
],
"hasMore": true
}
}
爬取代码如下:
const sleep = (timeout) => {
return new Promise((resolve)=>{
setTimeout(()=>{
resolve();
}, timeout)
})
}
// fetch API 封装
const get = async function(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Net Error: ${response.status}`);
}
const jsonBody = await response.json();
return jsonBody;
}
for (let i = 0; i < 100; i+=20) {
const response = await get('https://api.juejin.cn/user_api/v1/follow/followers?user_id=3386151545092589&cursor=' + i)
const followers = response.data.data.map(follower => {
return {
user_id: follower.user_id,
user_name: follower.user_name,
avatar_large: follower.avatar_large,
}
})
save(followers)
// 休眠一会, 避免压垮服务器
await sleep(200);
}
1.2. 用户联系
我选取了用户与用户之间关注作为联系,关注关系是单向的。为了保护隐私演示代码不会取真实的关注数据,通过分区采样的方式来随机生成用户关注数据。
// 生成 [n,m] 的随机整数
function randomNum(minNum, maxNum){
return parseInt(Math.random()*(maxNum-minNum+1)+minNum,10);
}
var links = []
// 对区间 [min, max] 中的节点, 随机生成 times 次关系
function randomLinks1(min, max, times){
for (let i = 0; i < times; i++) {
links.push({
source: randomNum(min, max),
target: randomNum(min, max),
})
}
}
// 从区间 [min1, max2] 和 [min2, max2] 分别随机取一个节点连接关系, 生成 times 次
function randomLinks2(min1, max1, min2, max2, times){
for (let i = 0; i < times; i++) {
links.push({
source: randomNum(min1, max1),
target: randomNum(min2, max2),
})
}
}
randomLinks1(0, 9, 8)
randomLinks1(10, 29, 30)
randomLinks1(30, 79, 40)
randomLinks1(80, 99, 40)
randomLinks2(0, 9, 30, 79, 5)
randomLinks2(80, 99, 30, 79, 3)
randomLinks2(0, 9, 30, 79, 1)
randomLinks2(10, 29, 80, 99, 4)
2. 绘制可视化图谱
- 引入 Echars 库
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.1/echarts.min.js"></script>
- 设置力引导布局,节点之间使用斥力分开彼此
force: {
repulsion: 300,
edgeLength: 1200,
gravity: 0.5,
// layoutAnimation: false
},
- 设置选中节点或边时,高亮展示相关联的节点和边
emphasis: {
focus: 'adjacency',
lineStyle: {
width: 2,
color: 'red'
}
},
- 使用掘金小伙伴的头像作为节点的形状展示
var data = []
for (let i = 0; i < users.length; i++) {
data.push({
id: users[i].id,
name: users[i].name,
symbol: 'image://' + users[i].avatar,
})
}
3. 结语
制作这个好友关系可视化图谱,希望可以通过其为青训营的小伙伴们发现更多志同道合的朋友。大家一起学习、一起进步,祝大家都能在此处青训营中学习到知识、交到朋友。