У меня есть код, использующий d3 v6.7.0, который устанавливает шкалу следующим образом:
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.info('array a', a);
console.info('scaled a:', scale(a));
// test 2: declaring a new, identical array to the one above,
// also works in v6
const b = [400, 1];
console.info('array b', b);
console.info('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>В d3 v7.9.0 это больше не работает:
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.info('array a', a);
console.info('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.info('array b', b);
console.info('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>Что-то изменилось с v6 на v7 или что я делаю не так?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Похоже, что D3 v7.9.0 внес изменения в то, как функция ScaleBand обрабатывает входные данные. Например, когда вы пытаетесь передать массив как ([400, 1]), он может быть неправильно интерпретирован как массив с двумя элементами [400, 1].
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);
// corrected test 2
const b = [400, 1];
console.info('array b', b);
console.info('scaled b:', scale(b));
Хороший глаз, спасибо. Вы правы, не было никакой причины заключать объявления массивов в круглые скобки, это была опечатка с моей стороны (я отредактировал вопрос). Но, как отмечает @Mark, даже без скобок масштаб возвращается undefined в v7.
D3 v7 использует InternMap:
Порядковые шкалы теперь используют InternMap для доменов; Значения домена теперь уникальны за счет приведения к примитивному значению через
object.valueOfвместо приведения к строке черезobject.toString.
В версии 6 домен будет принудительно использоваться с помощью object.toString:
console.info([400,1].toString() === [400,1].toString())В v7 они используют object.valueOf:
console.info([400,1].valueOf() === [400,1].valueOf())Это хороший ответ. @toms, немного больше контекста см. здесь, чтобы узнать больше контекста InternMap.
Спасибо вам обоим. Читаю сейчас - кажется, это укажет на подход, который работает, хотя я еще не совсем знаю, что это такое. Я могу привести каждое отдельное значение домена к строке при настройке шкалы (и это работает), но это кажется хакерским.
Это тоже возвращает
undefined.