为什么我们不用 ECharts/Chart.js 也能出图
一开始我也想直接引一个图表库:ECharts 好看、交互多。但我们的场景是作战中心大屏 + 每日进度条 + 给客户截图发的周报,要的是"一个文件发过去就能看、能嵌进静态站、手机能打开"。引框架意味着要让对方也加载几十 KB 的 JS,还常有版本兼容问题。后来我们干脆用纯内联 SVG + CSS 自己画,单个 HTML 文件零依赖,打开即出图。
经验 看板不是"越炫越好",是"对方一眼看懂、你能三秒改数"。静态站 + 截图分享的场景里,框架反而是负担。
进度条:用一段 SVG 搞定
最常见的是"目标完成度"。不用 Canvas、不用库,一段 <svg> 加两个 <rect> 就够:底色灰条 + 前景色条,宽度用百分比算好写死即可。
- 底色
<rect>满宽,填充浅灰;前景色<rect>宽度 = 完成率 × 总宽。 - 把数字用
<text>标在条尾,例如72%,比纯色块更直白。 - 颜色随状态变:正常红(品牌色)、达标绿、告急加深红——规则写死在代码里改一处即可。
跑通 作战中心的"今日获客 / 本月目标"进度条就这么做,每天改一个数值重新渲染,截图发企业微信,全程零依赖、零加载失败。
排名/对比:横向条形图
渠道排名、客户贡献 Top 榜,本质是横向条形。技巧是以最大项为基准宽度,其余按比例缩放,这样最短的条也不会看不见。
- 每项左对齐标签,右边跟条;条长按
值 / 最大值比例给宽度。 - 标签用
font-size小一点、右对齐,避免和条重叠。 - 想要"今天 vs 昨天"的对比,就并排画两条、用不同透明度区分。
踩坑 曾直接把所有条宽度写死像素,结果某天最大值暴涨,其他条全挤成细线看不清。改成"除以当日最大值"后,相对关系永远清楚。
手机适配:viewBox 是关键
SVG 最香的一点是有 viewBox。设好 viewBox="0 0 680 400",外层 CSS 给 width:100%,它就在桌面和手机上都自动缩放、不变形。千万别写死像素宽高,否则手机上要么溢出要么缩成一团。
可嵌站、可截图、可当组件
因为是纯 HTML 片段,三种用法都顺:
- 截图发:浏览器打开直接截,发企微/客户群,对方不用点链接。
- 嵌进静态站:把
<svg>那段直接贴进页面,天然随站上线,没有 404 风险。 - 当组件复用:把"画一条进度条"封装成一个小函数,传入数值和标签,批量生成一排看板。
提醒 别为了"好看"去引 D3、ECharts。它们适合复杂交互仪表盘;我们的需求是"看数 + 分享",纯 SVG 足够,且永远不会出现"对方打不开"的尴尬。
诚实的边界
这套做法不万能:需要鼠标悬停看明细、需要下钻、需要实时拉数据的,还是得上框架或后端。但在"每日/每周固定看板 + 静态站 + 截图汇报"这条主线上,零依赖 SVG 是我们性价比最高的选择——改数即用、人人能开、永不掉链子。