;(function(global, $) { 'use strict'; $.fn.milchart = function(options){ const BAR_PADDING = 10, //barのpadding DRAGGING_TIME = 150, //150ms以上のmousedownで、drag判定。それ以外はclick判定。ダブルクリックが硬いときは値を大きくする CLICK_SPAN = 200, //200ms以下の間隔で連続クリックした場合、doubleclick判定。それ以外はclick判定 AUTO_SCROLLING_MARGIN = 50, //auto_scroll開始位置。左右の端からドラッグした場合。 [xx] px; LEFT_TITLE_WIDTH = 150, //左端のタイトルCELLの幅 CHART_WINDOWS_NAME = '.milchart_window', //チャートが含まれるwindowクラス、or window ID STICKY_TABLE_NAME = '.sticky_table', //sticky_tableのクラス、or window ID TARGET_MODAL_CONTENT = 'modal_content'; //変更しなくてよい var defaults = { gtdata : "", ctrl_script : "", }, setting = $.extend(defaults, options), is_drag_new_bar, is_drag_move_bar, is_drag_move_grabpoint, scrolling, cell_w, cell_h, vname_w, vname_h, sticky_header, bar_padding, dragging_time, click_span, auto_scrolling_margin, left_title_w, chart_window, sticky_table, target_modal_content, _selected_arr = [], selected_arr = [], timer_id = null, $target = $(this), $target_table = $(this).find('table.chart_table'), $target_td = $(this).find('td'), target_area_width, target_area_height, target_area_left, target_area_top, target_table_w, target_table_h, move_block_count, left_max_date, right_max_date, fp, /*============================================================================================* * * ■ server * * ・ctrl * ・ * *============================================================================================*/ server = { ctrl : function(ctrl_type, data) { //validation if ( !( ctrl_type === 'get_modal_content' || ctrl_type === 'create' || ctrl_type === 'update' || ctrl_type === 'delete' ) ) { return false; } var send_data = { "ctrl_type" : ctrl_type, "bar_id" : data.bar_id, "start_date" : data.start_date, "end_date" : data.end_date, "id" : data.plan_id, "vid" : data.vid, "class" : data.plan_class, "title" : data.plan_title, "bikou" : data.plan_bikou, }; $.each(send_data,function(key,value){ if (typeof value == 'undefined') { send_data[key] = ''; } }); $.ajax({ type: "POST", url : setting.ctrl_script, data: send_data, }).done(function (result) { if (ctrl_type === 'get_modal_content') { $('#' + target_modal_content).html(result); //buttonイベントとcloseイベント追加 add_event.add_event_overlay(); } else { if (result !== 'false') { if (ctrl_type === 'create' || ctrl_type === 'update') { /*----------------------------------* * selected_arrを作成 *----------------------------------*/ selected_arr = util.get_consecutive_date_arr(data.start_date,data.end_date); /*----------------------------------* * barをselected_arrから新規作成 *----------------------------------*/ add_dom.add_bar(data.bar_id, selected_arr, data.vid, data.plan_id, data.plan_class, data.plan_title); /*----------------------------------* * grabpointを追加 *----------------------------------*/ add_dom.add_grabpoint(data.bar_id); if (ctrl_type === 'create') { $('.bar[data-bar_id="' + data.bar_id + '"]').attr('data-plan_id',result); $('.delete_point[data-bar_id="' + data.bar_id + '"]').remove(); } /*----------------------------------* * モーダルから更新でalert表示 *----------------------------------*/ if (typeof data.modal != 'undefined') { alert("データを更新しました。"); } } else if (ctrl_type === 'delete') { $('.bar[data-bar_id="' + data.bar_id + '"]').remove(); alert("データを削除しました。"); } $('.overlay').remove(); setTimeout(function() { $.each(fp,function(k,v){ fp[k].destroy();//flatpickr削除 }); }, 1000); } else { if (data.plan_id !== '') { alert("データ更新に失敗しました。"); } } } }).fail(function () { }).always(function () { }); }, }, /*============================================================================================* * * ■ add_event * * ・init * ・set_event_grabpoint * ・set_event_move_bar * ・set_event_create_bar * ・ * *============================================================================================*/ add_event = { /*--------------------------* * init *--------------------------*/ init : function() { add_event.reset(); is_drag_new_bar = false, is_drag_move_bar = false, is_drag_move_grabpoint = false, scrolling = false, move_block_count = 0, bar_padding = BAR_PADDING, dragging_time = DRAGGING_TIME, click_span = CLICK_SPAN, auto_scrolling_margin = AUTO_SCROLLING_MARGIN, left_title_w = LEFT_TITLE_WIDTH, chart_window = CHART_WINDOWS_NAME, sticky_table = STICKY_TABLE_NAME, target_modal_content = TARGET_MODAL_CONTENT; target_table_w = $target_table.outerWidth(); target_table_h = $target_table.outerHeight(); $(".viewport").css("width",target_table_w + 'px'); $(".viewport").css("height",target_table_h + 'px'); add_dom.add_initial_data(setting.gtdata);//DBのデータをチャート上へ呼び出し add_event.set_event_create_bar(); add_event.set_event_move_bar(); add_event.set_event_grabpoint(); add_event.set_event_auto_scroll(); util.scroll_window(); }, /*--------------------------* * reset * windowサイズを変更した場合 *--------------------------*/ reset : function() { cell_w = $target_table.find('td').first().outerWidth(), cell_h = $target_table.find('td').first().outerHeight(), vname_w = $('.data_vid th').first().outerWidth(), vname_h = $('.data_vid th').first().outerHeight(), sticky_header = $(sticky_table).find('thead').outerHeight(), target_area_width = $target.outerWidth(), target_area_height = $target.outerHeight(), //ブラウザスクロールの影響は受けないが、インラインフレームのスクロール量の影響を受ける target_area_left = $target.offset().left, target_area_top = $target.offset().top, left_max_date = $($target_table.find('td')[0]).attr('data-date'), right_max_date = $target_table.find('td:last').attr('data-date'); }, /*----------------------------------------* * * set_event_grabpoint * * grabpointをクリックした際のイベント * * *----------------------------------------*/ set_event_grabpoint : function() { var clicks = 0, bar_id = '', clickdowntime = 0, click_pos_x = 0, click_pos_y = 0, move_x = 0, start_grabpoint_x = 0, start_grabpoint_y = 0, start_bar_x = 0, start_bar_y = 0, grabpoint_size_offset = 0, grabpoint_horizontal = '', move_grabpoint_block_count = 0, bar_w = 0, bar_h = 0, bar_left_position = '', bar_right_position = '', $bar_obj = {}, vid = '', start_date = '', end_date = '', plan_title = '', plan_id = '', plan_class = '', selected_arr = []; $(document).on({ 'mousedown' : function(e) { /*-------------------------------* * grabpointの中心から端までの距離 *-------------------------------*/ grabpoint_size_offset = $(this).outerWidth() / 2; /*-------------------------------* * 動かそうとしているbarのID *-------------------------------*/ bar_id = $(this).attr('data-bar_id'); /*-------------------------------* * barのオブジェクト *-------------------------------*/ $bar_obj = $('.bar[data-bar_id=' + bar_id + ']'); /*-------------------------------* * barのvid *-------------------------------*/ vid = $bar_obj.attr('data-vid'); /*-------------------------------* * barのtitle *-------------------------------*/ plan_title = $bar_obj.attr('title'); /*-------------------------------* * barのpid *-------------------------------*/ plan_id = $bar_obj.attr('data-plan_id'); /*-------------------------------* * barのclass *-------------------------------*/ plan_class = $bar_obj.attr('data-plan_class'); /*-------------------------------* * barのstart_date *-------------------------------*/ start_date = $bar_obj.attr('data-start_date'); /*-------------------------------* * barのend_date *-------------------------------*/ end_date = $bar_obj.attr('data-end_date'); /*-------------------------------* * クリック開始時間 *-------------------------------*/ clickdowntime = new Date().getTime(); /*-------------------------------* * grabpointドラッグフラグを立てる *-------------------------------*/ is_drag_move_grabpoint = true; /*-------------------------------* * barの X,Y 起点位置 *-------------------------------*/ start_bar_x = $bar_obj.position().left; start_bar_y = $bar_obj.position().top; /*-------------------------------* * grabpointの X,Y 起点位置 *-------------------------------*/ start_grabpoint_x = $(this).position().left; start_grabpoint_y = $(this).position().top; /*-------------------------------* * grabpointの horizontal *-------------------------------*/ grabpoint_horizontal = $(this).attr("data-horizontal"); /*-------------------------------* * クリックしたカーソルの位置を保存 *-------------------------------*/ click_pos_x = e.clientX; click_pos_y = e.clientY; /*------------------------------------------* * 左右へ移動したcellのブロック数(距離) *------------------------------------------*/ move_grabpoint_block_count = 0; /*-------------------------------* * barの幅と高さ *-------------------------------*/ bar_w = $bar_obj.outerWidth(); bar_h = $bar_obj.outerHeight(); /*----------------------------------* * z-index再設定 *----------------------------------*/ $bar_obj.css('z-index','20'); }, 'mouseup' : function(e) { /*----------------------------------* * キャンセル処理 *----------------------------------*/ if (!is_drag_move_grabpoint) { return ; } /*----------------------------------* * grabpoint移動フラグを下げる *----------------------------------*/ is_drag_move_grabpoint = false; /*----------------------------------* * クリックアップ時刻を計測 *----------------------------------*/ var clickuptime = new Date().getTime(); // ★click up if (clickuptime - clickdowntime < dragging_time) { clicks++; if (clicks == 1) { setTimeout(function(){ //single if(clicks == 1) { //double } else { /*----------------------------------* * ほかの行の選択テキストを解除 *----------------------------------*/ window.getSelection().removeAllRanges(); } clicks = 0; }, click_span, $(this)); } // ★drag up } else { /*----------------------------------* * barとgrabpointを移動 *----------------------------------*/ var date_type = false; if (grabpoint_horizontal === 'right') { end_date = util.get_count_up_date(end_date,move_grabpoint_block_count,date_type); } else if ( grabpoint_horizontal === 'left') { start_date = util.get_count_up_date(start_date,move_grabpoint_block_count,date_type); } /*----------------------------------* * 新しい配列を作成 *----------------------------------*/ selected_arr = util.get_consecutive_date_arr(start_date, end_date); /*----------------------------------* * barをselected_arrから新規作成 *----------------------------------*/ add_dom.add_bar(bar_id,selected_arr,vid,plan_id,plan_class,plan_title); /*----------------------------------* * grabpointを追加 *----------------------------------*/ add_dom.add_grabpoint(bar_id); /*----------------------------------* * z-index再設定 *----------------------------------*/ $bar_obj.css('z-index','10');//戻す /*----------------------------------* * データベースに保存 *----------------------------------*/ var ctrl_type = 'update', data = { "bar_id" : bar_id, "vid" : vid, "plan_id" : plan_id, "plan_class" : plan_class, "plan_title" : plan_title, "start_date" : selected_arr[0], "end_date" : selected_arr.slice(-1)[0], }; server.ctrl(ctrl_type, data); /*----------------------------------* * 配列をリセット *----------------------------------*/ selected_arr = []; } }, 'mousemove' : function(e) { if (is_drag_move_grabpoint) { /*------------------------------------------* * 左右へ移動したgrabpointのpx(距離) *------------------------------------------*/ move_x = e.clientX - click_pos_x; /*----------------------------------* * grabpointを移動 *----------------------------------*/ $(this).css('left', start_grabpoint_x + move_x + $target.scrollLeft() + 'px'); /*----------------------------------* * barを伸縮 *----------------------------------*/ var new_barwidth; if ( grabpoint_horizontal === 'right') { new_barwidth = bar_w + move_x; } else if ( grabpoint_horizontal === 'left') { new_barwidth = bar_w - move_x; $bar_obj.css( 'left', (start_bar_x + move_x) + $target.scrollLeft() + 'px') } $bar_obj.css( 'width', new_barwidth + 'px') /*------------------------------------------* * 左右へ移動したcellのブロック数(距離) *------------------------------------------*/ move_grabpoint_block_count = Math.round( move_x / (cell_w) ); /*------------------------------------------* * delete_pointの移動 *------------------------------------------*/ add_dom.add_delete_point(bar_id); } }, 'mouseleave': function(e) { if (is_drag_move_grabpoint) { /*----------------------------------* * grabpoint移動フラグを下げる *----------------------------------*/ is_drag_move_grabpoint = false; /*----------------------------------* * barとgrabpointを移動 *----------------------------------*/ var date_type = false; if (grabpoint_horizontal === 'right') { end_date = util.get_count_up_date(end_date,move_grabpoint_block_count,date_type); } else if ( grabpoint_horizontal === 'left') { start_date = util.get_count_up_date(start_date,move_grabpoint_block_count,date_type); } /*----------------------------------* * 新しい配列を作成 *----------------------------------*/ selected_arr = util.get_consecutive_date_arr(start_date, end_date); /*----------------------------------* * barをselected_arrから新規作成 *----------------------------------*/ add_dom.add_bar(bar_id,selected_arr,vid,plan_id,plan_class,plan_title); /*----------------------------------* * grabpointを追加 *----------------------------------*/ add_dom.add_grabpoint(bar_id); /*----------------------------------* * z-index再設定 *----------------------------------*/ $bar_obj.css('z-index','10');//戻す /*----------------------------------* * データベースに保存 *----------------------------------*/ var ctrl_type = 'update', data = { "bar_id" : bar_id, "vid" : vid, "plan_id" : plan_id, "plan_class" : plan_class, "plan_title" : plan_title, "start_date" : selected_arr[0], "end_date" : selected_arr.slice(-1)[0], }; server.ctrl(ctrl_type, data); /*----------------------------------* * 配列をリセット *----------------------------------*/ selected_arr = []; /*----------------------------------* * ほかの行の選択テキストを解除 *----------------------------------*/ window.getSelection().removeAllRanges(); } }, },".grabpoint"); }, /*----------------------------------------* * * set_event_create_bar * * 新しくbarを作る場合 * * *----------------------------------------*/ set_event_create_bar : function() { var vid = ''; $target_td.on({ 'mousedown' : function(e) { /*----------------------------------* * フラグ *----------------------------------*/ if (is_drag_new_bar) { util.reset_create_bar(); } /*----------------------------------* * vid取得 *----------------------------------*/ vid = $(this).attr('data-vid'); /*----------------------------------* * cellデータ取得 *----------------------------------*/ var date = $(this).attr('data-date'); /*--------------------------------------------* * date,vidが取得できなかったらキャンセル *--------------------------------------------*/ if ( (typeof date == 'undefined' || date == '') || (typeof vid == 'undefined' || vid == '') ) { util.reset_create_bar(); } /*--------------------------------------------* * padding外をクリックした際はキャンセル *--------------------------------------------*/ if ( !( ( (e.offsetX > (bar_padding / 2)) && (e.offsetX < cell_w - (bar_padding / 2)) ) && ( (e.offsetY > (bar_padding / 2)) && (e.offsetY < cell_h - (bar_padding / 2)) ) ) ) { util.reset_create_bar(); return false; } is_drag_new_bar = true; }, 'mouseup' : function(e) { if (is_drag_new_bar){ /*----------------------------------* * validation *----------------------------------*/ if (selected_arr.length === 0) { util.reset_create_bar(); return false; } /*----------------------------------* * barをdomに追加 *----------------------------------*/ var new_bar_id = util.get_unique_number(); add_dom.add_bar(new_bar_id, selected_arr, vid); /*----------------------------------* * drag終了 *----------------------------------*/ clearInterval(timer_id); scrolling = false; util.reset_create_bar(); return false; } }, 'mousemove' : function(e) { if (is_drag_new_bar) { /*----------------------------------* * cellデータ取得 *----------------------------------*/ var obj = document.elementFromPoint(e.pageX - window.scrollX, e.pageY - window.scrollY ), date = $(obj).attr('data-date'); /*--------------------------------------------* * date,vidが取得できなかったらキャンセル *--------------------------------------------*/ if ( (typeof date == 'undefined' || date == '') ) { util.reset_create_bar(); } /*--------------------------------------------* * 行を固定 *--------------------------------------------*/ var this_vid = $(obj).attr('data-vid'); if ( typeof this_vid == 'undefined' || this_vid == '' ) { util.reset_create_bar(); return false; } if (vid !== this_vid) { return false; } /*----------------------------------* * idを配列に格納 *----------------------------------*/ _selected_arr.push(date); selected_arr = util.push_id(_selected_arr, vid, date); } }, }); }, /*----------------------------------------* * * set_event_move_bar * * barをクリックした際のイベント * * *----------------------------------------*/ set_event_move_bar : function() { var clicks = 0, clickdowntime = 0, start_bar_x = 0, start_bar_y = 0, move_x = 0, click_pos_x = 0, click_pos_y = 0, bar_id = '', bar_left_position = '', bar_right_position = '', $bar_obj = {}, vid = '', plan_title = '', plan_id = '', plan_class = '', default_selected_arr, selected_arr = []; $(document).on({ 'mousedown' : function(e) { /*-------------------------------* * barのdata-id *-------------------------------*/ bar_id = $(this).attr('data-bar_id'); /*-------------------------------* * barのvid *-------------------------------*/ vid = $(this).attr('data-vid'); /*-------------------------------* * barのtitle *-------------------------------*/ plan_title = $(this).attr('title'); /*-------------------------------* * barのpid *-------------------------------*/ plan_id = $(this).attr('data-plan_id'); /*-------------------------------* * barのclass *-------------------------------*/ plan_class = $(this).attr('data-plan_class'); /*-------------------------------* * selected_arrを取得 *-------------------------------*/ selected_arr = util.get_consecutive_date_arr($(this).attr('data-start_date'), $(this).attr('data-end_date')); if ( !selected_arr ) { is_drag_move_bar = false; $('.bar').removeClass('selected'); $('.grabpoint').remove(); $(this).css('z-index','10'); selected_arr = []; return false; } /*-------------------------------* * クリック開始時間 *-------------------------------*/ clickdowntime = new Date().getTime(); /*-------------------------------* * barドラッグフラグを立てる *-------------------------------*/ is_drag_move_bar = true; /*-------------------------------* * barの X,Y 起点位置 *-------------------------------*/ start_bar_x = $(this).position().left; start_bar_y = $(this).position().top; /*-------------------------------* * クリックしたカーソルの位置を保存 *-------------------------------*/ click_pos_x = e.clientX; click_pos_y = e.clientY; /*------------------------------------------* * 左右へ移動したbarのpx(距離) *------------------------------------------*/ move_x = 0; /*----------------------------------* * z-index再設定 *----------------------------------*/ $(this).css('z-index','20'); /*----------------------------------* * barの右端と左端の位置 *----------------------------------*/ bar_left_position = parseInt($(this).css('left'),10); bar_right_position = parseInt($(this).css('left'),10) + (selected_arr.length * cell_w - (bar_padding)); /*----------------------------------* * 動かす前に最初の配列を保存 *----------------------------------*/ default_selected_arr = selected_arr; }, 'mousemove' : function(e) { if (is_drag_move_bar) { if ( $(this).hasClass('selected') ) { /*----------------------------------* * validation *----------------------------------*/ //移動量 move_x = e.clientX - click_pos_x; //動かしたブロック数 move_block_count = Math.round( move_x / cell_w ); /*-------------------------------* * selected_arrを取得 *-------------------------------*/ selected_arr = util.get_after_move_date_arr(bar_id, move_block_count); /*----------------------------------* * validation *----------------------------------*/ if ( !selected_arr ) { is_drag_move_bar = false; $('.bar').removeClass('selected'); $('.grabpoint').remove(); $(this).css('z-index','10'); selected_arr = []; return false; } /*----------------------------------* * barとgrabpointを移動 *----------------------------------*/ $(this).css('left', start_bar_x + move_x + 'px'); $('.grabpoint[data-bar_id="' + bar_id + '"][data-horizontal="left"]').css('left', bar_left_position + move_x + 'px'); $('.grabpoint[data-bar_id="' + bar_id + '"][data-horizontal="right"]').css('left', bar_right_position + move_x + 'px'); /*------------------------------------------* * delete_pointの移動 *------------------------------------------*/ add_dom.add_delete_point(bar_id); } } }, 'mouseup' : function(e) { /*----------------------------------* * キャンセル処理 *----------------------------------*/ if (!is_drag_move_bar) { return ; } /*----------------------------------* * bar移動フラグを下げる *----------------------------------*/ is_drag_move_bar = false; /*----------------------------------* * クリックアップ時刻を計測 *----------------------------------*/ var clickuptime = new Date().getTime(), $this_obj = $(this); // ★click up if (clickuptime - clickdowntime < dragging_time) { clicks++; if (clicks == 1) { setTimeout(function(){ //single if(clicks == 1) { if ( !$this_obj.hasClass('selected') ) { /*-------------------------------* * validation *-------------------------------*/ if ( !selected_arr ) { is_drag_move_bar = false; $('.bar').removeClass('selected'); $('.grabpoint').remove(); $(this).css('z-index','10'); selected_arr = []; return false; } /*-------------------------------* * grabpointを新規で作成 *-------------------------------*/ add_dom.add_grabpoint(bar_id); /*----------------------------------* * 配列をリセット *----------------------------------*/ selected_arr = []; } //double } else { add_dom.add_overlay(bar_id,plan_id); /*----------------------------------* * ほかの行の選択テキストを解除 *----------------------------------*/ window.getSelection().removeAllRanges(); } clicks = 0; }, click_span, $this_obj); } // ★drag up } else { /*----------------------------------* * validation *----------------------------------*/ if (bar_id != $(this).attr('data-bar_id')) { return ; } if ( !selected_arr ) { is_drag_move_bar = false; $('.bar').removeClass('selected'); $('.grabpoint').remove(); $(this).css('z-index','10'); selected_arr = []; return false; } /*----------------------------------* * z-index再設定 *----------------------------------*/ $(this).css('z-index','10');//戻す /*----------------------------------* * barをselected_arrから新規作成 *----------------------------------*/ add_dom.add_bar(bar_id, selected_arr, vid, plan_id, plan_class, plan_title); /*----------------------------------* * grabpointを追加 *----------------------------------*/ add_dom.add_grabpoint(bar_id); /*----------------------------------* * データベースに保存★ *----------------------------------*/ var ctrl_type = 'update', data = { "bar_id" : bar_id, "vid" : vid, "plan_id" : plan_id, "plan_class" : plan_class, "plan_title" : plan_title, "start_date" : selected_arr[0], "end_date" : selected_arr.slice(-1)[0], }; server.ctrl(ctrl_type, data); /*----------------------------------* * 移動数をリセット *----------------------------------*/ move_block_count = 0 /*----------------------------------* * 配列をリセット *----------------------------------*/ selected_arr = []; } }, 'mouseleave' : function(e) { if (is_drag_move_bar) { /*----------------------------------* * bar移動フラグを下げる *----------------------------------*/ is_drag_move_bar = false; /*----------------------------------* * validation *----------------------------------*/ if (bar_id != $(this).attr('data-bar_id')) { return ; } if ( !selected_arr ) { is_drag_move_bar = false; $('.bar').removeClass('selected'); $('.grabpoint').remove(); $(this).css('z-index','10'); selected_arr = []; return false; } /*----------------------------------* * z-index再設定 *----------------------------------*/ $(this).css('z-index','10');//戻す /*----------------------------------* * barをselected_arrから新規作成 *----------------------------------*/ add_dom.add_bar(bar_id, selected_arr, vid, plan_id, plan_class, plan_title); /*----------------------------------* * grabpointを追加 *----------------------------------*/ add_dom.add_grabpoint(bar_id); /*----------------------------------* * データベースに保存★ *----------------------------------*/ var ctrl_type = 'update', data = { "bar_id" : bar_id, "vid" : vid, "plan_id" : plan_id, "plan_class" : plan_class, "plan_title" : plan_title, "start_date" : selected_arr[0], "end_date" : selected_arr.slice(-1)[0], }; server.ctrl(ctrl_type, data); /*----------------------------------* * 配列をリセット *----------------------------------*/ selected_arr = []; /*----------------------------------* * 移動数をリセット *----------------------------------*/ move_block_count = 0 /*----------------------------------* * ほかの行の選択テキストを解除 *----------------------------------*/ window.getSelection().removeAllRanges(); } }, },'.bar'); }, /*----------------------------------------* * * set_event_auto_scroll * * tableの端からauto_scrolling_marginにonmouse * で自動スクロールする * *----------------------------------------*/ set_event_auto_scroll : function() { var vid = '', amount_x = 0, amount_y = 0, scrolling = false, bottom_max = $target_table.height(), time = 50; $target.on({ 'mousedown' : function(e) { amount_x = $(chart_window).scrollLeft(); }, 'mouseup' : function(e) { clearInterval(timer_id); scrolling = false; }, 'mousemove' : function(e) { //右側 if (($(chart_window).outerWidth() + $(chart_window).offset().left) - (e.clientX + window.scrollX) <= auto_scrolling_margin) { if (!scrolling && (is_drag_new_bar || is_drag_move_bar || is_drag_move_grabpoint)) { scrolling = true; timer_id = setInterval(function(){ if ($target_table.width() > amount_x) { amount_x = amount_x + 10; $(chart_window).scrollLeft(amount_x); var obj = document.elementFromPoint(e.pageX - window.scrollX , e.pageY - window.scrollY), date = $(obj).attr('data-date'), vid = $(obj).attr('data-vid'); /*----------------------------------* * validation *----------------------------------*/ if ( (typeof date == 'undefined' || date == '') || (typeof vid == 'undefined' || vid == '') ) { util.reset_create_bar(); return false; } /*----------------------------------* * 行が変わった場合,pushしない *----------------------------------*/ var this_vid = vid; if (vid !== '') { if ( typeof this_vid == 'undefined' || this_vid == '' ) { util.reset_create_bar(); return false; } if (vid !== this_vid) { return false; } } vid = this_vid; /*----------------------------------* * idを配列に格納 *----------------------------------*/ _selected_arr.push(date); selected_arr = util.push_id(_selected_arr, vid, date); } },time); } } else //左側 if ((e.clientX + window.scrollX) - ($(chart_window).offset().left + vname_w) <= auto_scrolling_margin) { if (!scrolling && (is_drag_new_bar || is_drag_move_bar || is_drag_move_grabpoint)) { scrolling = true; timer_id = setInterval(function(){ if (amount_x > 0) { amount_x = amount_x - 10; $(chart_window).scrollLeft(amount_x); var obj = document.elementFromPoint(e.pageX - window.scrollX , e.pageY - window.scrollY), date = $(obj).attr('data-date'), vid = $(obj).attr('data-vid'); /*----------------------------------* * validation *----------------------------------*/ if ( (typeof date == 'undefined' || date == '') || (typeof vid == 'undefined' || vid == '') ) { util.reset_create_bar(); return false; } /*----------------------------------* * 行が変わった場合,pushしない *----------------------------------*/ var this_vid = vid; if (vid !== '') { if ( typeof this_vid == 'undefined' || this_vid == '' ) { util.reset_create_bar(); return false; } if (vid !== this_vid) { return false; } } vid = this_vid; /*----------------------------------* * idを配列に格納 *----------------------------------*/ _selected_arr.push(date); selected_arr = util.push_id(_selected_arr, vid, date); } },time); } } else { clearInterval(timer_id); scrolling = false; } }, 'mouseleave' : function(e) { clearInterval(timer_id); scrolling = false; }, }); }, /*--------------------------* * add_event_delete_point *--------------------------*/ add_event_delete_point : function() { $(".delete_point").off(); $(".delete_point").on("click",function(){ var bar_id = $(this).attr('data-bar_id'); if (window.confirm('削除してもよろしいですか?')) { $(this).remove(); $('.bar[data-bar_id=' + bar_id + ']').remove(); $('.grabpoint[data-bar_id=' + bar_id + ']').remove(); } }); }, /*--------------------------* * add_event_overlay *--------------------------*/ add_event_overlay : function() { //クローズイベント $('.overlay').off(); $('.overlay').on('click', function(e) { if (!$(e.target).closest('.content').length) { $(this).remove(); setTimeout(function() { $.each(fp,function(k,v){ fp[k].destroy();//flatpickr削除 }); }, 1000); } }); //ボタンイベント $('.modal_button').off(); $('.modal_button').on('click', function(e) { var ctrl_type = $(this).attr('data-class'), data = { "bar_id" : $('input[name="bar_id"]').val(), "vid" : $('input[name="vid"]').val(), "plan_id" : $('input[name="id"]').val(), "start_date" : $('input[name="start_date"]').val(), "end_date" : $('input[name="end_date"]').val(), "plan_title" : $('input[name="title"]').val(), "plan_class" : $('select[name="class"]').val(), "plan_bikou" : $('textarea[name="bikou"]').val(), "modal" : 'true', }; server.ctrl(ctrl_type, data); }); add_event.add_event_modal_calendar();//flatpickr追加 }, /*--------------------------* * add_event_modal_calendar *--------------------------*/ add_event_modal_calendar : function() { fp = flatpickr('#modal_content input[name="start_date"],#modal_content input[name="end_date"]', { locale : 'ja', dateFormat : 'Y-m-d' }); }, }, /*============================================================================================* * * ■ add_dom * * ・add_grabpoint * ・add_bar * ・add_initial_data * ・ * *============================================================================================*/ add_dom = { /*--------------------------* * add_overlay *--------------------------*/ add_overlay : function(bar_id,plan_id) { var dom = '
', $obj = $('.bar[data-bar_id="' + bar_id + '"]'), ctrl_type = 'get_modal_content', data = { "bar_id" : bar_id, "vid" : $obj.attr('data-vid'), "plan_id" : $obj.attr('data-plan_id'), "start_date" : $obj.attr('data-start_date'), "end_date" : $obj.attr('data-end_date'), }; //domに追加 $('body').prepend(dom); //overlayに入力項目のコンテンツを追加(非同期で) server.ctrl(ctrl_type, data); }, /*--------------------------* * add_delete_point *--------------------------*/ add_delete_point : function(bar_id) { var obj = $('.bar[data-bar_id="' + bar_id + '"]'), bar_left = parseInt($('.bar[data-bar_id="' + bar_id + '"]').css("left")), bar_top = parseInt($('.bar[data-bar_id="' + bar_id + '"]').css("top")), bar_width = $('.bar[data-bar_id="' + bar_id + '"]').outerWidth(), bar_right = bar_left + bar_width, style = 'left:'+bar_right+'px;top:'+bar_top+'px;', dom = ''; if (obj.attr('data-plan_id') === '') { $('.delete_point[data-bar_id="' + bar_id + '"]').remove(); $target_table.after(dom); } add_event.add_event_delete_point(); }, /*--------------------------* * add_grabpoint *--------------------------*/ add_grabpoint : function(bar_id) { var chartbar_w = 0, chartbar_h = 0, $obj = $('.bar[data-bar_id="' + bar_id + '"]'); /*-------------------------------* * chartbarの幅と高さ *-------------------------------*/ chartbar_w = $obj.outerWidth(); chartbar_h = $obj.outerHeight(); /*-------------------------------* * chartbarにselectedクラスを付加 *-------------------------------*/ $('.bar').removeClass('selected'); $obj.addClass('selected'); /*-------------------------------* * grabpointをいったん全部削除 *-------------------------------*/ $('.grabpoint').remove(); /*-------------------------------* * grabpointを新規で作成 *-------------------------------*/ var g_y = $obj.position().top + (chartbar_h / 2) + $target.scrollTop(); var gl_x = $obj.position().left; var gr_x = $obj.position().left + chartbar_w; var gsl = 'top:'+g_y+'px;left:' + gl_x + 'px;'; var gsr = 'top:'+g_y+'px;left:' + gr_x + 'px;'; var gp_left_html = ''; var gp_right_html = ''; /*-------------------------------* * 既存のgrabpointを削除 *-------------------------------*/ $('.grabpoint').remove(); /*-------------------------------* * DOMを追加 *-------------------------------*/ $target_table.after(gp_left_html); $target_table.after(gp_right_html); }, /*--------------------------* * add_bar *--------------------------*/ add_bar : function(bar_id, arr, vid = '', plan_id = '', plan_class = '', plan_title = '') { var bgcolor = util.get_rgbcolor(plan_class), barw = arr.length * cell_w - bar_padding, barh = cell_h - bar_padding, barposx = '', barposy = '', start_date = arr[0], end_date = arr.slice(-1)[0], $obj = $('.bar[data-bar_id="' + bar_id + '"]'); if (typeof $('td[data-date="' + arr[0] + '"]').position() != 'undefined') { barposx = $('td[data-date="' + arr[0] + '"]').position().left + (bar_padding / 2), barposy = $('[data-vid="' + vid + '"]').position().top + (bar_padding / 2); } else { if (move_block_count != 0) { start_date = left_max_date; var max_date_left_pos = $('td[data-date="' + left_max_date + '"]').position().left, bar_left_pos = parseInt($('.bar[data-bar_id="' + bar_id + '"]').css('left')), left_move_block_count = Math.round((max_date_left_pos - bar_left_pos) / cell_w), _start_date = new Date(start_date); start_date = new Date(_start_date.setDate(_start_date.getDate() - left_move_block_count)).toLocaleDateString('ja-JP', options).split('/').join('-'), selected_arr = util.get_count_up_date_arr(start_date, (arr.length - 1)), start_date = selected_arr[0], end_date = selected_arr.slice(-1)[0], barposx = max_date_left_pos - ( left_move_block_count * cell_w ) + (bar_padding / 2), barposy = parseInt($('.bar[data-bar_id="' + bar_id + '"]').css('top')); } else { start_date = arr[0], end_date = arr.slice(-1)[0], barposx = parseInt($obj.css('left')); barposy = parseInt($obj.css('top')); if (Number.isNaN(barposx)) { //left_max_dateから何ブロック離れたところにstart_dateがあるか、ブロック数を求める barposx = cell_w * -1 * ( util.get_span_date_count(start_date,end_date) - util.get_span_date_count(left_max_date,end_date) ) - (bar_padding / 2); barposy = $('[data-vid="' + vid + '"]').position().top + (bar_padding / 2); } } } //plan_classからバックグラウンドを選択 if (!bgcolor) { bgcolor = "#000"; } if (plan_class == '') { plan_title = 'ダブルクリックでデータを登録してください。'; } var stylecss = 'width:' + barw + 'px;height:' + barh + 'px;left:' + barposx + 'px;top:' + barposy + 'px;background-color:' + bgcolor + ';', barhtml = ''; /*-------------------------------* * 既存のbarを削除 *-------------------------------*/ $('.bar[data-bar_id="' + bar_id + '"]').remove(); /*-------------------------------* * DOMを追加 *-------------------------------*/ $target_table.after(barhtml); if (plan_class == '') { add_dom.add_delete_point(bar_id); } }, /*--------------------------* * add_initial_data *--------------------------*/ add_initial_data : function(userdata) { $.each(userdata, function(key,val){ var vid = val.id, start_date, end_date, plan_id, plan_class, plan_title, start_id, end_id, s, s_y, s_m, s_d, e, e_y, e_m, e_d, test_ym, test_m, test_y, new_ym, new_date, test_date, p, data_id, selected_arr = []; $.each(val.data,function(key,val){ start_date = val.start_date; end_date = val.end_date; plan_id = key; plan_class = val.class; plan_title = val.title; s = start_date.split('-'); s_y = s[0]; s_m = s[1]; s_d = s[2]; e = end_date.split('-'); e_y = e[0]; e_m = e[1]; e_d = e[2]; test_ym = s[0] + '-' + s[1]; test_y = parseInt(s[0]); test_m = parseInt(s[1]); new_date = start_date; p = 0; var i = s_d; if (new_date === end_date) { selected_arr.push(new_date); add_dom.add_bar(key, selected_arr, vid, plan_id, plan_class, plan_title); selected_arr = []; } else { while (new_date !== end_date) { test_date = new Date(test_ym + '-' + ('0' + i).slice(-2)); new_date = test_ym + '-' + ('0' + i).slice(-2); if ( isNaN(test_date.getDate()) ) { test_m = test_m + 1; if (test_m > 12) { test_y++; test_m = 1; test_ym = ('0' + test_y).slice(-4) + '-01'; } else { test_ym = test_y + '-' + ("0" + test_m).slice(-2); } i = 1; new_date = test_ym + '-' + ('0' + i).slice(-2); selected_arr.push('data-' + vid + '-' + new_date); if (new_date === end_date) { break; } } else { selected_arr.push(new_date); if (new_date === end_date) { break; } } if (p > 1000) { break; } i++; p++; } add_dom.add_bar(key, selected_arr, vid, plan_id, plan_class, plan_title); selected_arr = []; } }); }); }, }, /*============================================================================================* * * ■ util * * ・get_after_move_date_arr * ・get_rgbcolor * ・get_unique_number * ・rgbtohex * ・push_id * ・reset_create_bar * ・ * *============================================================================================*/ util = { /*--------------------------* * get_span_date_count *--------------------------*/ get_span_date_count : function(start_date, end_date) { if (start_date > end_date) { var a = start_date; start_date = end_date, end_date = a; } var day1 = new Date(start_date); var day2 = new Date(end_date); //差日を求める(86,400,000ミリ秒=1日) return (day2 - day1) / 86400000; }, /*--------------------------* * get_after_move_date_arr *--------------------------*/ get_after_move_date_arr : function(bar_id, ss_move_block_count = 0) { if (typeof bar_id == 'undefined' || bar_id == '') { return false; } var $obj = $('.bar[data-bar_id="' + bar_id + '"]'); if (ss_move_block_count === 0) { return util.get_consecutive_date_arr($obj.attr('data-start_date'), $obj.attr('data-end_date')); } //起点となる日付 var start_date = $obj.attr("data-start_date"), end_date = $obj.attr("data-end_date"), _start_date = new Date(start_date), _end_date = new Date(end_date), date_count = util.get_consecutive_date_arr($obj.attr('data-start_date'), $obj.attr('data-end_date')).length, options = { year: 'numeric', month: '2-digit', day: '2-digit' }; start_date = new Date(_start_date.setDate(_start_date.getDate() + ss_move_block_count)).toLocaleDateString('ja-JP', options).split('/').join('-'); end_date = new Date(_end_date.setDate(_end_date.getDate() + ss_move_block_count)).toLocaleDateString('ja-JP', options).split('/').join('-'); return util.get_consecutive_date_arr(start_date, end_date); }, /*--------------------------* * get_rgbcolor *--------------------------*/ get_rgbcolor : function(num) { if (num == '') { return false; } //2023.7.23現在120種 var colorseries = [ '#A4C400','#60A917','#1BA1E2','#F472D0','#6D8764', '#60A917','#0050EF','#D80073','#F0A30A','#647687', '#008A00','#6A00FF','#A20025','#E3C800','#76608A', '#00ABA9','#AA00FF','#E51400','#825A2C','#87794E', '#A4C400','#60A917','#1BA1E2','#F472D0','#6D8764', '#60A917','#0050EF','#D80073','#F0A30A','#647687', '#008A00','#6A00FF','#A20025','#E3C800','#76608A', '#00ABA9','#AA00FF','#E51400','#825A2C','#87794E', '#A4C400','#60A917','#1BA1E2','#F472D0','#6D8764', '#60A917','#0050EF','#D80073','#F0A30A','#647687', '#008A00','#6A00FF','#A20025','#E3C800','#76608A', '#00ABA9','#AA00FF','#E51400','#825A2C','#87794E', '#A4C400','#60A917','#1BA1E2','#F472D0','#6D8764', '#60A917','#0050EF','#D80073','#F0A30A','#647687', '#008A00','#6A00FF','#A20025','#E3C800','#76608A', '#00ABA9','#AA00FF','#E51400','#825A2C','#87794E', '#A4C400','#60A917','#1BA1E2','#F472D0','#6D8764', '#60A917','#0050EF','#D80073','#F0A30A','#647687', '#008A00','#6A00FF','#A20025','#E3C800','#76608A', '#00ABA9','#AA00FF','#E51400','#825A2C','#87794E', '#A4C400','#60A917','#1BA1E2','#F472D0','#6D8764', '#60A917','#0050EF','#D80073','#F0A30A','#647687', '#008A00','#6A00FF','#A20025','#E3C800','#76608A', '#00ABA9','#AA00FF','#E51400','#825A2C','#87794E', ], key = num - 1; return colorseries[key]; }, /*--------------------------* * get_unique_number *--------------------------*/ get_unique_number : function() { return new Date().getTime().toString(); }, /*--------------------------* * rgbtohex *--------------------------*/ rgbtohex : function(orig) { var rgb = orig.replace(/\s/g,'').match(/^rgba?\((\d+),(\d+),(\d+)/i); return (rgb && rgb.length === 4) ? '#' + ('0' + parseInt(rgb[1],10).toString(16)).slice(-2) + ('0' + parseInt(rgb[2],10).toString(16)).slice(-2) + ('0' + parseInt(rgb[3],10).toString(16)).slice(-2) : orig; }, /*--------------------------* * get_count_up_date *--------------------------*/ get_count_up_date : function(base_date, count_up, date_type = true) { var _base_date = new Date(base_date), options = { year: 'numeric', month: '2-digit', day: '2-digit' }; if (date_type) { return _base_date.setDate( _base_date.getDate() + count_up ); } else { return new Date(_base_date.setDate( _base_date.getDate() + count_up )).toLocaleDateString('ja-JP', options).split('/').join('-'); } }, /*--------------------------* * get_count_up_date_arr *--------------------------*/ get_count_up_date_arr : function(start_date, count_up) { var end_date = util.get_count_up_date(start_date, count_up) return util.get_consecutive_date_arr(start_date, end_date); }, /*--------------------------* * get_consecutive_date_arr *--------------------------*/ get_consecutive_date_arr : function(start_date, end_date) { var _start_date = new Date(start_date), _end_date = new Date(end_date), data_arr = [], options = { year: 'numeric', month: '2-digit', day: '2-digit' }; if (_start_date < _end_date) { start_date = _start_date; end_date = _end_date; } else { start_date = _end_date; end_date = _start_date; } for(var d = start_date; d <= end_date; d.setDate( d.getDate() + 1 )) { var _date = d.toLocaleDateString('ja-JP', options).split('/').join('-'); data_arr.push(_date); } return data_arr; }, /*----------------------------------------------------* * push_id * * 日付がジャンプしていないかチェックする。 * ジャンプしていたら、ジャンプする直前の配列にする。 * *----------------------------------------------------*/ push_id : function(arr, vid, date) { if (!is_drag_new_bar) { return false; } var _start_date = new Date(arr[0]), _end_date = new Date(arr.slice(-1)[0]), start_date, end_date, data_arr = [], options = { year: 'numeric', month: '2-digit', day: '2-digit' }; if (_start_date < _end_date) { start_date = _start_date; end_date = _end_date; } else { start_date = _end_date; end_date = _start_date; } $target_td.removeClass('isset'); for(var d = start_date; d <= end_date; d.setDate( d.getDate() + 1 )) { var _date = d.toLocaleDateString('ja-JP', options).split('/').join('-'); data_arr.push(_date); $('[data-date="' + _date + '"][data-vid="'+vid+'"]').addClass('isset'); } return data_arr; }, /*--------------------------* * reset_create_bar *--------------------------*/ reset_create_bar :function() { is_drag_new_bar = false; $target_td.removeClass('isset'); selected_arr = []; _selected_arr = []; }, /*--------------------------* * scroll_window *--------------------------*/ scroll_window :function() { //今月が画面上に出るようにスクロール $(chart_window).animate({scrollLeft: 0}, 100); var target_date = new Date().getFullYear() + '-' + ('0' + (new Date().getMonth() + 1)).slice(-2) + '-01'; if ($('[data-date="' + target_date + '"]').length > 0) { var move_distance = $('[data-date="' + target_date + '"]').offset().left - vname_w - $(chart_window).offset().left; $(chart_window).animate({scrollLeft: move_distance}, 100); } }, }; /*-----------------------------* * プログラム実行 *-----------------------------*/ add_event.init(); /*-----------------------------* * その他 *-----------------------------*/ $target_table.on({ 'mouseleave' : function(e) { scrolling = false; clearInterval(timer_id); return false; }, }); $(document).on({ 'mousedown' : function(e) { if(!$(e.target).closest('#' + $target.attr('id')).length) { $('.bar').removeClass('selected'); $('.grabpoint').remove(); } }, 'mouseup' : function(e) { is_drag_new_bar = false; _selected_arr = []; $target_td.removeClass('isset'); return false; }, }); return (this); }; }(this, jQuery));