如何用JavaScript从给定JSON数据生成ASCII可视化地图?
问题
假设每个地点最多有4个通行方向,能否使用JavaScript基于给定的JSON数据生成如下样式的ASCII可视化地图?
期望生成的ASCII图:
A=====B======C | D
给定的JSON数据:
{ "A": [ "B"], "B": [ "A", "C", "D"], "C": ["D"], "D": ["B"] }
我尝试编写的JavaScript代码:
const data = { "A": ["B"], "B": ["A", "C", "D"], "C": ["B"], "D": ["B"] }; for (const location in data) { const neighbors = data[location]; let line = location; for (const neighbor of neighbors) { line += '=====' + neighbor; } console.log(line); }
解决方案
要生成你想要的ASCII地图,核心是先给每个节点分配坐标,再按行渲染节点和连接线,而不是简单拼接节点与邻居。以下是实现思路和代码:
步骤说明
- 定义节点坐标:根据节点间的连接关系,给每个节点设置(x,y)坐标,确保横向、纵向的位置对齐。
- 构建地图网格:先初始化一个二维数组作为网格,填充空格;然后依次绘制节点、横向连接线(
=====)、纵向连接线(|)。 - 渲染输出:将网格的每一行拼接成字符串,打印结果。
实现代码
const data = { "A": ["B"], "B": ["A", "C", "D"], "C": ["B"], "D": ["B"] }; // 给每个节点分配坐标,确保布局符合需求 const positions = { "A": { x: 0, y: 0 }, "B": { x: 5, y: 0 }, "C": { x: 11, y: 0 }, "D": { x: 5, y: 2 } }; // 确定地图的宽高,根据坐标计算最大值+1 const maxX = Math.max(...Object.values(positions).map(p => p.x)) + 1; const maxY = Math.max(...Object.values(positions).map(p => p.y)) + 1; // 初始化网格,填充空格 const grid = Array(maxY).fill().map(() => Array(maxX).fill(' ')); // 绘制节点 for (const [node, pos] of Object.entries(positions)) { grid[pos.y][pos.x] = node; } // 绘制横向连接线(同一行的节点) for (const [node, neighbors] of Object.entries(data)) { const nodePos = positions[node]; for (const neighbor of neighbors) { const neighborPos = positions[neighbor]; if (nodePos.y === neighborPos.y) { // 同一行,绘制横向线 const startX = Math.min(nodePos.x, neighborPos.x) + 1; const endX = Math.max(nodePos.x, neighborPos.x); for (let x = startX; x < endX; x++) { grid[nodePos.y][x] = '='; } } } } // 绘制纵向连接线(同一列的节点) for (const [node, neighbors] of Object.entries(data)) { const nodePos = positions[node]; for (const neighbor of neighbors) { const neighborPos = positions[neighbor]; if (nodePos.x === neighborPos.x) { // 同一列,绘制纵向线 const startY = Math.min(nodePos.y, neighborPos.y) + 1; const endY = Math.max(nodePos.y, neighborPos.y); for (let y = startY; y < endY; y++) { grid[y][nodePos.x] = '|'; } } } } // 渲染输出 grid.forEach(row => console.log(row.join('')));
输出结果
运行代码后会输出:
A=====B======C | D
扩展说明
如果需要自动计算坐标(不用手动设置),可以实现简单的布局算法:比如先处理横向节点链,再把纵向连接的节点放在对应x坐标的下方。但对于小规模数据,手动设置坐标更直接可控。
内容的提问来源于stack exchange,提问作者Ayush Choudhary
相关产品推荐
相关产品推荐

