Шкала D3 работает в версии 6, но не в версии 7

У меня есть код, использующий 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 или что я делаю не так?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
72
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Похоже, что 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));

Это тоже возвращает undefined.

Mark 03.04.2024 14:22

Хороший глаз, спасибо. Вы правы, не было никакой причины заключать объявления массивов в круглые скобки, это была опечатка с моей стороны (я отредактировал вопрос). Но, как отмечает @Mark, даже без скобок масштаб возвращается undefined в v7.

toms 03.04.2024 15:31
Ответ принят как подходящий

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.

Mark 03.04.2024 14:25

Спасибо вам обоим. Читаю сейчас - кажется, это укажет на подход, который работает, хотя я еще не совсем знаю, что это такое. Я могу привести каждое отдельное значение домена к строке при настройке шкалы (и это работает), но это кажется хакерским.

toms 03.04.2024 15:35

Другие вопросы по теме

Похожие вопросы

Изображение в твиттере при обмене контентом
Ключ доступа с библиотекой машинописных текстов simplewebauthn и менеджером паролей
Я написал этот код, но не понимаю, как JavaScript обрабатывает замену??? (Я видел это раньше в статье, но не объяснил)
Ошибка OpenAI API: «Конфигурация не является конструктором»
Почему оценка этого выражения не определена, хотя при отладке оно показывает правильное значение?
Как исправить таблицу, построенную на js, всякий раз, когда я добавляю дополнительный столбец, который будет помещен в качестве первого столбца?
У меня проблема со свойством Excel JS — защита {locked: true}
Выражение JavaScript на стороне клиента в динамическом действии Oracle Apex
JS Структура/алгоритм данных для случайного выбора из набора с уменьшением вероятности
Angular Material перетаскивает сложенную колоду карт и автоматически расширяется при наведении