Как реализовать подобную шкалу времени на 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']
из контроллера):
<div class="row">
<div class="col" style="padding-right: 0;">
<div>9:00</div>
<div class="progress progress-plan">
<template v-for="nine in planDay.progress.nine">
<div class="progress-bar progress-bar-striped bg-info" role="progressbar" :style="'width:'+nine+'%'" aria-valuenow="15" aria-valuemin="0" aria-valuemax="100"></div>
</template>
</div>
</div>
<div class="col" style="padding: 0">
<div>10:00</div>
<div class="progress progress-plan">
<template v-for="ten in planDay.progress.ten">
<div class="progress-bar progress-bar-striped bg-info" role="progressbar" :style="'width:'+ten+'%'" aria-valuenow="15" aria-valuemin="0" aria-valuemax="100"></div>
</template>
</div>
</div>
<div class="col" style="padding: 0">
<div>11:00</div>
<div class="progress progress-plan">
<template v-for="eleven in planDay.progress.eleven">
<div class="progress-bar progress-bar-striped bg-info" role="progressbar" :style="'width:'+eleven+'%'" aria-valuenow="15" aria-valuemin="0" aria-valuemax="100"></div>
</template>
</div>
</div>
<div class="col" style="padding: 0">
<div>12:00</div>
<div class="progress progress-plan">
<template v-for="twelve in planDay.progress.twelve">
<div class="progress-bar progress-bar-striped bg-info" role="progressbar" :style="'width:'+twelve+'%'" aria-valuenow="15" aria-valuemin="0" aria-valuemax="100"></div>
</template>
</div>
</div>
<div class="col" style="padding: 0">
<div>13:00</div>
<div class="progress progress-plan">
<template v-for="thirteen in planDay.progress.thirteen">
<div class="progress-bar progress-bar-striped bg-info" role="progressbar" :style="'width:'+thirteen+'%'" aria-valuenow="15" aria-valuemin="0" aria-valuemax="100"></div>
</template>
</div>
</div>
<div class="col" style="padding: 0">
<div>14:00</div>
<div class="progress progress-plan">
<template v-for="fourteen in planDay.progress.fourteen">
<div class="progress-bar progress-bar-striped bg-info" role="progressbar" :style="'width:'+fourteen+'%'" aria-valuenow="15" aria-valuemin="0" aria-valuemax="100"></div>
</template>
</div>
</div>
<div class="col" style="padding: 0">
<div>15:00</div>
<div class="progress progress-plan">
<template v-for="fifteen in planDay.progress.fifteen">
<div class="progress-bar progress-bar-striped bg-info" role="progressbar" :style="'width:'+fifteen+'%'" aria-valuenow="15" aria-valuemin="0" aria-valuemax="100"></div>
</template>
</div>
</div>
<div class="col" style="padding: 0">
<div>16:00</div>
<div class="progress progress-plan">
<template v-for="sixteen in planDay.progress.sixteen">
<div class="progress-bar progress-bar-striped bg-info" role="progressbar" :style="'width:'+sixteen+'%'" aria-valuenow="15" aria-valuemin="0" aria-valuemax="100"></div>
</template>
</div>
</div>
<div class="col" style="padding-left: 0">
<div>17:00</div>
<div class="progress progress-plan">
<template v-for="seventeen in planDay.progress.seventeen">
<div class="progress-bar progress-bar-striped bg-info" role="progressbar" :style="'width:'+seventeen+'%'" aria-valuenow="15" aria-valuemin="0" aria-valuemax="100"></div>
</template>
</div>
</div>
</div>
</div>
Вот что получилось на скрине:
Появилось несколько проблем:
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)Как-то слишком много кода
Так как рабочих решений на 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;
}
<canvas id="c"></canvas>
Виртуальный выделенный сервер (VDS) становится отличным выбором
подскажите пожалуйста как исправить баг в хроме
Как можно реализовать scroll контента в Desktop версии на каждой вкладке в pop-up? В мобильной версии (media query) вкладки пропадают и все вливается в одну...
Подскажите, как убрать эту рамку как на изображении после клика мыши? Focus border none пробовал