chi*_*igk 9 javascript svg transform scaletransform d3.js
我正在使用d3编写甘特图
我有带时间刻度的xScale(时间)
this.xScale = d3.scaleTime()
.domain([this.startDate,this.endDate])
.range([0,this.getWidth()]);
Run Code Online (Sandbox Code Playgroud)
和yScale作为Band Scale(资源)
this.yScale = d3.scaleBand()
.domain(resources.map(function(res){
return res.res_num;
}))
.rangeRound([0,this.getHeight()])
.paddingInner(.3)
Run Code Online (Sandbox Code Playgroud)
问题是我需要将任务(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).raise().attr("transform","translate(" + [x,y] + ")");
},
Run Code Online (Sandbox Code Playgroud)
但是在下降时我必须处理如下逻辑:
chi*_*igk 17
解决了这个如下,但我不知道这是标准的方式,如果有任何其他方式请回答这个问题.
var eachBand = self.yScale.step();
var index = Math.round((d3.event.y / eachBand));
var val = self.yScale.domain()[index];
Run Code Online (Sandbox Code Playgroud)
如果我将y值(拖动事件)除以eachBand,则eachBand给出带的大小(以像素为单位)i将获得给出yScale值的索引
对已接受答案的一个调整 - 您可能想要使用Math.floor而不是Math.round因为如果您碰巧在项目的中心点下方选择,前者会返回较低的下一个级别。修改后的解决方案是:
var eachBand = self.yScale.step();
var index = Math.floor((d3.event.y / eachBand));
var val = self.yScale.domain()[index];
Run Code Online (Sandbox Code Playgroud)
当图形左右有填充时,undefined如果值超出图形的条形,则给出答案。可以使用以下函数来考虑此填充,并将索引限制为的有效值domain。
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))];
}
}
Run Code Online (Sandbox Code Playgroud)
可以如下使用:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3398 次 |
| 最近记录: |