d3 getting invert value of Band Scales

核能气质少年 提交于 2019-11-30 19:50:05

Solved this as below but i don't know this is standard way, if any other way please answer to this.

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

eachBand gives the size of the band in pixels if i divide the y value (drag event) by the eachBand i will get the index which gives the yScale value

When the graph has padding on the left and right the answers give undefined as result if the value is outside the bars of the graph. The following function can be used to take this padding into consideration and clamp the index to the valid values of the 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))];
  }
}

It can be used as follows:

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
Matthew Cox

One tweak to the accepted answer - you may want to use Math.floor rather than Math.round as the former will return the next level lower if you happen to select below the center point of the item. Modified solution is thus:

var eachBand = self.yScale.step();
var index = Math.floor((d3.event.y / eachBand));
var val = self.yScale.domain()[index];
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!