D3 вычислить позицию x по датам

У меня есть график D3, где я строю график времени (hh:mm) по x относительно некоторых значений по оси y.

Для шкалы x я использую эту логику

    const currentData : string[] = ['06:00', '12:00', '18:00'];

    this.x = d3Scale.scalePoint(
      [0, this.width - this.margin.right - this.margin.left])
      .domain(
        currentData.map(
          (d: PlotData) => d.time))
      .round(true);
   

Это хорошо отображает все мои данные. Теперь я хотел бы использовать this.x, чтобы вернуть значение момента времени, которого в настоящее время нет в моих исходных данных. Но когда я запускаю его с

this.x('14:00')

он возвращает NAN , что, по-видимому, связано с тем, что ввод не находится в массиве currentData и работает только со значениями из массива.

Нужно ли мне интерполировать это значение самостоятельно или есть функция D3, чтобы взять this.x и вычислить this.x('14:00') внутренне?

Спасибо, ЭЛЬ

Поведение ключевого слова "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
420
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вместо этого может быть проще использовать scaleTime

const currentData : string[] = ['06:00', '12:00', '18:00'];

this.x = d3.scaleTime()
  .domain((d: PlotData) => d.time))
  .range([0, this.width - this.margin.right - this.margin.left]);

this.x(new DateTime('xyz:abc'))
Ответ принят как подходящий

Другой ответ предлагает правильный подход к использованию d3-scaleTime. Я хотел бы разобраться, почему вы видите свою проблему, а затем подробно рассказать о решении с помощью d3-scaleTime.

Порядковые шкалы

d3.scalePoint — порядковая шкала. Домен представляет собой дискретный и дискретный набор значений. Сопоставление домена с диапазоном основано на порядке, в котором указаны значения домена. Первое значение в домене сопоставляется с первым значением в диапазоне (с d3.scalePoint) независимо от его значения по сравнению с другими значениями в домене.

В результате только значения, которые существуют в домене, могут быть сопоставлены с диапазоном: между значениями в домене нет семантической/количественной связи, которая позволяет интерполировать промежуточные значения. Поскольку вы используете количественные, а не качественные или порядковые данные, вы хотите использовать шкалу, которая рассматривает домен как непрерывный.

Могут быть случаи, когда вы захотите использовать шкалу d3.scalePoint/Band с данными, основанными на времени, но в этих случаях вам нужно будет иметь возможность построить полный домен всех значений, которые необходимо нанести на график.

То, что ваша шкала сначала отображает ваши данные как непрерывные, является случайным, если ваше среднее значение домена было «07:00», «июнь» или «вчера», оно появится в середине вашего диапазона. То, что вы выбрали «12:00», скрывает тот факт, что шкала позиционирует это не на основе его значения, а только на его индексе.

Непрерывные весы

d3.scaleTime — одна из непрерывных шкал d3.

Непрерывные шкалы отображают непрерывную количественную входную область в непрерывный выходной диапазон. (документы)

Домены и диапазоны

Для непрерывных шкал d3 домен и диапазон должны содержать одинаковое количество элементов — если в каждом больше двух элементов, домен и диапазон разбиваются на сегменты:

 .domain([a,b,c]) // where a,b,c are quantitative
 .range([1,2,3])

Значения между a и b будут интерполированы между 1 и 2, аналогично значения между b и c будут интерполированы между 2 и 3. Если домен и диапазон имеют разное количество элементов, D3 пропустит лишние значения того, у которого больше .

В вашем случае кажется, что будет достаточно только двух значений домена, минимального и максимального значений, которые вы хотите передать на шкалу.

Использование дат

Домен d3.scaleTime должен быть установлен с объектами даты, а не строкой, такой как «12:00», также при передаче значения в шкалу (scale(x)) нам нужно передать объект даты. Мы можем создать базовый парсер даты d3 с помощью:

 d3.parseTime("%H:%M")

Что дает нам:

const currentData = ['06:00', '12:00', '18:00'];

const parse = d3.timeParse("%H:%M")

const x = d3.scaleTime()
        .range([0,100])
      .domain(d3.extent(currentData, (time) => parse(time)))
      
console.info("15:00 scales to: ", x(parse('15:00')))
console.info("06:00 scales to: ", x(parse('06:00')))
<script src = "https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Это должно отображать ваш домен, как и раньше, но также позволяет вам отображать значения, которых нет в вашем исходном наборе данных, и правильно сопоставлять их с диапазоном на основе их значения.

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