I have code using d3 v6.7.0 that sets up a scale like so:
const range = [0, 828.156];
const domain = [[300,1],[300,2],[300,3],[400,1],[400,2],[400,3],[400,4]]
const scale = d3.scaleBand()
.domain(domain)
.range(range);
// test 1: this works in both v6 and v7
const a = domain[3];
console.log('array a', a);
console.log('scaled a:', scale(a));
// test 2: declaring a new, identical array to the one above,
// also works in v6
const b = [400, 1];
console.log('array b', b);
console.log('scaled b:', scale(b));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js" integrity="sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
In d3 v7.9.0, this no longer works:
const range = [0, 828.156];
const domain = [[300,1],[300,2],[300,3],[400,1],[400,2],[400,3],[400,4]]
const scale = d3.scaleBand()
.domain(domain)
.range(range);
// test 1: this works in both v6 and v7
const a = domain[3];
console.log('array a', a);
console.log('scaled a:', scale(a));
// test 2: declaring a new, identical array to the one above,
// does not work in v7, but it does work in v6
const b = [400, 1];
console.log('array b', b);
console.log('scaled b:', scale(b));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js" integrity="sha512-vc58qvvBdrDR4etbxMdlTt4GBQk1qjvyORR2nrsPsFPyrs+/u5c3+1Ct6upOgdZoIl7eq6k3a1UPDSNAQi/32A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
Has something changed from v6 to v7, or what am I doing wrong?
2
Answers
It looks like D3 v7.9.0 made a change in how the scaleBand function handles input data. For example, when you try to pass an array as ([400, 1]), it might not be interpreted correctly as an array with two elements [400, 1].
Corrected Version
D3 v7 uses InternMap:
In v6 the domain would be coerced using
object.toString
:In v7 they use
object.valueOf
: