倒数与序数规模

时间:2013-12-24 09:36:11

标签: d3.js

有没有办法找到序数量表的倒置?

我在x轴上使用字符串值,这是使用序数比例而我在鼠标移动时我想找到x轴反转以找到鼠标位置的哪个字符串?

有没有办法找到这个?

var barLabels = dataset.map(function(datum) {
    return datum.image;
});
console.log(barLabels);
var imageScale = d3.scale.ordinal()
        .domain(barLabels)
        .rangeRoundBands([0, w], 0.1);
// divides bands equally among total width, with 10% spacing.
console.log("imageScale....................");
console.log(imageScale.domain());

 .
 .
var xPos = d3.mouse(this)[0];
xScale.invert(xPos);

8 个答案:

答案 0 :(得分:25)

我实际上认为不是序数标度的反转方法没有意义,但你可以使用ordinal.range()方法来解决它,它会给你返回每个条的起始值,以及ordinal.rangeBand()方法的宽度。

此处示例: http://fiddle.jshell.net/dMpbh/2/

相关代码是

    .on("click", function(d,i) {
        var xPos = d3.mouse(this)[0];
        console.log("Clicked at " + xPos);
        //console.log(imageScale.invert(xPos));
        var leftEdges = imageScale.range();
        var width = imageScale.rangeBand();
        var j;
        for(j=0; xPos > (leftEdges[j] + width); j++) {}
            //do nothing, just increment j until case fails
        console.log("Clicked on " + imageScale.domain()[j]);
    });

答案 1 :(得分:17)

我在parseInt拒绝了拉取请求中找到了较短的实施here,该请求完美无缺。

var ypos = domain[d3.bisect(range, xpos) - 1];

其中domain和range是scale domain和range:

var domain = x.domain(),
    range = x.range();

答案 2 :(得分:3)

我过去曾在需要时改变了域名和范围

> var a = d3.scale.linear().domain([0,100]).range([0, w]);
> var b = d3.scale.linear().domain([0,w]).range([0, 100]);

> b(a(5));
5

然而,有了序数,答案并不那么简单。我检查了文档和&代码,它似乎并不是一个简单的方法。我首先从域中映射项目并计算起点和终点。这是一个开始。

imageScale.domain().map(function(d){
    return {
        'item':d,
        'start':imageScale(d)
    };
})

考虑将问题作为功能请求发布在https://github.com/mbostock/d3/issues?state=open以防

  1. 对此类功能有足够的需求
  2. 我没有忽略任何内容,或者文档下面隐藏的内容会对本案有所帮助

答案 3 :(得分:1)

我最近发现自己和OP一样。

我需要获得滑块的分类比例的倒数。滑块有3个离散值,外观和行为类似于三向切换开关。它改变了某些SVG元素的混合模式。 我使用scaleQuantize()创建了一个反比例,如下所示:

var modeArray = ["normal", "multiply", "screen"];
var modeScale = d3.scalePoint()
  .domain(modeArray)
  .range([0, 120]);
var inverseModeScale = d3.scaleQuantize()
  .domain(modeScale.range())
  .range(modeScale.domain());

我在拖动时将此inverseModeScale鼠标x位置(d3.mouse(this)[0])提供:

.call( d3.drag()
    .on("start.interrupt", function() { modeSlider.interrupt(); })
    .on("start drag", function() { inverseModeScale(d3.mouse(this)[0]); })
)

它返回最接近鼠标x位置的modeArray元素。即使该值超出范围(-400或940),它也会返回正确的元素。

答案可能看起来有些特定于滑块,但无论如何都要发布,因为它有效(我认为)并且这个问题在" d3反转序数"在Google上。

注意:此答案使用d3 v4。

答案 4 :(得分:0)

我理解为什么Mike Bostock可能不愿意将invert包括在序数尺度上,因为你无法返回一个单一的真值。但是,这是我的版本。
该函数采用一个位置并返回周围的基准面。也许我稍后会跟进二进制搜索版本: - )

function ordinalInvert(pos, scale) {
    var previous = null
    var domain = scale.domain()
    for(idx in domain) {
        if(scale(datum[idx]) > pos) {
            return [previous, datum[idx]];
        }
        previous = datum[idx];
    }
    return [previous, null];
}

答案 5 :(得分:0)

我通过构造具有相同域和范围的第二个线性标度来解决它,然后在其上调用invert。

  var scale = d3.scale.ordinal()
    .domain(domain)
    .range(range);
  var continousScale = d3.scale.linear()
    .domain(domain)
    .range(range)

  var data = _.map(range, function(i) {
    return continousScale.invert(i);
  });

答案 6 :(得分:0)

如果您只是想知道哪个鼠标位置对应哪个数据,那么d3已经为您做了这个。

.on("click", function(d,i) {
    console.log("Clicked on " + d);
});

我已经从@AmeliaBR http://fiddle.jshell.net/dMpbh/17/

更新了小提琴

答案 7 :(得分:0)

您可以轻松地在回调中获取对象的索引/数据

.on("click", function(d,i) {
    console.log("Clicked on index = " + i); 
    console.log("Clicked on data  = " + d); 
    // d == imageScale.domain()[1]
}); 

d是 反转值本身 您不需要使用obj.domain()[index]。