OSDN Git Service

報告書の「マス」を「経路」に直す
[kancollesniffer/KancolleSniffer.git] / LogViewer / tags.tag
index 4ebd6fe..4c2eb4c 100644 (file)
@@ -26,7 +26,7 @@ this.changeTab = function(e) {
     <li each={name, i in rangeTabs} class={select: opts.logRange.val === i} onclick={parent.rangeTabChange}>{name}</li>
 </ul>
 <div style="padding: 0.2em 0;">
-<input type="text" id="term_from" style="width: 7em">~<input type="text" id="term_to" style="width: 7em">
+<input type="text" id="term_from" style="width: 10em">~<input type="text" id="term_to" style="width: 10em">
 </div>
 </div>
 
@@ -51,17 +51,9 @@ var val = sessionStorage.getItem('logRange');
 opts.logRange.val = val === null ? 2 : +val;
 
 this.init = function() {
-    $('#term_from').datepicker({
-        onClose: function() {
-            if (opts.logRange.val === 4)
-                opts.observable.trigger("logRangeChanged");
-        }
-    });
-    $('#term_to').datepicker({
-        onClose: function() {
-            if (opts.logRange.val === 4)
-                opts.observable.trigger("logRangeChanged");
-        }
+    self.initPicker('#term_from', '#term_to', function() {
+        if (opts.logRange.val === 4)
+            opts.observable.trigger( "logRangeChanged");
     });
 };
 
@@ -82,14 +74,17 @@ this.rangeTabChange = function(e) {
 <thead>
 <tr></tr>
 </thead>
+<tfoot>
+<tr></tr>
+</toot>
 </table>
 </div>
 
 <script>
 this.tables = [
-"<th>æ\97¥ä»\98</th><th>æµ·å\9f\9f</th><th>ã\83\9eã\82¹</th><th>ボス</th><th>ランク</th><th>ドロップ艦種</th><th>ドロップ艦娘", // ドロップ
-"<th>æ\97¥ä»\98</th><th style=\"min-width: 3.2em;\">æµ·å\9f\9f</th><th>ã\83\9eã\82¹</th><th>ã\83\9cã\82¹</th><th>ã\83©ã\83³ã\82¯</th><th>è\89¦é\9a\8aè¡\8cå\8b\95</th><th>å\91³æ\96¹é\99£å½¢</th><th>æ\95µé\99£å½¢</th><th style=\"min-width: 3.2em;\">æ\95µè\89¦é\9a\8a</th><th>å\91³æ\96¹è\89¦1</th><th>å\91³æ\96¹è\89¦1HP</th><th>å\91³æ\96¹è\89¦2</th><th>å\91³æ\96¹è\89¦2HP</th><th>å\91³æ\96¹è\89¦3</th><th>å\91³æ\96¹è\89¦3HP</th><th>å\91³æ\96¹è\89¦4</th><th>å\91³æ\96¹è\89¦4HP</th><th>å\91³æ\96¹è\89¦5</th><th>å\91³æ\96¹è\89¦5HP</th><th>å\91³æ\96¹è\89¦6</th><th>å\91³æ\96¹è\89¦6HP</th><th>大破è\89¦</ht><th style=\"min-width: 2.2em;\">敵艦1</th><th>敵艦1HP</th><th style=\"min-width: 2.2em;\">敵艦2</th><th>敵艦2HP</th><th style=\"min-width: 2.2em;\">敵艦3</th><th>敵艦3HP</th><th style=\"min-width: 2.2em;\">敵艦4</th><th>敵艦4HP</th><th style=\"min-width: 2.2em;\">敵艦5</th><th>敵艦5HP</th><th style=\"min-width: 2.2em;\">敵艦6</th><th>敵艦6HP</th><th>味方制空値</th><th>敵制空値</th><th>制空状態</th>", // 海戦
-"<th>日付</th><th>結果</th><th>遠征</th><th>燃料</th><th>弾薬</th><th>鋼材</th><th>ボーキ</th><th>開発資材</th><th>高速修復材</th><th>高速建造材</th>", // 遠征
+"<th>æ\97¥ä»\98</th><th>æµ·å\9f\9f</th><th>ã\83\9eã\83\83ã\83\97</th><th>çµ\8cè·¯</th><th>ボス</th><th>ランク</th><th>ドロップ艦種</th><th>ドロップ艦娘", // ドロップ
+"<th>æ\97¥ä»\98</th><th style=\"min-width: 3.2em;\">æµ·å\9f\9f</th><th>ã\83\9eã\83\83ã\83\97</th><th>çµ\8cè·¯</th><th>ã\83\9cã\82¹</th><th>ã\83©ã\83³ã\82¯</th><th>è\89¦é\9a\8aè¡\8cå\8b\95</th><th>å\91³æ\96¹é\99£å½¢</th><th>æ\95µé\99£å½¢</th><th style=\"min-width: 3.2em;\">æ\95µè\89¦é\9a\8a</th><th>å\91³æ\96¹è\89¦1</th><th>å\91³æ\96¹è\89¦1HP</th><th>å\91³æ\96¹è\89¦2</th><th>å\91³æ\96¹è\89¦2HP</th><th>å\91³æ\96¹è\89¦3</th><th>å\91³æ\96¹è\89¦3HP</th><th>å\91³æ\96¹è\89¦4</th><th>å\91³æ\96¹è\89¦4HP</th><th>å\91³æ\96¹è\89¦5</th><th>å\91³æ\96¹è\89¦5HP</th><th>å\91³æ\96¹è\89¦6</th><th>å\91³æ\96¹è\89¦6HP</th><th>大破è\89¦</th><th>中破è\89¦</th><th style=\"min-width: 2.2em;\">敵艦1</th><th>敵艦1HP</th><th style=\"min-width: 2.2em;\">敵艦2</th><th>敵艦2HP</th><th style=\"min-width: 2.2em;\">敵艦3</th><th>敵艦3HP</th><th style=\"min-width: 2.2em;\">敵艦4</th><th>敵艦4HP</th><th style=\"min-width: 2.2em;\">敵艦5</th><th>敵艦5HP</th><th style=\"min-width: 2.2em;\">敵艦6</th><th>敵艦6HP</th><th>味方制空値</th><th>敵制空値</th><th>制空状態</th>", // 海戦
+"<th>日付</th><th>結果</th><th>遠征</th><th>燃料</th><th>弾薬</th><th>鋼材</th><th>ボーキ</th><th>開発資材</th><th>高速修復材</th><th>高速建造材</th><th>改修資材</th>", // 遠征
 "<th>日付</th><th>開発装備</th><th>種別</th><th>燃料</th><th>弾薬</th><th>鋼材</th><th>ボーキ</th><th>秘書艦</th><th>司令部Lv</th>", // 開発
 "<th>日付</th><th>種類</th><th>名前</th><th>艦種</th><th>燃料</th><th>弾薬</th><th>鋼材</th><th>ボーキ</th><th>開発資材</th><th>空きドック</th><th>秘書艦</th><th>司令部Lv</th>", // 建造
 "<th>日付</th><th>改修装備</th><th>レベル</th><th>成功</th><th>確実化</th><th>消費装備</th><th>消費数</th><th>燃料</th><th>弾薬</th><th>鋼材</th><th>ボーキ</th><th>開発資材</th><th>改修資材</th><th>秘書艦</th><th>二番艦</th>", // 改修
@@ -107,9 +102,6 @@ this.jsons = [
 ];
 
 this.on("mount", function() {
-    var records = this.root.querySelectorAll("tr");
-    for (var i = 0; i < records.length; i++)
-        records[i].innerHTML = this.tables[i];
     this.init();
 });
 
@@ -127,30 +119,85 @@ opts.observable.on("logRangeChanged", function() {
 
 this.init = function() {
     for (var t = 0; t < this.tables.length; t++) {
-        var opts = {
-            destroy: true,
-            deferRender: true,
-            stateSave: true,
-            order: [[0, "desc"]],
-            pageLength: 50,
-            lengthMenu: [[50, 100, 200, -1], [50, 100, 200, "All"]],
-            drawCallback: function() {
-                $('#loading').hide();
-            }
-        };
-        if (t === 0) {
-            opts.columns = [{ data: 0 }, { data: 1 }, { data: 2 }, { data: 3 }, { data: 4 }, { data: 9 }, { data: 10 }];
-        } else if (t === 1) {
-            var entries = [];
-            for (var i = 0; i < 39; i++) {
-                if (i === 9 || i === 10)
-                    continue;
-                entries.push({ data: i });
-            }
-            opts.columns = entries;
+        var table = $('#log' + t);
+        self.setHeaderAndFooter(table, self.tables[t]);
+        var dTable = table.DataTable(self.tableOptions(t));
+        self.searchSetup(dTable);
+    }
+};
+
+this.tableOptions = function(tableId) {
+    var opts = {
+        destroy: true,
+        deferRender: true,
+        stateSave: true,
+        order: [[0, "desc"]],
+        pageLength: 50,
+        lengthMenu: [[50, 100, 200, -1], [50, 100, 200, "All"]],
+        drawCallback: function() {
+            $('#loading').hide();
         }
-        $('#log' + t).dataTable(opts);
+    };
+    if (tableId === 0) {
+        opts.columns = self.dropColumns();
+    } else if (tableId === 1) {
+        opts.columns = self.sortieColumns();
+    }
+    return opts;
+};
+
+this.dropColumns = function() {
+    return [{data: 0}, {data: 1}, {data: 40}, {data: 2}, {data: 3}, {data: 4}, {data: 9}, {data: 10}];
+};
+
+this.sortieColumns = function() {
+    var entries = [];
+    for (var i = 0; i < 38; i++) {
+        if (i === 2)
+            entries.push({data: 40});
+        if (i === 9 || i === 10)
+            continue;
+        if (i === 23) {
+            entries.push({data: 38});
+            entries.push({data: 39});
+        }
+        entries.push({data: i});
     }
+    return entries;
+};
+
+this.setHeaderAndFooter = function(table, header) {
+    table.find("thead tr").first().html(header);
+    var footer = table.find("tfoot tr");
+    table.find("th").each(function(index) {
+        footer.append(
+            '<th style="padding: 1px"><input style="min-width: 100%" size="1" type="search" placeholder="Search ' +
+            $(this).text() + '"/></th>');
+    });
+};
+
+this.searchSetup = function(dTable) {
+    self.setupCellSearch(dTable);
+    self.setupGlobalSearch(dTable);
+};
+
+this.setupCellSearch = function(dTable) {
+    dTable.columns().every(function() {
+        var that = this;
+        that.search(""); // reset
+        $('input', this.footer()).on("input search", function() {
+            that.search(this.value, true, false).draw();
+        });
+    });
+};
+
+this.setupGlobalSearch = function(dTable) {
+    var searchLabel = $(dTable.table().container()).find(".dataTables_filter label").first();
+    searchLabel.html('Search: <input type="search">');
+    searchLabel.children("input").first().on("input search", function() {
+        dTable.search(this.value, true, false).draw();
+    });
+    dTable.search(""); // reset
 };
 
 this.show = function() {
@@ -167,15 +214,15 @@ this.show = function() {
         query += from.valueOf();
         break;
     case 1:
-        from = now.clone().startOf('week').hours(5);
-        if (now.hour() < 5 && now.days() === 1)
+        from = now.clone().day(1).startOf('day').hours(5);
+        if (now.day() === 0 || now.day() === 1 && now.hour() < 5)
             from.subtract(1, 'weeks');
         query += from.valueOf();
         break;
     case 2:
         if (now.hours() >= 22 &&
-            now.dates() === now.clone().endOf('month').date()) {
-            from = now.clone().hours(22);
+            now.date() === now.clone().endOf('month').date()) {
+            from = now.clone().startOf('day').hours(22);
         } else {
             from = now.clone().startOf('month').subtract(1, 'days').hours(22);
         }
@@ -185,23 +232,13 @@ this.show = function() {
         query = "";
         break;
     case 4:
-        from = $('#term_from').datepicker("getDate");
-        var to = $('#term_to').datepicker("getDate");
+        from = $('#term_from').datetimepicker("getValue");
+        var to = $('#term_to').datetimepicker("getValue");
         if (from === null)
             return;
-        from = moment(from);
-        if (from.date() === 1)
-            from.subtract(2, 'hours');
         query += from.valueOf();
-        if (to !== null) {
-            to = moment(to);
-            if (to.date() === to.clone().endOf('month').date()) {
-                to.hour(22);
-            } else {
-                to.add(1, 'days').hours(5);
-            }
+        if (to !== null)
             query += "&to=" + to.valueOf();
-        }
         break;
     }
     $('#loading').show();
@@ -247,7 +284,7 @@ opts.observable.on("mainTabChanged", function(idx) {
     <li each={name, i in diffChartRanges} class={select: chartSpec.diffRange === i} onclick={parent.rangeTabChange}>{name}</li>
 </ul>
 <div style="padding: 0.2em 0;">
-<input type="text" id="chart_from" style="width: 7em">~<input type="text" id="chart_to" style="width: 7em">
+<input type="text" id="chart_from" style="width: 10em">~<input type="text" id="chart_to" style="width: 10em">
 <label><input type="checkbox" id="tooltip" value="" style="margin-left: 2em;" onchange={tooltipChange} checked={opts.chartSpec.tooltip === 1}>ツールチップ</label>
 </div>
 </div>
@@ -297,23 +334,16 @@ this.useDatePicker = function() {
         opts.chartSpec.type === 1 && opts.chartSpec.diffRange === 4;
 };
 
+var self = this;
+
 this.init = function() {
-    $('#chart_from').datepicker({
-        onClose: function() {
-            if (self.useDatePicker())
-                opts.observable.trigger("chartSpecChanged");
-        }
-    });
-    $('#chart_to').datepicker({
-        onClose: function() {
-            if (self.useDatePicker())
-                opts.observable.trigger("chartSpecChanged");
-        }
+    self.initPicker('#chart_from', '#chart_to', function() {
+        if (self.useDatePicker())
+            opts.observable.trigger("chartSpecChanged");
     });
 };
 
 this.mainTab = 0;
-var self = this;
 
 this.on("mount", self.init);
 
@@ -400,12 +430,12 @@ this.calcRange = function(range) {
         case 4:
             break;
         case 5:
-            var fromDate = $('#chart_from').datepicker("getDate");
-            var toDate = $('#chart_to').datepicker("getDate");
+            var fromDate = $('#chart_from').datetimepicker("getValue");
+            var toDate = $('#chart_to').datetimepicker("getValue");
             if (fromDate === null || toDate === null)
                 return {first: 0, last:0};
-            first = fromDate.valueOf() + 3600 * 5000;
-            last = toDate.valueOf() + this.oneDay + 3600 * 5000;
+            first = fromDate.valueOf();
+            last = toDate.valueOf();
             break;
     }
     return {first: first, last: last};
@@ -603,14 +633,12 @@ this.calcRange = function(range) {
         case 3:
             break;
         case 4:
-            var fromDate = $('#chart_from').datepicker("getDate");
-            var toDate = $('#chart_to').datepicker("getDate");
+            var fromDate = $('#chart_from').datetimepicker("getValue");
+            var toDate = $('#chart_to').datetimepicker("getValue");
             if (fromDate === null || toDate === null)
                 return {first: 0, last: 0};
-            var from = fromDate.valueOf() + 3600 * 5000;
-            var to = toDate.valueOf() + this.oneDay + 3600 * 5000;
-            first = Math.max(first, from);
-            last = Math.min(last, to);
+            first = Math.max(first, fromDate.valueOf());
+            last = Math.min(last, toDate.valueOf());
             break;
     }
     return {first: first, last: last};
@@ -844,7 +872,7 @@ $(window).resize(function() {
 </select>
 <table id="achivement_table" class="display compact cell-border">
 <thead>
-<tr><th>日付</th><th>戦果</th><th>EO</th><th>月毎</th></tr>
+<tr><th>日付</th><th>戦果</th><th>月毎</th><th>EO</th><th>月毎(EO込)</th></tr>
 </thead>
 </table>
 <div id="achivementChart" style="margin: 1em;"></div>
@@ -901,6 +929,7 @@ this.calcResult = function(data) {
     var lastDate = moment(0);
     var lastExp = -1;
     var nextDate = moment(0);
+    var lastEmit = moment(0);
     for (var i = 0; i < data.length; i++) {
         var row = data[i];
         var date = this.parseDate(row[0]);
@@ -920,13 +949,16 @@ this.calcResult = function(data) {
             }
             if (nextDate.valueOf() !== 0) {
                 var d = isNewDate ? nextDate.subtract(1, 'days') : endOfMonth;
+                lastEmit = isNewDate ? d : moment(0);
                 var m = d.format("YYYY-MM");
                 if (!this.result[m])
                     this.result[m] = [];
+                var perMonth = (lastExp - monthExp) / expPerAch + carryOverAch;
                 this.result[m].push([
                     d.format("YYYY-MM-DD"),
-                    ((lastExp - prevExp) / expPerAch).toFixed(1), dayEo,
-                    ((lastExp - monthExp) / expPerAch + monthEo + carryOverAch + carryOverEo).toFixed(1)
+                    ((lastExp - prevExp) / expPerAch).toFixed(1),
+                    perMonth.toFixed(1), dayEo,
+                    (perMonth + monthEo + carryOverEo).toFixed(1)
                 ]);
             }
             prevExp = lastExp === -1 ? exp : lastExp;
@@ -950,7 +982,7 @@ this.calcResult = function(data) {
                 if (!this.result[m])
                     this.result[m] = [];
                 this.result[m].push([endOfMonth.format("YYYY-MM 引継"),
-                    carryOverAch.toFixed(1), carryOverEo.toFixed(1), (carryOverAch + carryOverEo).toFixed(1)]);
+                    carryOverAch.toFixed(1), carryOverAch.toFixed(1), carryOverEo.toFixed(1), (carryOverAch + carryOverEo).toFixed(1)]);
             }
             dayEo = 0;
             nextDate = date.clone().hour(2).startOf('hour');
@@ -967,6 +999,12 @@ this.calcResult = function(data) {
         lastDate = date;
         lastExp = exp;
     }
+    if (lastEmit.valueOf() !== 0) {
+        var eom = endOfMonth.format("YYYY-MM");
+        var ave = (perMonth - carryOverAch) / lastEmit.date();
+        var estimate = perMonth + ave * (endOfMonth.date() - lastEmit.date());
+        this.result[eom].push([endOfMonth.format("YYYY-MM-DD 予測"), ave.toFixed(1) + " 平均", estimate.toFixed(1) + " 予測", monthEo + " 合計", (estimate + monthEo).toFixed(1) + " 予測"]);
+    }
 };
 
 this.calcChartData = function() {
@@ -979,15 +1017,16 @@ this.calcChartData = function() {
         data.push(["日付", "戦果", "EO", "月毎"]);
         for (var i = 0; i < result.length; i++) {
             var row = result[i];
+            if (row[0].match(/予測/))
+                continue;
             if (row[0].match(/引継/)) {
-                eo = row[2] - 0;
-                data.push([0, row[1], row[2], row[3]]);
+                eo = row[3] - 0;
+                data.push([0, row[1], row[3], row[4]]);
                 continue;
             }
             d = moment(row[0], "YYYY-MM-DD").date();
-            eo += row[2];
-            var ach = (row[3] - eo).toFixed(1);
-            data.push([d, ach, eo, row[3]]);
+            eo += row[3];
+            data.push([d, row[2], eo, row[4]]);
         }
         var endOfMonth = moment(month, "YYYY-MM").endOf("month").date();
         while (d < endOfMonth) {
@@ -1078,7 +1117,7 @@ this.show = function() {
 </ul>
 
 <div style="padding: 0.2em 0;">
-<input type="text" id="sortie_stat_from" style="width: 7em">~<input type="text" id="sortie_stat_to" style="width: 7em">
+<input type="text" id="sortie_stat_from" style="width: 10em">~<input type="text" id="sortie_stat_to" style="width: 10em">
 </div>
 
 <div style="clear: both;" show={type === "recent"}>
@@ -1132,15 +1171,9 @@ opts.observable.on("mainTabChanged", function(idx) {
 });
 
 this.init = function() {
-    this.initDatePicker();
-};
-
-this.initDatePicker = function() {
-    $('#sortie_stat_from').datepicker({
-        onClose: function() { if (self.type === "range") self.show(); }
-    });
-    $('#sortie_stat_to').datepicker({
-        onClose: function() { if (self.type === "range") self.show(); }
+    self.initPicker('#sortie_stat_from', '#sortie_stat_to', function() {
+        if (self.type === "range")
+            self.show();
     });
 };
 
@@ -1152,23 +1185,14 @@ this.loadData = function() {
         from = moment().subtract(1, 'months').subtract(1, 'day').valueOf();
         to = new Date().valueOf();
     } else {
-        var fromDate = $('#sortie_stat_from').datepicker("getDate");
-        var toDate = $('#sortie_stat_to').datepicker("getDate");
+        var fromDate = $('#sortie_stat_from').datetimepicker("getValue");
+        var toDate = $('#sortie_stat_to').datetimepicker("getValue");
         if (fromDate === null || toDate === null) {
             this.show([]);
             return;
         }
-        from = moment(fromDate);
-        if (from.date() === 1)
-            from.subtract(2, 'hours');
-        from = from.valueOf();
-        to = moment(toDate);
-        if (to.date() === to.clone().endOf('month').date()) {
-            to.hour(22);
-        } else {
-            to.endOf('day');
-        }
-        to = to.valueOf();
+        from = fromDate.valueOf();
+        to = toDate.valueOf();
     }
     $.ajax({
         url: "./海戦・ドロップ報告書.json?from=" + from + "&to=" + to,
@@ -1221,7 +1245,7 @@ this.gatherData = function(data) {
         var isBoss = row[3].indexOf("ボス") !== -1;
         var isStart = row[3].indexOf("出撃") !== -1;
         var resR = 0;
-        for (var j = 23; j < row.length; j++) {
+        for (var j = 22; j < row.length; j++) {
             if (/^輸送/.test(row[j]) && /^0\x2f/.test(row[j + 1]))
                 resR++;
         }
@@ -1248,6 +1272,13 @@ this.gatherData = function(data) {
                     if (name === "合計")
                         to.stat["合計 - ボス"] = initStat();
                 }
+                if ((b === 0 || b === 2) && isStart) {
+                    if (mo.start === "-")
+                        mo.start = 0;
+                    mo.start++;
+                }
+                if (/^基地航空隊/.test(row[11]))
+                    continue;
                 mo["R"] += resR;
                 mo[res]++;
                 if (item) {
@@ -1255,11 +1286,6 @@ this.gatherData = function(data) {
                         mo[item] = 0;
                     mo[item]++;
                 }
-                if ((b === 0 || b === 2) && isStart) {
-                    if (mo.start === "-")
-                        mo.start = 0;
-                    mo.start++;
-                }
             }
         }
     }