OSDN Git Service

資材グラフにツールチップを表示するか選択可能にする
[kancollesniffer/KancolleSniffer.git] / LogViewer / index.html
1 <!DOCTYPE html>
2 <html lang="ja">
3 <head>
4 <meta charset="utf-8">
5 <title>各種報告書 - KancolleSniffer</title>
6
7 <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
8 <script src="//cdnjs.cloudflare.com/ajax/libs/datatables/1.10.7/js/jquery.dataTables.min.js"></script>
9 <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/datatables/1.10.7/css/jquery.dataTables.min.css">
10 <script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.min.js"></script>
11 <script src="//cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.js"></script>
12 <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css">
13 <script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js"></script>
14 <script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
15 <link rel="stylesheet" type="text/css" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
16 <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/i18n/datepicker-ja.min.js"></script>
17 <style>
18 body {
19     font-family:'Lucida Grande','Hiragino Kaku Gothic ProN', Meiryo, sans-serif;
20     line-height: 1.5;
21     font-size: 14px;
22 }
23 .tab {overflow: hidden; list-style-type: none; margin: 0em 2em 2em 1em; padding: 0em;}
24 .tab li {background: #eee; padding: 0.3em 2.0em; float: left; margin-right: 2px;}
25 .tab li.select {background: #ccc;}
26 .contents {list-style-type: none; margin: 0em; padding: 0em;}
27 .hide {display: none;}
28 #loading {
29     width: 48px;
30     height: 48px;
31     display: none;
32     position: fixed;
33     top: 50%;
34     left: 50%;
35     margin-top: -24px;
36     margin-left: -24px;
37     z-index: 100;
38 }
39 </style>
40
41 </head>
42 <body>
43 <script>
44 function showLog()
45 {
46     var query = "?from=" + moment().subtract(1, 'months').valueOf();
47     if ($('input[name=term]:eq(1)').prop('checked')) {
48         from = $('#term_from').datepicker("getDate");
49         to = $('#term_to').datepicker("getDate");
50         if (from != null)
51             query = "?from=" + from.valueOf();
52         if (to != null)
53             query += "&to=" + (to.valueOf() + 3600 * 24 * 1000);
54     }
55     var jsons = [
56         "海戦・ドロップ報告書.json",
57         "海戦・ドロップ報告書.json",
58         "遠征報告書.json",
59         "開発報告書.json",
60         "建造報告書.json",
61         "資材ログ.json"
62     ];
63     $('#loading').show();
64     var url = jsons[selectedTable] + query;
65     $('#log' + selectedTable).DataTable().ajax.url(url).load();
66 }
67
68 function initTables()
69 {
70     for (var t = 0; t < 6; t++) {
71         var opts = {
72             destroy: true,
73             deferRender: true,
74             stateSave: true,
75             order: [[0, "desc"]],
76             pageLength: 50,
77             lengthMenu: [[50, 100, 200, -1],[50, 100, 200, "All"]],
78             drawCallback: function () {
79                 $('#loading').hide();
80             }
81         };
82         if (t == 0) {
83             opts.columns = [{data: 0}, {data: 1}, {data: 2}, {data: 3}, {data: 4}, {data: 9}, {data: 10}];
84         } else if (t == 1) {
85             var entries = [];
86             for (i = 0; i < 35; i++) {
87                 if (i == 9 || i == 10)
88                     continue;
89                 entries.push({data: i})
90             }
91             opts.columns = entries;
92         }
93         $('#log' + t).dataTable(opts);
94     }
95 }
96
97 const timeFormat = "YYYY-MM-DD HH:mm:ss";
98 function parseDate(d)
99 {
100     return moment(d, timeFormat);
101 }
102
103 function toString(d)
104 {
105     return d.format(timeFormat);
106 }
107
108 function pickChartData(data, range)
109 {
110     var newdata = [];
111     var ticks = [];
112     var grid = [];
113     var last = moment(data[data.length - 1][0]).valueOf();
114     var first, interval, tickInterval;
115     const oneDay = 3600 * 24 * 1000;
116     switch (range) {
117     case 0:
118         first = moment(last).subtract(24, 'hours').valueOf();
119         interval = 1000;
120         tickInterval = 3600 * 1000;
121         last -= last % tickInterval;
122         break;
123     case 1:
124         first = moment(last).subtract(7, 'days').valueOf();
125         interval = 1000;
126         tickInterval = oneDay;
127         last -= last % tickInterval + 3600 * 4000;
128         break;
129     case 2:
130         first = moment(last).subtract(1, 'months').valueOf();
131         last = moment(last).day(1).valueOf();
132         interval = 3600 * 2000;
133         tickInterval = oneDay * 7;
134         last -= last % oneDay + 3600 * 4000;
135         break;
136     case 3:
137         first = moment(data[0][0]).valueOf();
138         last = moment(last).day(1).valueOf();
139         interval = 3600 * 6000;
140         tickInterval = oneDay * 7;
141         last -= last % oneDay + 3600 * 4000;
142         break;
143     }
144     for (var tick = last; tick > first; tick -= tickInterval)
145     {
146         var str = toString(moment(tick));
147         ticks.unshift(str);
148         grid.unshift({value: str});
149     }
150     var last_data;
151     for (var i = data.length - 1; i >= 0; i--) {
152         var row = data[i];
153         var date = parseDate(row[0]).valueOf();
154         if (date > first) {
155             var v = date - date % interval;
156             if (last_data != v) {
157                 newdata.unshift(row);
158                 last_data = v;
159             }
160         } else {
161             break;
162         }
163     }
164     return { data: newdata, tick: ticks, grid: grid };
165 }
166
167 var selectedTable = 0;
168 var selectedRange = 0;
169
170 function drawChart(data)
171 {
172     if (data == null) {
173         $('#loading').show();
174         $.get("./資材ログ.json?time=" + Date.now(), function (data) { drawChart(data);}, "json");
175         return;
176     }
177     picked = pickChartData(data.data, selectedRange);
178     var header = ["日付","燃料","弾薬","鋼材","ボーキ","高速建造材","高速修復材","開発資材","改修資材"];
179     picked.data.unshift(header);
180     var chart = c3.generate({
181         bindto: '#chart',
182         size: {
183             height: 400,
184             width: 800
185         },
186         data: {
187             x: '日付',
188             xFormat: '%Y-%m-%d %X',
189             rows: picked.data,
190             axes: {
191                 燃料: 'y',
192                 弾薬: 'y',
193                 鋼材: 'y',
194                 ボーキ: 'y',
195                 高速建造材: 'y2',
196                 高速修復材: 'y2',
197                 開発資材: 'y2',
198                 改修資材: 'y2'
199             }
200         },
201         point: {
202             show: false
203         },
204         tooltip: {
205             show: $('#tooltip').prop('checked')
206         },
207         grid: {
208             x: {
209                 lines: picked.grid
210             }
211         },
212         axis: {
213             x: {
214                 type: 'timeseries',
215                 tick: {
216                     rotate: 30,
217                     format: function (x) { return moment(x).format("MM-DD HH:mm"); },
218                     values: picked.tick
219                 },
220                 height: 60
221             },
222             y2: {
223                 show: true
224             }
225         },
226         onrendered: function () { $('#loading').hide(); }
227     });
228 }
229
230 function setSortieStat(data) {
231     if (!data) {
232         $('#loading').show();
233         var from = moment().subtract(1, 'months').valueOf();
234         $.get("./海戦・ドロップ報告書.json?time=" + Date.now() + "&from=" + from, function (data) { setSortieStat(data.data);}, "json");
235         return;
236     }
237     var r = {
238         day: {stat: {}},
239         week: {stat: {}},
240         month: {stat: {}}
241     };
242     now = moment();
243     r.day.begin = moment(now).hour(5).minute(0);
244     if (now.hour() < 5) {
245         r.day.begin.subtract(1, 'days');
246     }
247     r.week.begin = moment(now).day(1).hour(5).minute(0);
248     if (now.day() == 1 && now.hour() < 5) {
249         r.week.begin.subtract(1, 'weeks');
250     }
251     r.month.begin = moment(now).date(1).hour(5).minute(0);
252     if (now.date() == 1 && now.hours() < 5) {
253         r.month.begin.subtract(1, 'months');
254     }
255     for (var i = 0; i < data.length; i++) {
256         var row = data[i];
257         var date = moment(row[0]);
258         var map = row[1];
259         var isBoss = row[3] == "ボス";
260         var isStart = row[3] == "出撃";
261         var res = row[4];
262         if (res == "E")
263             res = "D";
264         for (var term in r) {
265             to = r[term];
266             if (to.begin.isAfter(date))
267                 continue;
268             for (var b = 0; b < 2; b++) {
269                 var name = map;
270                 if (b == 1) {
271                     if (!isBoss)
272                         break;
273                     name = map + " - ボス";
274                 }
275                 var mo = to.stat[name];
276                 if (!mo)
277                     mo = to.stat[name] = {start:"-", S:0, A:0, B:0, C:0, D:0};
278                 mo[res]++;
279                 if (b == 0 && isStart)
280                 {
281                     if (mo.start == "-")
282                         mo.start = 0;
283                     mo.start++
284                 }
285             }
286         }
287     }
288     for (term in r) {
289         var table = [];
290         for (map in r[term].stat)
291         {
292             var e = r[term].stat[map];
293             e.map = map;
294             table.push(e);
295         }
296         var dt = $("#sortie_stat_" + term).DataTable();
297         dt.clear();
298         dt.rows.add(table).draw();
299     }
300     $('#loading').hide();
301 }
302
303 function initSortieStat()
304 {
305     var terms = ['day', 'week', 'month'];
306     for (var i = 0; i < terms.length; i++) {
307         $("#sortie_stat_" + terms[i]).dataTable({
308             paging: false,
309             searching: false,
310             ordering: false,
311             columns: [
312                 { data: "map" },
313                 { data: "start" },
314                 { data: "S" },
315                 { data: "A" },
316                 { data: "B" },
317                 { data: "C" },
318                 { data: "D" }
319             ]
320         });
321     }
322 }
323
324 function selectTopTab(i)
325 {
326     if (i < 6) {
327         selectedTable = i;
328         showLog();
329     } else if (i == 6) {
330         drawChart();
331     } else if (i == 7) {
332         setSortieStat();
333     }
334     if (i < 6)
335         $('#term').show();
336     else
337         $('#term').hide();
338     var tab = $('.tab0 li');
339     tab.removeClass('select');
340     tab.eq(i).addClass('select');
341     $('.contents .hide').hide();
342     $('.contents .hide').eq(i).show();
343 }
344
345 $(function() {
346     $.fn.dataTable.ext.errMode = 'throw';
347     $('.tab0 li').click(function() {
348         var tab = $('.tab0 li');
349         var i = tab.index(this)
350         selectTopTab(i);
351         sessionStorage.setItem('prevTab', i);
352     });
353     $('.tab1 li').click(function() {
354         var tab = $('.tab1 li');
355         var i = tab.index(this);
356         selectedRange = i;
357         drawChart();
358         tab.removeClass('select');
359         tab.eq(i).addClass('select');
360         sessionStorage.setItem('prevRange', i);
361     });
362     $('#tooltip').change(function() {
363         drawChart();
364     });
365     $('table').addClass('display compact cell-border');
366     initTables();
367     initSortieStat();
368     var range = sessionStorage.getItem('prevRange');
369     selectedRange = range == null ? 0 : +range;
370     $('.tab1 li').eq(range).addClass('select');
371     $('#term_from').datepicker({
372         defaultDate: moment().subtract(1, 'months').toDate()
373     });
374     $('#term_to').datepicker();
375     $('#term_apply').click(showLog);
376     var prev = sessionStorage.getItem('prevTab');
377     selectTopTab(prev == null ? 0 : +prev);
378 });
379 </script>
380
381 <div id="loading"><img src="http://kancollesniffer.osdn.jp/ajax-loader.gif" alt="読み込み中..."></div>
382
383 <ul class="tab tab0">
384 <li>ドロップ</li>
385 <li>海戦</li>
386 <li>遠征</li>
387 <li>開発</li>
388 <li>建造</li>
389 <li>資材</li>
390 <li>資材グラフ</li>
391 <li>出撃統計</li>
392 </ul>
393
394 <form id="term">
395 <p>
396 <label><input type="radio" name="term" value="0" checked="checked">直近一か月</label>
397 <label><input type="radio" name="term" value="1">指定の期間: </label>
398 <input type="text" id="term_from" style="width: 8em">~<input type="text" id="term_to" style="width: 8em">
399 <input type="button" id="term_apply" value="適用">
400 </p>
401 </form>
402
403 <ul class="contents">
404 <li class="hide">
405 <table id="log0">
406 <thead>
407 <tr><th>日付</th><th>海域</th><th>マス</th><th>ボス</th><th>ランク</th><th>ドロップ艦種</th><th>ドロップ艦娘</th></tr>
408 </thead>
409 </table>
410
411 <li class="hide">
412 <table id="log1">
413 <thead>
414 <tr><th>日付</th><th>海域</th><th>マス</th><th>ボス</th><th>ランク</th><th>艦隊行動</th><th>味方陣形</th><th>敵陣形</th><th>敵艦隊</th><th>味方艦1</th><th>味方艦1HP</th><th>味方艦2</th><th>味方艦2HP</th><th>味方艦3</th><th>味方艦3HP</th><th>味方艦4</th><th>味方艦4HP</th><th>味方艦5</th><th>味方艦5HP</th><th>味方艦6</th><th>味方艦6HP</th><th>敵艦1</th><th>敵艦1HP</th><th>敵艦2</th><th>敵艦2HP</th><th>敵艦3</th><th>敵艦3HP</th><th>敵艦4</th><th>敵艦4HP</th><th>敵艦5</th><th>敵艦5HP</th><th>敵艦6</th><th>敵艦6HP</th></tr>
415 </thead>
416 </table>
417
418 <li class="hide">
419 <table id="log2">
420 <thead>
421 <tr><th>日付</th><th>結果</th><th>遠征</th><th>燃料</th><th>弾薬</th><th>鋼材</th><th>ボーキ</th><th>開発資材</th><th>高速修復材</th><th>高速建造材</th></tr>
422 </thead>
423 </table>
424
425 <li class="hide">
426 <table id="log3">
427 <thead>
428 <tr><th>日付</th><th>開発装備</th><th>種別</th><th>燃料</th><th>弾薬</th><th>鋼材</th><th>ボーキ</th><th>秘書艦</th><th>司令部Lv</th></tr>
429 </thead>
430 </table>
431
432 <li class="hide">
433 <table id="log4">
434 <thead>
435 <tr><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></tr>
436 </thead>
437 </table>
438
439 <li class="hide">
440 <table id="log5">
441 <thead>
442 <tr><th>日付</th><th>燃料</th><th>弾薬</th><th>鋼材</th><th>ボーキ</th><th>高速建造材</th><th>高速修復材</th><th>開発資材</th><th>改修資材</th></tr>
443 </thead>
444 </table>
445
446 <li class="hide">
447 <ul class="tab tab1" style="float: left">
448 <li>一日</li>
449 <li>一週間</li>
450 <li>一か月</li>
451 <li>すべて</li>
452 </ul>
453 <label><input type="checkbox" id="tooltip" value="">ツールチップ</label>
454 <div id="chart" style="clear: both; width: 800px; margin: 1em;"></div>
455
456 <li class="hide">
457 <h3>今日</h3>
458 <table id="sortie_stat_day">
459 <thead>
460 <tr><th>マップ</th><th>出撃</th><th>S</th><th>A</th><th>B</th><th>C</th><th>D以下</th></tr>
461 </thead>
462 </table>
463
464 <h3>今週</h3>
465 <table id="sortie_stat_week">
466 <thead>
467 <tr><th>マップ</th><th>出撃</th><th>S</th><th>A</th><th>B</th><th>C</th><th>D以下</th></tr>
468 </table>
469
470 <h3>今月</h3>
471 <table id="sortie_stat_month">
472 <thead>
473 <tr><th>マップ</th><th>出撃</th><th>S</th><th>A</th><th>B</th><th>C</th><th>D以下</th></tr>
474 </table>
475 </ul>
476 </body>
477 </html>