Svelte结合D3实现柱状图时svg下g元素transform变换异常问题
问题修复方案
错误点说明
- SVG的
translate变换不需要加px单位,加单位会导致浏览器解析异常,变换不生效。 <g>是SVG的纯分组容器,本身不支持width和height属性,设置这两个值没有任何作用,它的边界范围天生由内部子元素的总大小决定,无法手动固定,这是SVG规范定义的正常特性。- 柱子的x坐标计算有误:
d3.scaleBand()返回的x值本身就是每个柱子的左边缘坐标,额外加上xScale.bandwidth() / 2会让所有柱子整体右偏移半个带宽,最终超出容器边界,看起来就像<g>的位置不对。
修正后代码
<script> import * as d3 from 'd3'; let data = [ { name: 'Apple', amount: 20 }, { name: 'Orange', amount: 80 }, { name: 'Banana', amount: 50 }, { name: 'Grapes', amount: 10 }, ]; let width = 600; let height = 400; let margins = { top: 20, right: 20, bottom: 100, left: 100 }; let innerWidth = width - margins.left - margins.right; let innerHeight = height - margins.top - margins.bottom; const xScale = d3 .scaleBand() .domain(data.map((d) => d.name)) .range([0, innerWidth]) .paddingInner(0.1) .paddingOuter(0.1); const yScale = d3 .scaleLinear() .domain([0, d3.max(data, (d) => d.amount)]) .range([innerHeight, 0]); </script> <div class="canvas"> <svg {width} {height}> <g transform={`translate(${margins.left}, ${margins.top})`}> {#each data as d} <rect width={xScale.bandwidth()} height={innerHeight - yScale(d.amount)} x={xScale(d.name)} y={yScale(d.amount)} fill="#3385ff" /> {/each} </g> </svg> </div> <style> .canvas { margin-top: 100px; width: 600px; height: 400px; background-color: #fff; } </style>
内容的提问来源于stack exchange,提问作者BlackMath
相关产品推荐
相关产品推荐

