使用HTML/CSS或Python库绘制U位定位服务器机架图方案咨询
服务器机架图实现方案
针对按U位生成机架示意图的需求,可直接选用以下两类方案,均原生支持「设备名称-起始U位-结束U位」格式的输入数据。
方案1:Python 实现(适合批量出图、嵌入运维报表场景)
可选依赖库
drawsvg:轻量SVG生成库,样式自定义自由度高,无前端依赖,生成的矢量图可任意缩放不模糊matplotlib:熟悉矩形绘制API即可快速实现,适合需要配套生成运维统计图表的场景diagrams:运维架构图专用库,内置通用服务器、网络设备图标,可快速拼接符合行业规范的机架图
可直接运行的参考代码(基于drawsvg)
先安装依赖:pip install drawsvg
import drawsvg as draw # 基础尺寸配置:按比例缩放1U物理高度,可按需调整 U_HEIGHT = 20 RACK_WIDTH = 300 RACK_TOTAL_U = 42 # 标准42U机柜,可根据实际机柜高度修改 DEVICE_COLORS = ["#4285F4", "#EA4335", "#FBBC05", "#34A853", "#9C27B0"] # 输入设备数据,格式:(设备名称, 起始U位, 结束U位) devices = [ ("servers1", 15, 17), ("server2", 20, 25), ("firewall", 2, 4), ("NAS", 10, 15) ] # 初始化画布 d = draw.Drawing(RACK_WIDTH + 80, RACK_TOTAL_U * U_HEIGHT + 40, origin=(0,0)) # 绘制机架外框 d.append(draw.Rectangle(40, 20, RACK_WIDTH, RACK_TOTAL_U * U_HEIGHT, fill="#f0f0f0", stroke="#333", stroke_width=2)) # 绘制U位刻度线与编号 for u in range(1, RACK_TOTAL_U+1): y_pos = 20 + (RACK_TOTAL_U - u) * U_HEIGHT d.append(draw.Line(40, y_pos, 40+RACK_WIDTH, y_pos, stroke="#ccc", stroke_width=1)) d.append(draw.Text(str(u), 12, 20, y_pos + U_HEIGHT/2, text_anchor="middle", dominant_baseline="middle")) # 逐个绘制设备 for idx, (name, start_u, end_u) in enumerate(devices): dev_height = (end_u - start_u + 1) * U_HEIGHT dev_y = 20 + (RACK_TOTAL_U - end_u) * U_HEIGHT # 设备主体 d.append(draw.Rectangle(45, dev_y+2, RACK_WIDTH-10, dev_height-4, fill=DEVICE_COLORS[idx % len(DEVICE_COLORS)], stroke="#222", stroke_width=1, rx=2)) # 设备名称标签 d.append(draw.Text(name, 12, 40 + RACK_WIDTH/2, dev_y + dev_height/2, fill="white", text_anchor="middle", dominant_baseline="middle", font_weight="bold")) # 输出为SVG矢量图,也可调用rasterize方法导出PNG d.save_svg("rack_diagram.svg")
替换devices列表中的数据即可生成对应机架图,代码默认遵循行业U位计数规则。
方案2:纯HTML/CSS实现(适合前端嵌入、交互场景)
无需额外依赖,通过CSS绝对定位即可实现,可扩展hover显示详情、拖拽调整U位等交互能力。
参考代码
<!DOCTYPE html> <html> <head> <style> .rack { width: 320px; height: 840px; /* 对应42U机柜,单U高度20px,和Python方案尺寸对齐 */ border: 2px solid #333; background: #f0f0f0; position: relative; margin: 20px; } .u-scale { position: absolute; left: -30px; top: 0; height: 100%; width: 25px; } .u-mark { height: 20px; line-height: 20px; font-size: 12px; text-align: center; border-bottom: 1px solid #ccc; } .device { position: absolute; left: 5px; right: 5px; border-radius: 2px; border: 1px solid #222; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 14px; } /* 设备配色可按需扩展 */ .device.servers1 { background: #4285F4; } .device.server2 { background: #EA4335; } .device.firewall { background: #FBBC05; color: #333; } .device.NAS { background: #34A853; } </style> </head> <body> <div class="rack"> <!-- U位刻度,动态场景下可通过JS循环生成 --> <div class="u-scale"> <div class="u-mark">42</div><div class="u-mark">41</div><div class="u-mark">40</div> <div class="u-mark">39</div><div class="u-mark">38</div><div class="u-mark">37</div> <div class="u-mark">36</div><div class="u-mark">35</div><div class="u-mark">34</div> <div class="u-mark">33</div><div class="u-mark">32</div><div class="u-mark">31</div> <div class="u-mark">30</div><div class="u-mark">29</div><div class="u-mark">28</div> <div class="u-mark">27</div><div class="u-mark">26</div><div class="u-mark">25</div> <div class="u-mark">24</div><div class="u-mark">23</div><div class="u-mark">22</div> <div class="u-mark">21</div><div class="u-mark">20</div><div class="u-mark">19</div> <div class="u-mark">18</div><div class="u-mark">17</div><div class="u-mark">16</div> <div class="u-mark">15</div><div class="u-mark">14</div><div class="u-mark">13</div> <div class="u-mark">12</div><div class="u-mark">11</div><div class="u-mark">10</div> <div class="u-mark">9</div><div class="u-mark">8</div><div class="u-mark">7</div> <div class="u-mark">6</div><div class="u-mark">5</div><div class="u-mark">4</div> <div class="u-mark">3</div><div class="u-mark">2</div><div class="u-mark">1</div> </div> <!-- 设备定位规则:top = (机柜总U数 - 设备结束U位)*单U高度 + 2px间距,height = (结束U-起始U+1)*单U高度 - 4px间距 --> <div class="device servers1" style="top: calc((42 - 17)*20px + 2px); height: calc((17-15+1)*20px -4px);">servers1</div> <div class="device server2" style="top: calc((42 - 25)*20px + 2px); height: calc((25-20+1)*20px -4px);">server2</div> <div class="device firewall" style="top: calc((42 - 4)*20px + 2px); height: calc((4-2+1)*20px -4px);">firewall</div> <div class="device NAS" style="top: calc((42 - 15)*20px + 2px); height: calc((15-10+1)*20px -4px);">NAS</div> </div> </body> </html>
动态数据场景下,只需要遍历设备列表,按照注释里的定位规则生成DOM元素即可。
实现注意事项
- 行业默认U位计数规则为从机柜底部向上计数:1U在机柜最底部,最大U位在机柜顶部,上述代码的位置计算已遵循该规则,避免顺序颠倒
- 可增加U位冲突校验逻辑:遍历所有设备的U位区间,判断是否存在交集,提前提示设备排布重叠问题
- 代码中单U像素值为显示方便做了等比缩放,可根据实际展示需求调整尺寸比例,不影响U位对应关系
内容的提问来源于stack exchange,提问作者Abdellah ALAOUI ISMAILI
相关产品推荐
相关产品推荐

