ガントチャートをVue.jsで作成し、オブジェクトのタスクデータを時間単位でプロットしたいです。(positionのleftによる位置決め)
[現状です。]
領域
左側 | 右側 |
---|---|
タスク | 時間を帯で表したもの |
[現状]
左側
(今回は問題点としておりません。)
同名のタスクが行で表示されています。
右側
日にちの差分で帯を描画しております。こちらを時間の差分での描画で達成したいです。
課題と対策
[右側]
(質問内容はこちらです)
時間での描画になっていないこと。
対策としましては、フォーマットに時間や分を判別できるようなオブジェクトを作成することと考えています。
カレンダーの作成はgetDaysとgetCarendarで作成されたオブジェクトでできています。
このオブジェクトにブロックのサイズをループしております。この単位を時間の単位にする、もしくは時間の単位になる新たなブロックで(現在は一日の単位)達成できないでしょうか。
実現したいこと
時間単位,もしくは分単位での描画です。
分単位でフォーマットが作成できれば実現できるのではと考えております。
環境
windows 10/mac os 10 どちらもあります。
front/Vue.js(Vue2)
- moment.js
- axios
- tailwind css
以下コードとなります。
テンプレート部分は行数制限のため省かせていただきました。
お分かりになられる方がいらっしゃいましたらご教授お願い致します。
よろしくお願いします。
JavaScript
1// Calendar.vue 2 3<script> 4import axios from 'axios' 5import * as moment from 'moment' 6import 'moment/locale/ja' 7 8export default { 9 data(){ 10 return { 11 tasks: [ 12 { 13 // 3時間 => 3 14 user_id:100, 15 order_name: 'AAAAAAAAAAAAAA', 16 order_code:'1i191o1i1j19', 17 start_date: '2020-01-06 9:30', 18 end_date: '2020-01-06 12:30', 19 }, 20 { 21 // 5時間 => 5 22 user_id:100, 23 order_name: 'AAAAAAAAAAAAAA', 24 order_code:'1i191o1i1j19', 25 start_date: '2020-01-06 13:30', 26 end_date: '2020-01-06 18:30', 27 }, 28 { 29 // 9時間 => 9 30 user_id:100, 31 order_name: 'BBBBBBBBBBBB', 32 order_code:'1hashiahih', 33 start_date: '2020-01-07 9:30', 34 end_date: '2020-01-07 18:30', 35 }, 36 { 37 // 6時間 => 6 38 user_id:100, 39 order_name: 'BBBBBBBBBBBB', 40 order_code:'1hashiahih', 41 start_date: '2020-01-08 09:30', 42 end_date: '2020-01-08 15:30', 43 }, 44 { 45 // 3時間 => 3 46 user_id:100, 47 order_name: 'AAAAAAAAAAAAAA', 48 order_code:'1i191o1i1j19', 49 start_date: '2020-01-08 15:30', 50 end_date: '2020-01-08 18:30', 51 }, 52 { 53 //3時間 => 3 54 user_id:100, 55 order_name: 'AAAAAAAAAAAAAA', 56 order_code:'1i191o1i1j19', 57 start_date: '2020-01-09 9:30', 58 end_date: '2020-01-09 12:30', 59 }, 60 { 61 // 2時間 => 2 62 user_id:100, 63 order_name: 'BBBBBBBBBBBB', 64 order_code:'1hashiahih', 65 start_date: '2020-01-09 13:30', 66 end_date: '2020-01-09 15:30', 67 }, 68 { 69 // 3時間 => 3 70 user_id:100, 71 order_name: 'AAAAAAAAAAAAAA', 72 order_code:'1i191o1i1j19', 73 start_date: '2020-01-09 9:30', 74 end_date: '2020-01-09 18:30', 75 } 76 ] 77 78 } 79 }, 80 computed: { 81 // カレンダーのwidthをもとめる 82 calendarViewWidth() { 83 return this.inner_width - this.task_width; 84 }, 85 // カレンダーのheihtを求める 86 calendarViewHeight () { 87 // 上部のheaderとタスク領域の高さを差し引く 88 return this.inner_height - this.task_height -48; 89 }, 90 displayTasks() { 91 let display_task_number = Math.floor(this.calendarViewHeight / 40); 92 // console.log('display', this.lists.slice(this.position_id, this.position_id + display_task_number)) 93 return this.lists.slice(this.position_id, this.position_id + display_task_number) 94 }, 95 lists() { 96 let lists = []; 97 this.tasks.map(task => { 98 if (task.user_id) { 99 lists.push({ 100 cat: 'task', 101 ...task 102 }) 103 } 104 }) 105 106 console.log('computed:lists', lists) 107 return lists; 108 }, 109 taskBars() { 110 let start_date = moment(this.start_month); 111 console.log('start_date', start_date) 112 let top = 10; 113 let left; 114 let between; 115 let start; 116 let style; 117 return this.displayTasks.map(task => { 118 //////// console////// 119 // console.log('taskBars', task) 120 style = {} 121 if (task.order_name || task.order_code) { 122 if(task.cat==='task'){ 123 let date_from = moment(task.start_date); 124 //////// console////// 125 // console.log('date_from', date_from) 126 let date_to = moment(task.end_date); 127 // 日にちの差分 128 // between = date_to.diff(date_from, 'days'); 129 // 時間の差分 130 between = moment.duration(date_to.diff(date_from), 'milliseconds') 131 let hour = Math.floor(between.asHours()) 132 133 134 // start_dateとdate_fromの差分をmiliで表す 135 136 let milisecondsBetween = moment.duration(date_from.diff(start_date), 'millisecond') 137 console.log('milisecondsBetween', milisecondsBetween) 138 139 //////// console////// 140 console.log('between', between) 141 // between++; 142 console.log('hour', hour) 143 start = date_from.diff(start_date, 'days'); 144 console.log('start', start) 145 left = start * this.block_size; 146 // style = { 147 // top: `${top}px`, 148 // left: `${left}px`, 149 // width: `${hour}px`, 150 // } 151 // 4,3,2,1s 152 if (hour >= 9) { 153 style = { 154 top: `${top}px`, 155 left: `${left}px`, 156 width: `${this.block_size}px`, 157 border: `2px solid #FF33CC` 158 } 159 // 4,5,6,7,8 160 } else if(hour > 4 || hour < 9 ) { 161 style = { 162 top: `${top}px`, 163 left: `${left}px`, 164 width: `${this.block_size / 2}px`, 165 'border': `2px solid #3300FF` 166 } 167 // 9,10,11,12 168 } else if (hour < 4){ 169 style = { 170 top: `${top}px`, 171 left: `${left}px`, 172 width: `${this.block_size / 4}px`, 173 'border': `2px solid #3300FF` 174 } 175 } 176 } 177 178 } 179 180 top = top + 40; 181 return { 182 style, 183 task 184 } 185 }) 186 }, 187 scrollDistance() { 188 let start_date = moment(this.start_month) 189 let between_days = this.today.diff(start_date, 'days') 190 return (between_days + 1) * this.block_size - this.calendarViewWidth /2; 191 } 192 }, 193 mounted: function() { 194 console.log('getDays', this.getDays('2020','10',0)) // year, month, number 195 this.getCalendar() 196 this.getWindowSize() 197 window.addEventListener('resize', this.getWindowSize, false) 198 window.addEventListener('wheel', this.windowSizeCheck) 199 // this.$nextTick(() => { 200 // this.todayPosition() 201 // }) 202 // this.getTaskPeriod() 203 this.getMilliseconds() 204 }, 205 methods: { 206 // ミリでのテスト 207 getMilliseconds () { 208 let start = moment('2020/01/06 15:30') 209 let end = moment('2020/01-06 18:30') 210 if (start && end) { 211 let duration = moment.duration(end.diff(start), 'milliseconds') 212 let hour = Math.floor(duration.asHours()) 213 let time = hour + ':' + duration.minutes() + ':' + duration.seconds() 214 console.log('time', time) 215 } 216 }, 217 // async getTaskPeriod () { 218 // try { 219 // // http://localhost:3001/api/get/calendar// 220 // const response = await axios.get('http://localhost:3001/api/get/calendar') 221 // console.log('getTaskPeriod', response.data) 222 // this.tasks = await response.data 223 // console.log('tasks', this.tasks) 224 // } catch(err) { 225 // console.log('err', err) 226 // } 227 // }, 228 async getUsers() { 229 try { 230 const response = await axios.get('http://localhost:3001/users') 231 console.log('getUsers', response.data) 232 this.userId = response.data 233 } catch(err) { 234 console.log(err) 235 } 236 }, 237 // 日付と曜日を持った配列 238 getDays(year, month, block_number) { 239 const dayOfWeek = ['日', '月', '火', '水', '木', '金', '土']; 240 let days = []; 241 let date = moment(`${year}-${month}-01`); 242 // num: 取得した月の日数 243 // date()メソッド:日 244 // year():年 245 // day():曜日 246 // 今日から1日後の日付 247 let num = date.daysInMonth(); 248 for (let i = 0; i < num; i++) { 249 days.push({ 250 day: date.date(), 251 dayOfWeek: dayOfWeek[date.day()], 252 block_number 253 }) 254 date.add(1, 'day'); 255 block_number++; 256 } 257 return days; 258 }, 259 getCalendar() { 260 let block_number = 0; 261 let days; 262 // 始め月 263 let start_month = moment(this.start_month) 264 // 終わり月 265 let end_month = moment(this.end_month) 266 // 月の差分 267 let between_month = end_month.diff(start_month, 'months') 268 // 差分の月の分だけgetDaysを行う 269 for (let i = 0; i <= between_month; i++) { 270 days = this.getDays(start_month.year(), start_month.format('MM'), block_number); 271 this.calendars.push({ 272 date: start_month.format('YYYY年MM月'), 273 year: start_month.year(), 274 month: start_month.month(), //month(), 0,1..11と表示 275 start_block_number: block_number, 276 calendar: days.length, 277 days: days 278 }) 279 start_month.add(1, 'months') 280 block_number = days[days.length - 1].block_number 281 block_number++; 282 } 283 return block_number; 284 } 285 } 286} 287</script> 288 289<style scoped> 290.gantt-height > span { 291 font-size: 8px; 292 color: rgb(194, 35, 133); 293} 294</style> 295
あなたの回答
tips
プレビュー