Javascript D3更新x坐标元素

Javascript D3更新x坐标元素,javascript,d3.js,Javascript,D3.js,给定一个具有域[0,1]和范围[0,窗口宽度]的线性比例,我想渲染ticksNumber=5等间距的垂直线 因此,我创建了数组ticksValues,其中包含作为width*ticksValues[I]计算的线x坐标 然后,我通过索引将该数组与DOM元素行绑定。我想要的是5行(或6行,取决于d3)在整个范围内等距排列,因为这取决于窗口的宽度 我的代码不起作用,为什么?似乎数据绑定不正确 const ticksNumber=5 addEventListener('resize',getWindo

给定一个具有域
[0,1]
和范围
[0,窗口宽度]
的线性比例,我想渲染
ticksNumber=5
等间距的垂直线

因此,我创建了数组
ticksValues
,其中包含作为
width*ticksValues[I]
计算的线
x
坐标

然后,我通过索引将该数组与DOM元素行绑定。我想要的是5行(或6行,取决于d3)在整个范围内等距排列,因为这取决于窗口的宽度

我的代码不起作用,为什么?似乎数据绑定不正确

const ticksNumber=5
addEventListener('resize',getWindowsSize)
函数getWindowsSize(){
var width=window.innerWidth
var height=window.innerHeight
常量xScale=d3.scaleLinear()
.domain([0,1])
.范围([0,宽度])
常量ticksValues=xScale.ticks(ticksNumber.map)(d=>d*width)
常量svg=d3。选择(“#svg”)
const grid=svg.append('g')
网格
.selectAll('行')
.数据(勾选值,(d,i)=>i)
.输入()
.append('行')
.attr('x1',d=>d)
.attr('x2',d=>d)
.attr('y1',0)
.attr('y2',高度)
.attr('笔划','红色')
}

一个问题是,行的位置是根据窗口的宽度定义的,但SVG的宽度没有设置。为SVG定义一个显式的
100%
width属性,以便显示所有行

<svg id="svg" width="100%"></svg>
展示了d3中关于利润的良好实践

用来计算直线位置的公式似乎是正确的。然而,没有必要为这些细节费心,因为
d3量表
为我们做了这些

let dataset = d3.range(ticksNumber) // [0, 1, 2, 3, 4]

xScale.domain(d3.extent(dataset))

// ... 

selection.append('line')
  .attr('x1', d => xScale(d))
  // ...
下面的代码片段演示了这组修复程序

示例代码中的其他问题,在本演示中未解决

  • 每次调整窗口大小时,都会在现有网格上添加一个新的线网格。相反,应在页面加载时绘制一次条形图。然后在调整大小时,应移动其
    x
    位置
  • 性能:窗口大小调整事件侦听器应取消公告
const ticksNumber=5
,差额=50
,dataset=d3.range(滴答数)
getWindowsSize()
函数getWindowsSize(){
变量宽度=window.innerWidth-边距
var height=window.innerHeight
常量xScale=d3.scaleLinear()
.域(d3.范围(数据集))
.范围([0,宽度])
常量svg=d3。选择(“#svg”)
const grid=svg.append('g')
网格
.selectAll('行')
.数据(数据集)
.输入()
.append('行')
.attr('x1',d=>xScale(d))
.attr('x2',d=>xScale(d))
.attr('y1',0)
.attr('y2',高度)
.attr('笔划','红色')
}

我把它修好了。缺少合并选择

const grid = svg.append('g');
const update = grid.selectAll("line").data(ticksValues);
update.enter()
  .append("line")
  .merge(update)
  .attr("x1", d => this.xScale(d))
  .attr("x2", d => this.xScale(d))
  .attr("y1", 0)
  .attr("y2", height);

一个问题是,每次发生调整大小事件时,都会在现有网格的上方添加一个新网格。
d*width
可能不会产生记号位置的预期结果,因为它会将大多数记号定位在视口之外。与其自己计算坐标,不如让
d3.scale
为您计算。您应该查找关于
去Bouncing
事件,以避免一直重新计算和重新显示网格。@Mehdi关于
去Bouncing
和网格复制,您是对的,上面的示例只是一个简单的例子。但是数据绑定有什么问题呢?谢谢,但是当窗口调整大小时,您的行不会改变位置,谢谢@Mehdi,我不知道
range()
函数,非常有用!是的,演示仅显示如何修复“未显示的行”问题。
const grid = svg.append('g');
const update = grid.selectAll("line").data(ticksValues);
update.enter()
  .append("line")
  .merge(update)
  .attr("x1", d => this.xScale(d))
  .attr("x2", d => this.xScale(d))
  .attr("y1", 0)
  .attr("y2", height);