Страницы

Поиск по вопросам

четверг, 26 декабря 2019 г.

Временная шкала на html

#html #css #laravel #vuejs




Как реализовать подобную шкалу времени на html с добавлением 'красных участков'

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

На bootstrap получилось сделать что-то подобное(Закинул на jsfiddle, внутри SO не
работает)

На сколько это 'правильная' реализация?

Шкала нужна для вывода планов на день

Есть таблица с планами, в ней есть столбцы date_start и date_finish

Дата храниться подобным образом 2018-11-09 10:00:00

Выбираем желаемую дату и смотрим, что на эту дату запланировано. Простой вывод сделан(на
скрине справа). На скрине шкала не подключена(Тестирую)


UPD ---

Во что у меня получилось:

Контроллер:

  $rez = Plan::whereDate('date_start', '>=', $plan_day)
                ->whereDate('date_start', '<=', $plan_day)
                ->get();//Достаем планы за определенное число
  foreach ($rez as $item) {
    $date_start_h = date("H", strtotime($item->date_start));
    $date_finish_m = date("i", strtotime($item->date_finish));
    if($date_start_h == 9) {
      $progress['nine'][] = ($date_finish_m*100)/60;
    } else if($date_start_h == 10) {
      $progress['ten'][] = ($date_finish_m*100)/60;
    } else if($date_start_h == 11) {
      $progress['eleven'][] = ($date_finish_m*100)/60;
    } else if($date_start_h == 12) {
      $progress['twelve'][] = ($date_finish_m*100)/60;
    } else if($date_start_h == 13) {
      $progress['thirteen'][] = ($date_finish_m*100)/60;
    } else if($date_start_h == 14) {
      $progress['fourteen'][] = ($date_finish_m*100)/60;
    } else if($date_start_h == 15) {
      $progress['fifteen'][] = ($date_finish_m*100)/60;
    } else if($date_start_h == 16) {
      $progress['sixteen'][] = ($date_finish_m*100)/60;
    } else if($date_start_h == 17) {
      $progress['seventeen'][] = ($date_finish_m*100)/60;
    }
  }
  $v['progress'] = $progress;
  return $v;


Вывод (planDay.progress равен $v['progress'] из контроллера):

9:00
10:00
11:00
12:00
13:00
14:00
15:00
16:00
17:00
Вот что получилось на скрине: Появилось несколько проблем: 1)Не учтена дата начала, на скрине это Элегант, дата начала с 12:20 до 12:30 - на шкале он не учитывает 12:20, отсчет начинает с начала и до 30 2)Выделения на шкале используют 100 процентов, для выделения я использую минуты, максимальное значение в минутах это 60. Получается если будет например с 12:00 до 12:50, на шкале это будет 50% хотя 83% Перевел минуты в проценты (минуты*100)/60 3)Если план будет с 12:00 до 13:00 все сломается 4)Как-то слишком много кода


Ответы

Ответ 1



Так как рабочих решений на html+css выдвинуто не было, предлагаю решение на canvas const time = { "11:00": [ [0, 20], [40, 60] ], "12:00": [ [10, 20], [30, 40], [50, 60] ], "13:00": [ [0, 60] ], "14:00": [], "15:00": [], "16:00": [ [25, 47] ] }; window.addEventListener('resize', () => timeLine(time, "c")); timeLine(time, "c") function timeLine(time, canvasID) { const canvas = document.getElementById(canvasID); const c = canvas.getContext('2d'); const num = Object.keys(time).length; const img = document.createElement("img"); img.src = "https://image.ibb.co/eH3VCA/img-2018-11-22-18-03-12.png"; img.onload = function() { const ptrn = c.createPattern(img, 'repeat'); // Create a pattern with this image, and set it to "repeat". c.canvas.width = parseInt(getComputedStyle(canvas).width); c.canvas.height = parseInt(getComputedStyle(canvas).height); c.font = "10px Comic Sans MS"; c.lineWidth = 1; c.strokeStyle = "black"; const unitWidth = c.canvas.width / num; const tlh = c.canvas.height - 20; // tlh = timeline height let i = 0; for (let t in time) { if (time[t].length !== 0) { c.fillStyle = ptrn; time[t].forEach((it) => { c.fillRect(unitWidth * i + unitWidth / 60 * it[0], "0", unitWidth / 60 * (it[1] - it[0]), tlh); }) } c.fillStyle = 'green'; c.fillText(t, unitWidth * i, (2 * tlh + 20) / 2); i++; } //Draw vertical lines for (i = 0; i <= num; i++) { let x = unitWidth * i; // Check the first and last lines; x = x === 0 ? c.lineWidth / 2 : i === num ? (c.canvas.width - c.lineWidth / 2) : x; c.beginPath(); c.moveTo(x, 0); c.lineTo(x, tlh); c.stroke(); } // Top and bottom lines c.beginPath(); c.moveTo(c.lineWidth / 2, c.lineWidth / 2); c.lineTo(c.canvas.width, c.lineWidth / 2); c.moveTo(c.lineWidth, tlh - c.lineWidth / 2); c.lineTo(c.canvas.width, tlh - c.lineWidth / 2); c.stroke(); } } canvas { width: 100%; height: 70px; }

Комментариев нет:

Отправить комментарий