SVG绘图核心是数据映射、结构分组与交互逻辑:需倒置y轴坐标系,用viewBox实现响应式;柱状图用<g>分组+<rect>加data属性;折线图用<polyline>或<path>,配合事件委托与状态管理提升性能。

网页前端用 SVG 绘制复杂的折线图和柱状图,核心不是堆砌标签,而是理清数据映射、结构分组和交互逻辑。SVG 本质是可编程的矢量 DOM,画得准、动得稳、改得快,比“画出来就行”重要得多。
先统一坐标系和数据映射
SVG 原点在左上角,y 轴向下增长——这和数学习惯相反。绘图前必须做一次“倒置转换”:
- 设图表可用高度为 h(扣除顶部留白和底部轴距),数据最大值为 maxVal,某数据点值为 v,则它对应的 y 坐标 = topMargin + (maxVal − v) / maxVal × h
- 推荐用 viewBox="0 0 width height" 定义逻辑坐标系,再用 CSS 控制实际显示尺寸,实现真正响应式缩放
- 封装一个 scaleY(v) 函数,把原始数值转成 SVG 的 y 像素位置,后续所有图形都调用它,避免重复计算
柱状图:用 <rect> + 分组 + 语义属性
每根柱子不是一个孤立矩形,而是一个带上下文的数据载体:
- 用 <g class="bars"> 包裹全部柱子,方便整体位移、样式控制或事件委托
- 每个 <rect> 动态设置 x(按分类间距计算)、y(由 scaleY 得出)、width、height(注意 height = 可用高度 × v / maxVal)
- 务必添加自定义属性,如 data-value="72" data-category="6月",点击或悬停时直接读取,不用再查数组索引
- 数值标签用 <text> 放在柱子上方,y 值微调(比如 y = rect.y − 5),并设 dominant-baseline="middle" 确保垂直居中
折线图:<polyline> 或 <path> 配合数据点增强
折线不只是连起来的线,还要支持点选、提示、高亮联动:
立即学习“前端免费学习笔记(深入)”;
- 数据点坐标数组(如 [[10, 180], [50, 120], [90, 140]])转成字符串赋给 <polyline points="...">,简洁高效
- 若需点击某个点触发行为,就在对应位置加一个 <circle r="4" fill="#3498db" data-index="1">,绑定 click 事件后通过 event.target.dataset.index 获取上下文
- 想做平滑曲线或趋势拟合?换用 <path d="M10 180 C30 100, 70 100, 90 140">,C 指令支持贝塞尔插值
- 鼠标跟随提示(tooltip)不靠第三方库:监听 mousemove,用 getScreenCTM() 和 inverseTransformPoint() 把屏幕坐标转回逻辑坐标,再找最近数据点
交互与维护:用事件委托 + 状态管理
上百个柱子或点逐个绑事件会卡顿,也难维护:
- 给整个 <svg> 添加 click 监听器,用 event.target 判断是否为 rect 或 circle
- 高亮联动时,不要重绘整张图;用 CSS 类切换(如 .bar-active { fill: #e74c3c; })或临时修改 setAttribute("fill", ...)
- 把“数据 → 坐标 → 图形参数”三步拆开:先生成一个对象数组 [{x: 20, y: 80, width: 30, height: 120, label: "6月", value: 91}, ...],再批量创建元素——调试坐标、换主题、加动画都更可控


















