<!DOCTYPE html>
<html lang="ch">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#app {
margin: 12px;
}
.month-box {
display: flex;
justify-content: space-between;
align-items: center;
background: darkolivegreen;
border-radius: 2px;
}
.month-cell {
width: 8.3333%;
height: 32px;
display: flex;
justify-content: center;
align-items: center;
}
.task-box {
margin-bottom: 24px;
border: 1px dotted yellowgreen;
border-radius: 5px;
position: relative;
z-index: 3;
}
.task-row {
width: 100%;
height: 1px;
position: absolute;
top: 0;
z-index: 5;
background: grey;
}
.task-cell {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 12px;
cursor: pointer;
border: 1px solid grey;
border-radius: 3px;
position: absolute;
left: 0;
top: 0;
z-index: 10;
transition: all .5s ease .2s;
}
.text-test {
width: 600px;
height: 200px;
}
</style>
</head>
<body>
<div id="app">
<div class="month-box" :style="{width: 12 * cellWidth + 'px'}">
<span class="month-cell">1 月</span>
<span class="month-cell">2 月</span>
<span class="month-cell">3 月</span>
<span class="month-cell">4 月</span>
<span class="month-cell">5 月</span>
<span class="month-cell">6 月</span>
<span class="month-cell">7 月</span>
<span class="month-cell">8 月</span>
<span class="month-cell">9 月</span>
<span class="month-cell">10 月</span>
<span class="month-cell">11 月</span>
<span class="month-cell">12 月</span>
</div>
<div class="task-box" :style="{width: 12 * cellWidth + 'px', height: rows * cellHeight + 'px'}">
<div class="task-row" v-for="row in rows" :key="row" :style="{top: row * cellHeight - 1 + 'px'}"></div>
<div class="task-cell" v-for="(item, index) in taskList" :key="index" @click="showDetail(item)"
:style="{width: cellWidth * (item.end - item.start + 1) + 'px', height: cellHeight + 'px', left: item.style.left + 'px', top: item.style.top + 'px', background: `linear-gradient(to right, ${randomColor(0.2)}, ${randomColor(0.2)})`}">
<p>{{item.start}} - {{item.end}}</p>
</div>
</div>
<textarea class="text-test" resize="none"></textarea>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.13/vue.min.js"></script>
<script>
let cellWidth = 128,
cellHeight = 54
/*
const taskList = [
{
name: '1-2',
start: 1,
end: 2,
style: {}
}, {
name: '1-2',
start: 1,
end: 2,
style: {}
}, {
name: '3-5',
start: 3,
end: 5,
style: {}
}, {
name: '6-7',
start: 6,
end: 7,
style: {}
}, {
name: '4-4',
start: 4,
end: 4,
style: {}
}, {
name: '2-11',
start: 2,
end: 11,
style: {}
}, {
name: '1-5',
start: 1,
end: 5,
style: {}
}, {
name: '8-11',
start: 8,
end: 11,
style: {}
}, {
name: '3-5',
start: 3,
end: 5,
style: {}
}, {
name: '1-1',
start: 1,
end: 1,
style: {}
}, {
name: '7-12',
start: 7,
end: 12,
style: {}
}, {
name: '3-7',
start: 3,
end: 7,
style: {}
}, {
name: '12-12',
start: 12,
end: 12,
style: {}
}, {
name: '6-6',
start: 6,
end: 6,
style: {}
}]
*/
const num = randomNum(8, 12),
taskList = []
for (let i = 0; i < num; i++) {
let start = randomNum(1, 12), end = randomNum(1, 12)
taskList.push({
name: `${Math.min(start, end)}-${Math.max(start, end)}`,
start: Math.min(start, end),
end: Math.max(start, end),
style: {}
})
}
function createArr(len = 1, val = 0) {
let res = Object.prototype.toString.call(val), value = val
/* if (res === '[object Object]') {
value = { ...val }
} else if (res === '[object Array]') {
value = [...val]
}
value = JSON.parse(JSON.stringify(value)) */
const arr = []
for (let i = 0; i < len; i++) {
arr.push(value)
}
return arr
}
function createSectionArr(start, end) {
if (start === end) {
return [start]
}
const arr = []
for (let i = start; i <= end; i++) {
arr.push(i)
}
return arr
}
console.log(taskList)
const hashMonthData = {},
hashStartMonthData = {}
taskList.forEach((item, index) => {
const { start, end } = item
for (let i = start; i <= end; i++) {
if (!hashMonthData[i]) {
hashMonthData[i] = 1
} else {
hashMonthData[i]++
}
}
if (!hashStartMonthData[start]) {
hashStartMonthData[start] = [item]
} else {
hashStartMonthData[start].push(item)
}
})
console.log(hashMonthData)
console.log(hashStartMonthData)
const rows = Math.max(...Object.values(hashMonthData))
console.log('rows: ', rows)
// const taskPhoto = createArr(rows, createArr(12, 0))
const taskPhoto = []
for (let i = 0; i < rows; i++) {
taskPhoto.push(createArr(12, 0))
}
console.log('taskPhoto: ', taskPhoto)
for (const key in hashStartMonthData) {
const arr = hashStartMonthData[key]
// console.log(`起始月${key}月 arr: `, arr)
// 1月
if (key === '1') {
console.log('一月!!!')
console.log('arr.length: ', arr.length)
arr.forEach((item, index) => {
// console.log('index: ', index)
item.style = {
left: (key - 1) * cellWidth,
top: index * cellHeight
}
const { start, end } = item
console.log(`${start} - ${end}`)
const spliceArr = createSectionArr(start, end)
console.log(spliceArr)
taskPhoto[index].splice(0 /* 月份 - 1 */, spliceArr.length, ...spliceArr)
// console.log('��������������', JSON.parse(JSON.stringify(taskPhoto)))
})
} else {
console.log(`${key} 月!!!`)
console.log('arr.length: ', arr.length)
arr.forEach((item, index) => {
// console.log('index: ', index)
const { start, end } = item
console.log(`${start} - ${end}`)
const spliceArr = createSectionArr(start, end)
console.log(spliceArr)
// taskPhoto[index].splice(0, spliceArr.length, ...spliceArr)
isEmpty(key - 1 /* 月份 - 1 */, spliceArr, item)
})
}
}
console.log('taskPhoth: ', taskPhoto)
function isEmpty(month, spliceArr, item) {
for (let i = 0; i < rows; i++) {
// console.log('i: ', i)
if (taskPhoto[i][month] === 0) {
console.log(`第 ${i} 行,${month + 1} 月为空!`)
item.style = {
left: month * cellWidth,
top: i * cellHeight
}
taskPhoto[i].splice(month, spliceArr.length, ...spliceArr)
return false
}
}
}
function randomNum(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
function randomColor(alpha = 0.5) {
return `rgba(${this.randomNum(0, 128)}, ${this.randomNum(0, 128)}, ${this.randomNum(0, 128)}, ${alpha})`
}
// vue
const app = new Vue({
el: '#app',
data: {
cellWidth,
cellHeight,
taskList,
rows
},
methods: {
randomNum,
randomColor,
showDetail(item) {
const info = JSON.parse(JSON.stringify(item))
delete info.style
// alert(JSON.stringify(info))
this.copyTxt(JSON.stringify(info))
},
copyTxt(txt) {
const cInput = document.createElement('input')
cInput.value = txt
// cInput.style.width = 0
// cInput.style.height = 0
document.body.appendChild(cInput)
cInput.select()
document.execCommand('Copy')
cInput.remove()
}
}
})
</script>
</body>
</html>