Создание горизонтального календаря с помощью VueJS и Vis.js, часть 1/3
Привет,
Сегодня я хочу показать свой прогресс в создании горизонтального календаря, какие разные пакеты я просмотрел и почему я остановился на Vis.js.
Если у вас возникнут какие-либо вопросы по пути, не стесняйтесь обращаться к нам.
- Твиттер @cbottelet
- LinkedIn Каспер
- Гитхаб Ботлет
Если вам просто интересен окончательный код, вы можете найти полный пример/суть здесь:
https://gist.github.com/Bottelet/9eda4b6b3d587635c5ad7c7bc1d8132d
Отказ от ответственности Я не работаю с Vuejs профессионально, а это значит, что, вероятно, будут более эффективные способы делать некоторые вещи. Я пишу эти посты, чтобы улучшить себя, и я учусь на ходу.
Предпосылки/Требования
Мои исследования начали рассматривать различные пакеты, варианты в основном сводились к этим трем:
- https://visjs.org/ (хронология)
- https://github.com/ka215/jquery.timeline
- 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