使用方法
- 每行写一条数据,用英文逗号分隔「名称」和「数值」,例如
搜索引擎,12480。默认示例 12 行,合计 41 445。 - 名称里不要写逗号。需要逗号时用中文顿号或书名号代替;名称本身留空会报「第 N 行名称为空」。
- 数值支持负数,负值条形从零轴向左画,这时零轴会自动移到轨道中间;全为正值时零轴贴左。
- 三个渲染选项:条尾标注数值、按数值降序排列、刻度轴用 nice number 取整。默认全勾。
- 点「生成条形图」或按 Ctrl+Enter(macOS 按 Cmd+Enter)。行数上限 60,超出会报错而不是截断。
这个条形图图表生成工具能解决什么
把一列「名称 + 数值」快速变成能贴进文档或幻灯片的对比图。渠道来源、Top N 排行、评分分布、库存数量——这类数据天然是「谁多谁少」的结构,横向条形比竖向柱状图更好读,因为中文标签不用旋转。条形图图表生成把这个过程压缩到「粘贴、生成、复制」三步。
检查数据里有没有被极值压扁的长尾。默认示例里最小的「爬虫/异常」只有 85,占最大项 12 480 的 0.68%,横向条形仍能画出约 1/147 的可见长度;换成饼图就会变成一个看不见的扇形。条形图对「量级差异」的表达力就在这里。
做帕累托分析。对照表给了累计占比一列,前 3 行累计 68.06%、前 5 行累计 85.05%,据此能判断「抓前三项够不够」这类问题。饼图做不到这件事,它的角度无法比较累计值。
做差值汇报。「本月 430 vs 上月 260」这类数据用条形图一眼能看出量级,用饼图只能看到两个扇形谁大。
本页只做横向条形 + 零基线这一种形态,不做饼图、环形图、折线图。需要占比构成请用饼图图表生成;需要层级结构用Org图表生成;需要自由拖拽画板用在线绘图看板。注意别把本页和条形码生成器搞混,那生成的是商品条码,与统计图无关。
原理与规则说明
条长计算是一行除法:宽度百分比 = 数值 / 最大值 * 100,其中最大值取全部数据的绝对值最大者(含负值时)。默认示例最大 12 480,「直接访问」9 310 得到 9310 / 12480 * 100 = 74.60%。分母用最大值而不是合计,是为了让最长条恰好占满轨道、最短条仍有可见长度。
零基线是硬约束,不是默认值。条形图靠长度编码数值,而人眼判断长度比例时依赖「从同一起点出发」这个前提。一旦把基线从 0 抬到 60,默认示例尾部三项立刻失真:无来源标记 430 与 爬虫/异常 85 的真实比是 5.06 : 1,截断后画成 (430-60) : (85-60) = 370 : 25,即 14.8 : 1,差距被放大 2.93 倍。实测把基线依次设成 0/10/20/30/40/50/60,放大倍数是 1.00 / 1.11 / 1.25 / 1.44 / 1.71 / 2.15 / 2.93 倍——基线超过 30 就已经突破 1.5 倍的可接受上限。
所以本页干脆不给「起始值」输入框。这还有一个工程理由:基线设错会算出负的条长(数值 85 配基线 100 得到 −15%),而 CSS 的 width 不接受负值,最终会渲染成 0 宽或反向条。少一个输入框就少一类必然出错的输入。
刻度上限走 nice number。函数取 最大值 / 4 作为步长基准,再按 1 / 2 / 2.5 / 5 / 10 这组比例向上取整。实测:12 480 得 20 000、9 310 得 10 000、2 130 得 4 000、430 得 800、85 得 100、1 900 000 得 2 000 000。之所以要 2.5 这一档而不用 1~9 整数,是因为 2.5 能让 2 500 / 5 000 / 7 500 / 10 000 这组刻度全部整除,刻度标签不出现小数。
千分位用 new Intl.NumberFormat('zh-CN') 构造一次后复用,而不是逐行调 toLocaleString()。后者不传 locale 时跟随浏览器环境,中文环境显示 12,480、部分欧洲环境显示 12.480;把 locale 固定住并缓存实例,60 行的结果就一致了。
不画 Canvas。整张图是 div 加 CSS 绝对定位的条形,width 用行内百分比。好处是条形可以选中文字、可以用 CSS 打印样式控制、屏幕阅读器能读到 role="img" 的 aria-label;代价是行数多了 DOM 节点也多,所以上限设 60 行。
完整示例(数值仅作演示)
默认示例 12 行、合计 41 445,实测各项:
- 搜索引擎 12 480:占比 30.11%,条长 100.00%(作为分母),累计 30.11%。
- 直接访问 9 310:占比 22.46%,条长 74.60%,累计 52.57%。
- 社交分享 6 420:占比 15.49%,条长 51.44%,累计 68.06%。前 3 行已过三分之二。
- 推荐网站 4 180:占比 10.09%,条长 33.49%,累计 78.15%。
- 邮件订阅 2 860:占比 6.90%,条长 22.92%,累计 85.05%。前 5 行累计 85.05%,典型的帕累托分布形状。
- 广告点击 2 130:占比 5.14%,条长 17.07%,累计 90.19%。
- 书签收藏 1 580:占比 3.81%,条长 12.66%,累计 94.00%。
- 二维码 990:占比 2.39%,条长 7.93%,累计 96.39%。
- 其它来源 720:占比 1.74%,条长 5.77%,累计 98.13%。
- 无来源标记 430:占比 1.04%,条长 3.45%,累计 99.17%。
- 内部跳转 260:占比 0.63%,条长 2.08%,累计 99.80%。
- 爬虫/异常 85:占比 0.21%,条长 0.68%,累计 100.00%。最小项仍可见。
把「按数值降序排列」关掉,条形按输入顺序排列但长度不变——长度与排序是两个独立维度,排序只影响阅读顺序。这个开关存在的意义是:数据本身有时间序(如按月)时,降序会破坏原有信息。
换成含负值的数据试试,比如 A,120、B,-45、C,0、D,-80、E,60:零轴移到轨道 50% 处,A 占右半边 50.00%、B 占左半边 28.13%、C 长度为 0、D 占左半边 50.00%、E 占右半边 25.00%。这时最长条不再是 100%,因为分母是绝对值最大者 120 而不是极差 200。
输入范围与对照表
| 设置项 | 可选范围 | 本页默认值 | 作用与限制 |
|---|---|---|---|
| 数据行数 | 2 ~ 60 | 12 | 少于 2 行画不出对比;上限 60 是 DOM 节点考虑 |
| 数值 | ±1012,支持负数与小数 | 整数演示值 | 绝对值为 0 即整列全 0,走提示分支 |
| 名称 | 1 ~ 12 个字符 | 如「搜索引擎」 | 超出 12 字截断加省略号,避免挤占轨道 |
| 分隔符 | 英文逗号,可多个 | 逗号 | 取第一个逗号前为名称,其余为数值 |
| 条尾标注 | 勾选 / 不勾选 | 勾选 | 在条形右侧显示带千分位的数值 |
| 降序排列 | 勾选 / 不勾选 | 勾选 | 只改阅读顺序,不改条长 |
| nice 刻度 | 勾选 / 不勾选 | 勾选 | 关掉则刻度上限直接取最大值 |
分隔符取「第一个逗号前为名称,其余为数值」而不是「最后一个逗号前」:名称里出现 搜索,引擎,12480 这样写会得到名称「搜索」、数值解析失败并报出具体行号。名称里需要逗号时用中文顿号 、。
数值对照表默认渲染 12 行,点「加载更多」每次加 12 行;「导出 CSV」写出全部行并带 UTF-8 BOM(EF BB BF 三字节),Excel 打开中文不乱码。注意这是 CSV 不是 JSON,加 BOM 是必须的。
输入范围、边界与精度说明
行数下限 2:1 行时条形占满 100% 轨道,看不出任何对比,页面会提示「至少需要 2 行数据才能形成对比」。上限 60:条高按行数在 32 / 24 / 18 / 12 px 之间自适应(1~8 行 32px、9~16 行 24px、17~30 行 18px、31~60 行 12px),低于 12px 时 10px 中文字会溢出,高于 32px 时 60 行要滚 1 920px。
数值上限设在 1012。超过 1e15 后 toFixed 与百分比会进入指数记数法——实测 (1e21).toFixed(2) 直接返回字符串 "1e+21",页面上会出现「数值 1e+21」这种没法读的展示。安全整数上限是 9007199254740991(253−1),超过会丢整数精度,本页上限远低于此值。
全为 0 的数据会走单独的提示分支,不做除法。分母为 0 时 数值 / 0 在 JavaScript 里得 Infinity 或 NaN,写进 width 会让 CSS 声明失效,条形根本不出现。页面会先判断「全部数值绝对值为 0」再决定走哪条路径。
toFixed 只用于展示列。V8 的 toFixed 在 .5 边界上直接进位(实测 (2.5).toFixed(0) 得 3、(3.5).toFixed(0) 得 4,不是银行家舍入),而且 (1.005).toFixed(2) 得 1.00,因为二进制浮点里 1.005 实际是 1.004999…。所以占比、条长全程用原始 double 计算,只在写进表格时格式化,不把格式化后的字符串再拿回来参与运算。
常见误用一:把条形图当饼图用,纠结「搜索引擎占 30.11%,为什么扇形看起来不到 30%」。条形比的是长度,饼图比的是角度,而人眼对角度的判读精度远低于长度。
常见误用二:看到最小项只有 0.68% 的条长就以为渲染坏了。它真的只有这么长——85 ÷ 12 480 = 0.6812%。如果希望小项也看得见,正确的做法是改用对数刻度或分两档展示,而不是把基线抬起来。
常见误用三:在名称里写英文逗号。这会让整行解析失败,页面会报出「第 N 行数值解析失败」并指出原文,方便定位。
常见问题
为什么不给「坐标轴起始值」输入框?
两个原因。一是正确性:条形靠长度编码数值,基线一旦离开 0,长度比例就不再等于数值比例。实测基线抬到 60 时,430 与 85 的真实比 5.06 : 1 会被画成 14.8 : 1,差距放大 2.93 倍。二是工程性:基线设错会算出负的条长(数值 85 配基线 100 得到 −15%),CSS 的 width 不接受负值,条形会消失或反着画。去掉这个输入框等于消灭一类错误输入。
最小的那条几乎看不见,有办法吗?
默认示例里最小项 85 占最大项的 0.68%,条长 0.68% 确实很短,这是数据本身的量级差。正确做法有三种:一是换成对数刻度(但那样条长就不代表比例了);二是把小项单独拆成一个图;三是接受这个事实——它本来就不重要,「爬虫/异常」占 0.21% 这个信息用数字看比用条形看更清楚。抬基线是最差的方案。
含负数的数据怎么显示?
零轴会自动移到轨道 50% 处,正值向右、负值向左。分母取绝对值最大者而不是极差,所以含负值时最长条不会是 100%。例如 A=120、B=−45、C=0、D=−80、E=60 这组,A 占右半 50.00%、B 占左半 28.13%、D 占左半 50.00%、E 占右半 25.00%,C 因为是 0 所以长度为 0,轨道里看不到条但标签在。
数值 0 和名称为空分别会怎样?
名称为空会报「第 N 行名称为空,请填写名称或删掉这一行」,不静默跳过。数值填 0 是合法的,表示这一项为 0,条长为 0、占比为 0.00%,会正常显示。全部数值都是 0 才会触发「全部数值为 0,无法计算条长」的提示,因为这时分母为 0。
为什么默认按降序排列,不能保留我的原始顺序吗?
可以,关掉「按数值降序排列」就按输入顺序显示。排序只影响阅读顺序,条长是按最大值算的,与顺序无关。默认勾上是因为多数场景下人们关心「谁最大」;但如果你的数据有时间序(按月、按天)或有分类序(按部门层级),降序会破坏这个信息,该关掉。
名称太长会怎样?
超过 12 个字符会被截断并加省略号,完整名称在悬停的 title 与导出 CSV 里仍完整保留。12 这个上限是为了让标签列不把轨道挤到 0 宽——标签列在桌面端固定 150px 宽,再长就会把条形压得看不出长度,那时长度编码就失效了。
刻度上限那个 20 000 是怎么算的,为什么不直接用 12 480?
走的是 nice number:先取 最大值 / 4 = 3120 作为步长基准,再按 1 / 2 / 2.5 / 5 / 10 这组比例向上取整,得到 5 × 1000 = 5 000,乘 4 等于 20 000。取整后刻度线落在 0 / 5 000 / 10 000 / 15 000 / 20 000,每个都是整数、标签不带小数。关掉「刻度轴用 nice number 取整」就直接用 12 480 做上限,刻度会变成 0 / 3 120 / 6 240 / 9 360 / 12 480,读起来累。
数据会被上传吗?
不会。解析用 String.prototype.split,计算用原生除法,渲染是纯 CSS 宽度,模板里没有任何 fetch 或 XMLHttpRequest。可以在开发者工具的 Network 面板确认:页面加载后除自身 CSS 外不再发出任何请求,刷新即清空输入内容。
相关工具
条形图图表生成只做「横向条形 + 零基线」这一种形态,下面这些页面覆盖其它图表类型与相关处理,选错了图形类型比画得不好看更误导人。