Ordinal scale behaviour

微笑、不失礼 提交于 2019-12-01 09:01:27
Gerardo Furtado

That's the expected behaviour of an ordinal scale. Actually, D3 scales (quantitative or qualitative) are made in such a way that you can pass values outside the domain (see my answer here).

If you want to define outputs for unknown inputs, use scale.unknown():

var x = d3.scaleOrdinal()
    .domain(['a', 'b', 'c'])
    .range([10, 20, 30])
    .unknown("not in the scale");

console.log("a is " + x("a"));
console.log("b is " + x("b"));
console.log("c is " + x("c"));
console.log("f is " + x("f"));
console.log("xyz is " + x("xyz"));
<script src="https://d3js.org/d3.v4.min.js"></script>

EDIT: Regarding OP's question in the comments:

Are the range values for values outside the domain chosen randomly or is there a logic?

The logic can be seen inspecting the source code:

function scale(d) {
    var key = d + "", i = index.get(key);
    if (!i) {
        if (unknown !== implicit) return unknown;
        index.set(key, i = domain.push(d));
    }
    return range[(i - 1) % range.length];
}

It shows us that, if the value doesn't exist, it's pushed into the domain. So, values not specified in the domain will have an output that will "cycle" through the range. Check this demo, the output is 10, 20, 30, 10, 20, 30, 10, 20...:

var x = d3.scaleOrdinal()
    .domain(['a', 'b', 'c'])
    .range([10, 20, 30]);

console.log("d is " + x("d"));
console.log("e is " + x("e"));
console.log("f is " + x("f"));
console.log("g is " + x("g"));
console.log("h is " + x("h"));
console.log("i is " + x("i"));
console.log("j is " + x("j"));
<script src="https://d3js.org/d3.v4.min.js"></script>

Which has the same outcome of writing this:

var x = d3.scaleOrdinal()
.domain(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
.range([10, 20, 30]);

In this case d corresponds to 10, e corresponds to 20, f corresponds to 30 etc...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!