Создание горизонтального календаря с помощью VueJS и Vis.js, часть 1/3

Привет,

Сегодня я хочу показать свой прогресс в создании горизонтального календаря, какие разные пакеты я просмотрел и почему я остановился на Vis.js.

Если у вас возникнут какие-либо вопросы по пути, не стесняйтесь обращаться к нам.

Если вам просто интересен окончательный код, вы можете найти полный пример/суть здесь:

https://gist.github.com/Bottelet/9eda4b6b3d587635c5ad7c7bc1d8132d

Отказ от ответственности Я не работаю с Vuejs профессионально, а это значит, что, вероятно, будут более эффективные способы делать некоторые вещи. Я пишу эти посты, чтобы улучшить себя, и я учусь на ходу.

Предпосылки/Требования

Мои исследования начали рассматривать различные пакеты, варианты в основном сводились к этим трем:

  1. https://visjs.org/ (хронология)
  2. https://github.com/ka215/jquery.timeline
  3. https://github.com/neuronetio/gantt-schedule-timeline-calendar

Итак, третий вариант, хоть и выглядел очень красиво, был отброшен из-за используемой ими модели лицензирования (AGPL-3.0), в которой я не являюсь экспертом по лицензированию, и не мог получить абсолютно четкого ответа, что это такое. точно означает, что мне разрешено использовать это, не стоило риска для меня, и это коммерческий проект, для которого мне нужен этот график.

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

Начнем…

Первое, что мне нужно было сделать, это посмотреть, подойдет ли Vis.js для всех моих нужд.

мои требования к перспективе вертолета были:

  • Горизонтальный календарь
  • Несколько пользователей в виде строк
  • Масштабирование часов и дней
  • Перетащите записи календаря на новое время или новых пользователей. Что должно вызвать событие, чтобы я мог обновить запись «в режиме реального времени»
  • Развернуть/изменить время записи календаря.
  • Записи в одно и то же время будут показаны либо наложением друг на друга, либо перетеканием друг в друга другим цветом, чтобы сделать это очевидным.
  • Показать только часы работы
  • Выглядеть красиво (не лучший дизайнер :))

Давайте код…

Я использую Laravel в качестве фреймворка, в общем, это не должно сильно влиять на то, как вы что-то делаете, но будет небольшой бэкэнд, который использует некоторые термины Laravel, но может быть выполнен с любым бэкэндом, который вы выберите.

Сначала мне пришлось создать новую миграцию, модель, контроллер и маршрут. Я не буду вдаваться в подробности, так как это базовый Laravel, и это не будет слишком много о Laravel.

app/Http/Controllers/AppointmentsController.php
public function calendar()
{
return view(‘appointments.calendar’);
}
routes/web.php
Route::get(‘/appointments/calendar’, ‘AppointmentsController@calendar’)->name(‘appointments.calendar’);

Затем я начал играть с календарем, чтобы посмотреть, смогу ли я заставить его работать с моими потребностями, я начал просто делать это в колонке просмотра и еще не вводил Vue.js.

Начнем с добавления Vis CSS и JS.

<link href=”//unpkg.com/vis-timeline@latest/dist/vis-timeline-graph2d.min.css” rel=”stylesheet” type=”text/css” />
<script type=”text/javascript” src=”//unpkg.com/vis-timeline@latest/dist/vis-timeline-graph2d.min.js”></script>

Давайте инициализируем календарь в div с идентификатором визуализации, как показано в официальной документации.

<div id=”wrapper”>
<div id=”visualization”></div>
</div>
<script>
var container = document.getElementById(‘visualization’);
var timeline = new vis.Timeline(container);
</script>

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

Внутри нашего тега script добавьте следующие данные:

var items = [
{id: 1, content: “item 1”, start: ‘2020–04–01 10:00:00’, end: ‘2020–04–01 11:00:00’, group: 1},
{id: 2, content: ‘item 2’, start: ‘2020–04–01 09:00:00’, end: ‘2020–04–01 10:00:00’, group: 0},
{id: 3, content: ‘item 3’, start: ‘2020–04–03 08:00:00’, end: ‘2020–04–03 10:00:00’, group: 1},
];
var groups = [
{
id:0,
content: ‘Group 1’
},
{
id:1,
content: ‘Group 2’
},
];
var options = {
orientation: “top”, //Add the timeline to the top
itemsAlwaysDraggable:true, // Dont have to click for moving entries around
};
var container = document.getElementById(‘visualization’);
var timeline = new vis.Timeline(container);
timeline.setOptions(options);
timeline.setGroups(groups);
timeline.setItems(items);

И давайте добавим немного стиля, чтобы он выглядел наполовину прилично.

<style>
.vis-time-axis .vis-grid.vis-odd {
background: #f5f5f5;
}
.vis-time-axis .vis-grid.vis-saturday,
.vis-time-axis .vis-grid.vis-sunday {
background: gray;
}
.vis-time-axis .vis-text.vis-saturday,
.vis-time-axis .vis-text.vis-sunday {
color: white;
}
.vis-item {
background-color: #d6e6ff;
border-color: #1371fe;
color: #0155d3;
border-left-width: 3px;
border-left-style: solid;
font-weight: 500;
opacity: .8;
font-size: 13px;
height: 55px;
}
</style>

Давайте добавим еще несколько параметров на нашу временную шкалу, чтобы сделать ее более интерактивной и соответствующей тому, что нам нужно. (дополнительные параметры добавлены в нижней части этого блока кода)

Вот как должен выглядеть ваш скрипт сейчас:

<script>
// DOM element where the Timeline will be attached
var container = document.getElementById(‘visualization’);
var items = [
{id: 1, content: “Item 1”, start: ‘2020–04–01 10:00:00’, end: ‘2020–04–01 11:00:00’, group: 1},
{id: 2, content: ‘item 2’, start: ‘2020–04–01 09:00:00’, end: ‘2020–04–01 10:00:00’, group: 0},
{id: 3, content: ‘item 3’, start: ‘2020–04–03 08:00:00’, end: ‘2020–04–03 10:00:00’, group: 1},
];
var groups = [
{
id:0,
content: ‘Group 1’
// Optional: a field ‘className’, ‘style’, ‘order’, [properties]
},
{
id:1,
content: ‘Group 2’
// Optional: a field ‘className’, ‘style’, ‘order’, [properties]
}
// more groups…
];
// Configuration for the Timeline
var options = {
orientation: “top”,
itemsAlwaysDraggable:true,
timeAxis: {scale: ‘hour’, step: 1, },
zoomMax: 150000000,//for days 7 instead of 6?
minHeight:’500px’,
start: ‘2020–04–01’,
hiddenDates: { // Show only times between 06:00–18:00
start: ‘2020–03–04 18:00:00’,
end: ‘2020–03–05 06:00:00’,
repeat: ‘daily’
},
editable: {
add: true, // add new items by double tapping
updateTime: true, // drag items horizontally
updateGroup: true, // drag items from one group to another
remove: true, // delete an item by tapping the delete button top right
overrideItems: false // allow these options to override item.editable
},
onUpdate: function (item, callback) { //Fires event on update
item.content = prompt(‘Edit items text:’, item.content);
if (item.content != null) {
callback(item); // send back adjusted item
}
else {
callback(null); // cancel updating the item
}
},
onMove: function (item, callback) { // fire events on move
console.log(item, callback)
if (item.content != null) {
callback(item); // send back adjusted item
}
else {
callback(null); // cancel updating the item
}
},
};
// Create a Timeline
var timeline = new vis.Timeline(container);
timeline.setOptions(options);
timeline.setGroups(groups);
timeline.setItems(items);
</script>

Теперь у нас есть рабочий календарь, давайте перенесем его на VueJS на шаге 2