Javascript d3获取波段刻度的反转值
我正在用d3写甘特图 我有带时间刻度的xScale(时间) 和yScale作为频带标度(参考资料) 问题是我需要将任务(SVG Rect)从一个资源拖放到另一个资源 当我拖动时,我正在使用transfrom,以便它在SVG上移动Javascript d3获取波段刻度的反转值,javascript,d3.js,svg,transform,scaletransform,Javascript,D3.js,Svg,Transform,Scaletransform,我正在用d3写甘特图 我有带时间刻度的xScale(时间) 和yScale作为频带标度(参考资料) 问题是我需要将任务(SVG Rect)从一个资源拖放到另一个资源 当我拖动时,我正在使用transfrom,以便它在SVG上移动 _onDrag : function(d) { var x = d3.event.dx+d3.event.x; var y = d3.event.dy+d3.event.y; d3.select(this).rai
_onDrag : function(d)
{
var x = d3.event.dx+d3.event.x;
var y = d3.event.dy+d3.event.y;
d3.select(this).raise().attr("transform","translate(" + [x,y] + ")");
},
但在降落时,我必须按照以下逻辑处理:
解决这个问题如下,但我不知道这是标准的方式,如果有任何其他方式,请回答这个问题
var eachBand = self.yScale.step();
var index = Math.round((d3.event.y / eachBand));
var val = self.yScale.domain()[index];
每个波段以像素为单位给出波段的大小
如果我将y值(拖动事件)除以EACH,我将得到一个索引,该索引将给出yScale值一个可接受的答案-您可能希望使用
Math.floor
而不是Math.round
,因为如果您恰好选择项目中心点下方,前者将返回下一个级别。因此,改进的解决方案是:
var eachBand = self.yScale.step();
var index = Math.floor((d3.event.y / eachBand));
var val = self.yScale.domain()[index];
当图表的左右两侧都有填充时,如果值在图表的条形图之外,则答案会给出
未定义的
。以下函数可用于考虑此填充,并将索引钳制为域的有效值
function scaleBandInvert(scale) {
var domain = scale.domain();
var paddingOuter = scale(domain[0]);
var eachBand = scale.step();
return function (value) {
var index = Math.floor(((value - paddingOuter) / eachBand));
return domain[Math.max(0,Math.min(index, domain.length-1))];
}
}
它可以按如下方式使用:
var xScale = d3.scaleBand().domain(...).rangeRound([a,b]);
....
var dvalX = scaleBandInvert(xScale)(value); // single invert
....
var dRangeX = d3.event.selection.map(scaleBandInvert(xScale)); // in a brush event handler
感谢您:var paddingOuter=scale(域[0])
我发现为了让对分在条之间切换,我必须使用Math.round
和paddingner
:var paddingner=scale.step()*scale.paddingner()代码>然后var index=Math.round((x-scaleStart-paddingner/2)/eachBand)代码>
function scaleBandInvert(scale) {
var domain = scale.domain();
var paddingOuter = scale(domain[0]);
var eachBand = scale.step();
return function (value) {
var index = Math.floor(((value - paddingOuter) / eachBand));
return domain[Math.max(0,Math.min(index, domain.length-1))];
}
}
var xScale = d3.scaleBand().domain(...).rangeRound([a,b]);
....
var dvalX = scaleBandInvert(xScale)(value); // single invert
....
var dRangeX = d3.event.selection.map(scaleBandInvert(xScale)); // in a brush event handler