У меня есть график 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')
внутренне?
Спасибо, ЭЛЬ
Вместо этого может быть проще использовать 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>
Это должно отображать ваш домен, как и раньше, но также позволяет вам отображать значения, которых нет в вашем исходном наборе данных, и правильно сопоставлять их с диапазоном на основе их значения.