FullCalendar v6资源时间线视图:按事件时长调整事件栏宽度
问题:FullCalendar v6资源时间线视图中按事件时长占比显示事件宽度
使用FullCalendar v6配置了展示6个月的资源时间线视图,每个时间槽对应1个月。当创建一个时长为10天的事件时,事件栏默认占据整个月槽的宽度,希望实现该事件栏仅占月槽宽度的1/3。
当前实现代码
<FullCalendar plugins={[ interactionPlugin, resourceTimelinePlugin, dayGridPlugin, multiMonthPlugin, scrollgridPlugin, timelinePlugin, ]} eventMinWidth={5} initialView='sixMonthView' views={ { sixMonthView: { eventOverlap: false, type: 'resourceTimelineMonth', duration: { months: 12}, slotLabelInterval: {months: 1}, slotDuration: { days: 1 }, dateIncrement: { months: 6 }, slotLabelClassNames: 'slot-label', slotMinWidth: 120, // slotLabelContent: slotLabelContentForOneMonth, }, } } editable={true} selectable={true} selectMirror={true} dayMaxEvents={true} weekends={this.state.weekendsVisible} resources={[ { id: 'a', title: 'Auditorium A' }, { id: 'b', title: 'Auditorium B', eventColor: 'green' }, { id: 'c', title: 'Auditorium C', eventColor: 'orange' }, ]} initialDate={'2023-07-01'} initialEvents={[ { title: 'nice', start: '2023-08-01', end: '2023-08-10', resourceId: 'a', allDay: true }, ]} />
当前效果

预期效果

解决方案
方法一:通过eventContent动态计算宽度(推荐)
利用FullCalendar的eventContent回调,自动计算事件时长占所在月份总天数的比例,动态设置事件元素的宽度:
- 在FullCalendar组件中添加
eventContent属性:
eventContent={({ event, el }) => { // 获取事件起始日期所在月份的总天数 const startDate = new Date(event.start); const totalMonthDays = new Date(startDate.getFullYear(), startDate.getMonth() + 1, 0).getDate(); // 计算事件实际天数(end为排他日期,需转换为天数差) const eventStart = new Date(event.start); const eventEnd = new Date(event.end); const eventDays = Math.floor((eventEnd - eventStart) / (1000 * 60 * 60 * 24)); // 计算宽度比例并设置样式 const widthPercentage = (eventDays / totalMonthDays) * 100; el.style.width = `${widthPercentage}%`; el.style.left = '0'; el.style.position = 'absolute'; // 返回事件标题内容 return { html: `<div class="fc-event-title">${event.title}</div>` }; }}
- 确保视图配置中的
slotDuration保持为{ days: 1 },这样FullCalendar能正确识别事件的日期跨度。
这种方法会自动适配不同月份的天数(比如28天的2月、31天的大月),无需手动调整比例。
方法二:CSS结合自定义事件属性
如果需要更灵活的样式控制,可以通过自定义事件属性+CSS来实现:
- 给事件添加自定义属性记录时长:
initialEvents={[ { title: 'nice', start: '2023-08-01', end: '2023-08-10', resourceId: 'a', allDay: true, extendedProps: { daysDuration: 10 } // 自定义时长属性 }, ]}
- 给事件添加自定义类名:
eventClassNames={({ event }) => [ 'custom-timeline-event', `duration-${event.extendedProps.daysDuration}` ]}
- 添加CSS样式:
/* 基础事件容器样式 */ .fc-resource-timeline .custom-timeline-event { position: relative; left: 0 !important; max-width: unset !important; } /* 针对10天事件设置宽度(8月共31天,10/31≈32.26%) */ .custom-timeline-event.duration-10 { width: 32.26% !important; }
注意:这种方法需要针对不同月份的天数手动调整CSS比例,适合固定月份场景。
内容的提问来源于stack exchange,提问作者Shubham
相关产品推荐
相关产品推荐

