最终效果图如下:
HTML
<div class="guides-schedules-content">
<div class="guide-view" style="">
<table>
<thead class="guide-head">
<tr>
<td class="guide-border-none">
<div class="guide-row">
<table>
<thead>
<tr class="tr-header-js">
<!--头部数据插入处-->
</tr>
</thead>
</table>
</div>
</td>
</tr>
</thead>
<tbody class="guide-body">
<tr>
<td class="guide-border-none">
<div class="" style="">
<div class="guide-day-grid guide-day-grid-js">
<!--划线插入处-->
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
CSS
.form-month-schedules{font-size:0;text-indent: 0;}
.form-month-schedules span,
.form-month-schedules input,
.form-month-schedules button,
.form-month-schedules select{display: inline-block;vertical-align: middle;font-size:12px;border-radius: 0 0 0 0;}
.form-month-schedules .keyword-input{height:12px;margin-right:25px;}
.form-month-schedules .item-title{margin-left:20px;}
.form-month-schedules .search-button{
height:20px;
display: inline-block;
border-style: none;
border-color: inherit;
border-width: medium;
background-color: #FF7502;
background-repeat: repeat-x;
vertical-align: middle;
zoom: 1;
border-radius: 0 0 0 0;
box-shadow: 0 0 0 #FFFFFF inset, 0 0 1px #FFFFFF;
color: #FFFFFF;
outline: 1px solid #E35C00;
padding: 1px 24px;
text-shadow: none;
font-family: simsun;
background-image: -webkit-gradient(linear,left bottom,left top,color-stop(0, #ff7502),color-stop(1, #ff9a00));
background-image: linear-gradient(top, #ff9a00 0%, #ff7502 100%);
filter: progid:DXImageTransform.Microsoft.Gradient(gradientType=0,startColorStr=#ff9a00,endColorStr=#ff7502);
background-image: -o-linear-gradient(top, #ff9a00 0%, #ff7502 100%);
background-image: -moz-linear-gradient(top, #ff9a00 0%, #ff7502 100%);
background-image: -webkit-linear-gradient(top, #ff9a00 0%, #ff7502 100%);
background-image: -ms-linear-gradient(top, #ff9a00 0%, #ff7502 100%);
background-image: -webkit-gradient(linear,left bottom,left top,color-stop(0, #ff7502),color-stop(1, #ff9a00));
}
.form-month-schedules .right-angle{border-radius: 0 0 0 0;margin-bottom:1px;}
.form-month-schedules .input-height{height:22px;}
.form-month-schedules .year-select{margin-right:10px;}
.guides-schedules-content {}
.guide-view {}
.guide-view table{width:100%;table-layout: fixed;}
.guide-view td,
.guide-view th{border-style: solid;border-width: 1px;border-color:#FFF;padding: 0;vertical-align: top;color:#333;}
.guide-view .guide-head .guide-header{font-weight:normal;padding-top:0.25em;padding-bottom:0.25em;height:45px;border-bottom-color:#FFF;background-color:#FAFAFA;vertical-align: middle;text-align: center;}
.guide-view .guide-head .weekend-color{color:#FF2200;}
.guide-view .guide-border{border-color: #E6E6E6;}
.guide-view .guide-border-none{border:0;}
.guide-view .guide-first-col{width:70px;vertical-align: middle;text-align: center;position:relative;}
.guide-view .guide-head .guide-first-col .guide-name{position:absolute;bottom:0.5em;left:0.6em;font-weight:bold;color:#999;}
.guide-view .guide-head .guide-first-col .guide-date{position:absolute;right:0.6em;top:0.5em;font-weight:bold;color:#999;}
.guide-view .guide-head .guide-first-col .slant-line{position:absolute;width:88px;height:1px;background-color:#E6E6E6;top:25px;left:-8px;transform: rotate(36deg);-webkit-transform: rotate(36deg);-moz-transform: rotate(36deg);-ms-transform: rotate(36deg);-o-transform: rotate(36deg);}
.guide-view .guide-last-col{width:30px;padding:0 0.25em;vertical-align: middle;text-align: center;}
.guide-body .guide-event-content{padding:5px 0;}
.guide-body .guide-row{position:relative;z-index:1;}
.guide-body .guide-bg{position:absolute;z-index:1;left:0;right:0;top:0;bottom:0;}
.guide-body .guide-bg table{height:100%;}
.guide-body .guide-day-grid-event{display:block;position:relative;margin:5px 5px;height:10px;z-index:2;cursor:pointer;}
.guide-body .guide-day-grid-event .inner-line{position:absolute;left:0;right:0;top:4px;height:2px;background-color:red;}
.guide-body .guide-day-grid-event .inner-line .day-begin-point{
position:absolute;
display:inline-block;
left:0;
top:-3px;
width:8px;
height:8px;
background-color:inherit;
overflow: hidden;
border-radius: 50%;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
}
.guide-body .guide-day-grid-event .inner-line .day-end-point{
position:absolute;
display:inline-block;
right:0;
top:-3px;
width:8px;
height:8px;
background-color:inherit;
overflow: hidden;
border-radius: 50%;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
}
.guide-event-content .line-color-1 .inner-line{background-color:#6ad2ec;}
.guide-event-content .line-color-2 .inner-line{background-color:#fd5b78;}
.guide-event-content .line-color-3 .inner-line{background-color:#fdb933;}
.guide-event-content .line-color-4 .inner-line{background-color:#94d600;}
.detail-link-box{color:#4D4D4D;}
.detail-link-box .detail-link-url{margin-left:10px;color:#1686cc;text-decoration:none;}
.detail-link-box .detail-link-url:hover{text-decoration:underline;}
.detail-link-content-box >.inner{border:0;}
javascript
/**
* 导游月度排期表
*
* 作者:
* */
$(function(){
//生成排期表方法执行
var eventArr=[
{
name:'张三',
personId:123456,
schedules:[
{
TeamId:654321,
TeamType:"自由行",
TeamCode:"SKY-ZY20180109001",
StartDate:'2018/05/01',
EndDate:'2018/05/03',
DetailLink:'shoukeyi.com/daoyou/detail?id=151511'
},
{
TeamId:654321,
TeamType:"自由行",
TeamCode:"SKY-ZY20180109002",
StartDate:'2018/05/04',
EndDate:'2018/05/08',
DetailLink:'shoukeyi.com/daoyou/detail?id=151512'
},
{
TeamId:654321,
TeamType:"自由行",
TeamCode:"SKY-ZY20180109002",
StartDate:'2018/05/03',
EndDate:'2018/05/07',
DetailLink:'shoukeyi.com/daoyou/detail?id=151515'
},
{
TeamId:654321,
TeamType:"自由行",
TeamCode:"SKY-ZY20180109002",
StartDate:'2018/05/07',
EndDate:'2018/05/11',
DetailLink:'shoukeyi.com/daoyou/detail?id=151515'
},
{
TeamId:654321,
TeamType:"自由行",
TeamCode:"SKY-ZY20180109002",
StartDate:'2018/05/05',
EndDate:'2018/05/10',
DetailLink:'shoukeyi.com/daoyou/detail?id=151515'
},
{
TeamId:654321,
TeamType:"自由行",
TeamCode:"SKY-ZY20180109002",
StartDate:'2018/05/10',
EndDate:'2018/05/15',
DetailLink:'shoukeyi.com/daoyou/detail?id=151515'
},
{
TeamId:654321,
TeamType:"自由行",
TeamCode:"SKY-ZY20180109002",
StartDate:'2018/05/07',
EndDate:'2018/05/18',
DetailLink:'shoukeyi.com/daoyou/detail?id=151515'
}
]
},
{
name:'李四',
personId:123457,
schedules:[
{
TeamId:654321,
TeamType:"自由行",
TeamCode:"SKY-ZY20180109002",
StartDate:'2018/05/04',
EndDate:'2018/05/06',
DetailLink:'shoukeyi.com/daoyou/detail?id=151515'
},
{
TeamId:654321,
TeamType:"自由行",
TeamCode:"SKY-ZY20180109002",
StartDate:'2018/05/01',
EndDate:'2018/05/03',
DetailLink:'shoukeyi.com/daoyou/detail?id=151515'
},
{
TeamId:654321,
TeamType:"自由行",
TeamCode:"SKY-ZY20180109002",
StartDate:'2018/05/09',
EndDate:'2018/05/12',
DetailLink:'shoukeyi.com/daoyou/detail?id=151515'
}
]
},
{
name:'王五',
personId:123458,
schedules:[
{
TeamId:654321,
TeamType:"跟团游",
TeamCode:"SKY-ZY20180109002",
StartDate:'2018/05/02',
EndDate:'2018/05/05',
DetailLink:'shoukeyi.com/daoyou/detail?id=151515'
},
{
TeamId:654321,
TeamType:"自由行",
TeamCode:"SKY-ZY20180109002",
StartDate:'2018/05/06',
EndDate:'2018/05/10',
DetailLink:'shoukeyi.com/daoyou/detail?id=151515'
},
{
TeamId:654321,
TeamType:"自由行",
TeamCode:"SKY-ZY20180109002",
StartDate:'2018/05/11',
EndDate:'2018/05/14',
DetailLink:'shoukeyi.com/daoyou/detail?id=151515'
},
{
TeamId:654321,
TeamType:"自由行",
TeamCode:"SKY-ZY20180109002",
StartDate:'2018/05/16',
EndDate:'2018/05/20',
DetailLink:'shoukeyi.com/daoyou/detail?id=151515'
},
{
TeamId:654321,
TeamType:"自由行",
TeamCode:"SKY-ZY20180109002",
StartDate:'2018-05-22',
EndDate:'2018-05-28',
DetailLink:'shoukeyi.com/daoyou/detail?id=151515'
}
]
}
];
guidesMonthlySchedules({
events:eventArr
});
//每个排期的hover事件
$(document).on("mouseover",".guide-each-line-js",function(event){
var self=$(this);
var detail=self.attr("data-detail");
var DeatilUrl=self.attr("data-url");
var html='<div class="detail-link-box"><span>'+detail+'</span><a class="detail-link-url" href="'+DeatilUrl+'">→详情</a></div>';
$.showDialog({
$trigger:self,
message:html,
extraOffsetX:10,
extraOffsetY:0,
eventType :event.type,
showType:'tooltips',
isShowArrow:false,
isShowCloseButton:false,
reverseDirection:true,
styleClass:'detail-link-content-box'
})
})
})
//数组去重
Array.prototype.DelRepeat=function(){
var res = [];
var json = {};
for(var i = 0; i < this.length; i++){
if(!json[this[i]]){
res.push(this[i]);
json[this[i]] = 1;
}
}
// for(var i=0,len=res.length;i< len;i++){
// if(res[i]==''){
// res.splice(i,1);
// len--;//删掉一个减少一个,一定要,否则和i判断不了
// i--;//删掉了元素要退回去上一个i再判断和len的关系,不然会出错
// }
// }
return res;
}
//月度排期表总方法
function guidesMonthlySchedules(options){
//模拟数据
var defaults={
year:new Date().Format('yyyy'),
month:new Date().Format('MM'),
strictMode:false,//严格模式下每个线条自成一行
events:[]
};
//取得某个月所有日期和星期几数组
var opts=$.extend({}, defaults, options||{});
var currentMonthFirstDay=getMonthFirstLastDay(opts.year,opts.month)[0];
var currentMonthLastDay=getMonthFirstLastDay(opts.year,opts.month)[1];
var lastDay=new Date(currentMonthLastDay).Format('dd')-0;
var DaysAndWeeksArray=[];
//生成头部
var $header=$(".tr-header-js");
$header.empty();
var centerHtml='';
for(var i=0;i < lastDay;i++){
var dayStr=opts.year+'/'+opts.month+'/'+(i+1);
var monthDay=new Date(dayStr).Format('MM-dd');
var week=date2holiday(dayStr).cnWeekDay;
var weekendColor='';
if(date2holiday(dayStr).weekDay==0 || date2holiday(dayStr).weekDay==6){
weekendColor='weekend-color'
}
centerHtml+='<th class="guide-border guide-header"><div>'+monthDay+'</div><div class="'+weekendColor+'">'+week+'</div></th>';
}
var headerHtml='<th class="guide-border guide-header guide-first-col"><span class="guide-name">导游</span><i class="slant-line"></i><span class="guide-date">日期</span></th>'+centerHtml+'<th class="guide-border guide-header guide-last-col">出团天数</th>';
$header.append(headerHtml);
//生成背景分割线以及排期划线
var $grid=$(".guide-day-grid-js");
$grid.empty();
if(opts.events.length){
//开始生成每个导游对应的行
$.each(opts.events,function(){
//生成排期划线
//1、先计算出所有排期线的行列数组
var colRowArray=[];
$.each(this.schedules,function(){
var leftCol=new Date(this.StartDate).Format('d')-0;
var rightCol=new Date(this.EndDate).Format('d')-0;
var colRowJson={leftCol:leftCol,rightCol:rightCol,TeamCode:this.TeamCode,TeamType:this.TeamType,DetailLink:this.DetailLink};
colRowArray.push(colRowJson);
});
//2、排序
colRowArray.sort(function(a,b){
return a.leftCol-b.leftCol;
});
//统计总共出团多少天
var DayCountArr=[];
$.each(colRowArray, function() {
for(var i=this.leftCol;i<=this.rightCol;i++){
DayCountArr.push(i);
}
});
DayCountArr=DayCountArr.DelRepeat();
//生成背景分割线
var bgCenterHtml='';
for(var u=0;u < lastDay;u++){
var dayStr=opts.year+'/'+opts.month+'/'+(u+1);
bgCenterHtml+='<td class="guide-day guide-border" data-date="'+dayStr+'"></td>';
};
var bghtml='<td class="guide-day guide-border guide-first-col">'+this.name+'</td>'+bgCenterHtml+'<td class="guide-day guide-border guide-last-col">'+DayCountArr.length+'</td>';
//3、整理占哪一行(加上行值)
var colRowLevelArray=[];//拿到最早的那个准备对比//新插入的json跟已经存在的json对比是否重叠,重叠则另起一行
for(var k=0;k < colRowArray.length;k++){
if(!opts.strictMode){
var j,rowNum=0;
for(j=0;j < colRowLevelArray.length;j++){
//重叠 //跟某一行重叠则跳到下一行
if(colRowLevelArray[j].row==rowNum && (colRowArray[k].rightCol >= colRowLevelArray[j].leftCol && colRowArray[k].leftCol <= colRowLevelArray[j].rightCol)){
rowNum++;
j=-1;//下一行重置j,重新开始循环
}
}
}
colRowLevelArray.push(colRowArray[k]);
if(opts.strictMode){
colRowLevelArray[k].row=k;
}else{
colRowLevelArray[k].row=rowNum;
}
};
//4、重新排序
colRowLevelArray.sort(function(a,b){
return a.row-b.row || a.leftCol-b.leftCol;//优先按照行值排序,行相同则时间早的优先
});
//console.log(colRowLevelArray);//画图数组已经出来
//5、取得行循环数组
var rowsArray=[];
$.each(colRowLevelArray,function(){
rowsArray.push(this.row);
});
var delRepeatRowArray=rowsArray.DelRepeat();//去重
//6、开始画行
var eventsHtml='';
var rightNum=0;
var trColorCount=1;
var lineColorOrder=1;
$.each(delRepeatRowArray,function(i){
var s=1;
var eacheventHtml='';
//6.1开始画某个导游的每一行
for(var j=0;j < colRowLevelArray.length;j++){
var self=colRowLevelArray[j];
if(self.row==i){
//6.2拿到本行rightCol值数组
var RightColArray=[];
$.each(colRowLevelArray, function() {
if(this.row==i){
RightColArray.push(this.rightCol);
}
});
//6.3画线前面的td和线自己
var TdEmptyHtml='<td></td>';
for(;s <= lastDay ; s++){
//空值或者跨列html
var lineColspan=self.rightCol-self.leftCol+1;
var TdLineHtml='<td colspan="'+lineColspan+'">'
+'<a class="guide-day-grid-event guide-each-line-js" data-url='+self.DetailLink+' data-detail="'+self.TeamCode+' '+self.TeamType+'">'
+'<div class="inner-line color-line-'+lineColorOrder+'"><span class="day-begin-point"></span><span class="day-end-point"></span></div>'
+'</a>'
+'</td>';
if(s <= self.rightCol && s >= self.leftCol){
eacheventHtml+=TdLineHtml;
s=self.rightCol+1;
lineColorOrder++;
if(lineColorOrder>4){
lineColorOrder=1;
}
break;
}else{
eacheventHtml+=TdEmptyHtml;
}
}
//6.4拿到本行最大的rightCol值画最后的td
if(s > Math.max.apply(null,RightColArray)){
for(var m=0;m<(lastDay-s+1);m++){
eacheventHtml+=TdEmptyHtml;
}
}
}
}
if(trColorCount>4){
trColorCount=1;
}
eventsHtml+='<tr class="line-color-'+trColorCount+'"><td class="guide-first-col"></td>'+eacheventHtml+'<td class="guide-last-col"></td></tr>';
trColorCount++;
});
var rowHtml='<div class="guide-row">'
+'<div class="guide-bg">'
+'<table>'
+'<tbody>'
+'<tr>'
+bghtml
+'</tr>'
+'</tbody>'
+'</table>'
+'</div>'
+'<div class="guide-event-content">'
+'<table>'
+'<tbody>'
+eventsHtml
+'</tbody>'
+'</table>'
+'</div>'
+'</div>';
$grid.append(rowHtml);
})
}else{
$grid.append('<div style="border:1px solid #E6E6E6;color:#FF2200;text-align:center;padding:10px 0;">'
+'<table>'
+'<tbody>'
+'<tr>'
+'<td class="guide-first-col"></td>'
+'<td colspan="31" style="color:#FF2200;">没有更多数据...</td>'
+'<td class="guide-last-col"></td>'
+'</tr>'
+'</tbody>'
+'<table>'
+'</div>');
}
}