2016-07-28 8 views
2

я пишу диаграммы Ганта с использованием d3d3 получает значение инвертный зонных Весы

я имею XScale с Time Scale (Время)

this.xScale = d3.scaleTime() 
      .domain([this.startDate,this.endDate]) 
      .range([0,this.getWidth()]); 

и yScale как группа Scale (Ресурсы)

this.yScale = d3.scaleBand() 
     .domain(resources.map(function(res){ 
      return res.res_num; 
     })) 
     .rangeRound([0,this.getHeight()]) 
     .paddingInner(.3) 

Проблема в том, что мне нужно перетащить задачу (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] + ")"); 
    }, 

Но капли я должен справиться с логикой, как показано ниже:

  1. Прямоугольник не должно быть между ресурсами, поэтому необходимо преобразуется в любую полосу на основе d3.event.y
    1. в xAxis масштаб времени, который имеет инвертированный, но yScale не имеет этого. Как это сделать?

ответ

9

решаемые это, как показано ниже, но я не знаю, что это стандартный способ, если любой другой способ, пожалуйста, ответьте на это.

var eachBand = self.yScale.step(); 
var index = Math.round((d3.event.y/eachBand)); 
var val = self.yScale.domain()[index]; 

eachBand дает размер полосы в пикселях , если я разделить значение у (перетаскивание события) на eachBand я получит индекс, который дает значение yScale

1

один твик к принятый ответ - вы можете использовать Math.floor, а не Math.round, так как первые вернут следующий уровень ниже, если вам захочется выбрать под центральной точкой элемента. Модифицированный раствор таким образом:

var eachBand = self.yScale.step(); 
var index = Math.round((d3.event.y/eachBand)); 
var val = self.yScale.domain()[index];