Отображение данных о времени в горизонтальном календаре

У меня есть горизонтальный календарь, где каждый месяц имеет ширину 183px пикселей (пикселей). Я хочу отобразить панель времени в верхней части этого горизонтального календаря (см. Фото ниже) в зависимости от даты начала и даты окончания. Поэтому, если у меня есть начальная дата: 01-01-2020 и конечная дата: 03-15-2020 то есть около 2.5 months * 183px есть закрытие, которое я могу получить, но что я могу сделать или использовать, чтобы определить, что : 03-15-2020 - 01-01-2020 = ~2.5 months как можно точнее? Кроме того, мне нужен этот интервал времени, чтобы начать с текущей даты моего горизонтального календаря, поэтому, если он начинается left: 183px; div будет начинаться left: 183px; В настоящее время я изучаю date-fns но еще не повезло. Все может помочь, большое спасибо за ваше время. Я использую React.js, Javascript и Typescript.

Изображение горизонтального календаря и временной шкалы

Всего 2 ответа


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

т.е. eventWidth = daysInRange ÷ daysInYear * grahpFullWidth

Если вы просто хотите позиционировать что-либо с начала года, то всегда используйте 1 января текущего года в качестве начала диапазона.

Например, следующая дата помещает сегодняшнюю дату в полосу шириной 183 пикселя. Вы можете изменить график, изменив свойства стиля, например, установите ширину 300px.

function getDayOfYear(date) {
  // Use UTC to avoid any DST issues
  let d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
  let yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
  return Math.ceil((d - yearStart) / 8.64e7) + 1;
}

function getDaysInYear(date) {
  return getDayOfYear(new Date(date.getFullYear(), 11, 31));
}

function graphDate(date) {
  let dayNum = getDayOfYear(date);
  let daysInYear = getDaysInYear(date);
  let timeline = document.getElementById('timeline');
  let someEvent = document.getElementById('someEvent');
  let dateText = document.getElementById('dateText');
  let fullWidth = parseInt(window.getComputedStyle(timeline).getPropertyValue('width'));
  let partWidth = fullWidth * dayNum / daysInYear;
  someEvent.style.width = partWidth + 'px'
  dateText.textContent = date.toLocaleString('en-GB',{
    day: 'numeric',
    month: 'short'
  });
  dateText.style.marginLeft = partWidth - 1 + 'px'
  document.getElementById('yearLabel').textContent = date.getFullYear();
}

// Graph today
graphDate(new Date());
#timeline {
  border: 1px solid red;
  width: 183px;
  height: 10px;
}

#someEvent {
  border: 0;
  height: 10px;
  background-color: green;
  width: 0px;
}
#startLabel {
  width: 90px;
  display: inline-block;
}
#yearLabel {
  width: 90px;
  display: inline-block;
  font-size: 130%;
}
#dateText {
  padding: 15px 0 0 3px;
  border-left: 1px solid blue;
}
<div id="labels">
  <span id="startLabel">1 Jan</span>
  <span id="yearLabel"></span>
  <span id="endLabel">31 Dec</span>
</div>
<div id="timeline">
  <div id="someEvent"></div>
</div>
<div id="dateText"></div>


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

    var newStyles = document.createElement('style')
document.head.append(newStyles)
newStyles.innerHTML = ".my-element {" +
  "height: " + height + "px;" +
  "width: 40px;" +
  "color: #9b806b;" +
"}"

Есть идеи?

10000