1const 2adminFormHtml = 3`<form id="adminForm"> 4<ul> 5<li><a id="history"><i class="history"></i>å¦ç¿å±¥æ´ãè¦ã</a> 6<li><a id="coverage"><i class="coverage"></i>éæåº¦ãè¦ã</a> 7<li><a id="testgroup"><i class="testgroup"></i>試é¨åå¥ã®æç¸¾ãè¦ã</a> 8<li><a id="progress"><i class="progress"></i>å¦ç¿ã®æ¨ç§»ãè¦ã</a> 9<li><a id="review"><i class="review"></i>ééããåé¡ã復ç¿ãã</a> 10<li><a id="unanswer"><i class="unanswer"></i>æªåçåé¡ã ããåºé¡ãã</a> 11<li><a id="bookmark"><i class="bookmark"></i>ãã§ãã¯ããåé¡ãåºé¡ãã</a> 12<li><a id="bookmark_edit"><i class="bookmark_edit"></i>ãã§ãã¯ããåé¡ã®ç®¡ç</a> 13<li class="not-membership-menu"><a href="/membership/" id="membership_register"><i class="membership"></i>ã¡ã³ãã¼ã·ããã«ç»é²ãã</a> 14<li class="membership-menu"><a href="/membership/tokuten/" target="_blank"><i class="tokuten"></i>ã¡ã³ãã¼ã·ããç¹å ¸</a> 15<li><a id="account"><i class="account"></i>ã¢ã«ã¦ã³ã管ç</a> 16<li><a id="logout">ãã°ã¢ã¦ã</a> 17</ul> 18</form>`; 19 20$(function(){ 21var 22mode = null, 23maxQcount = function(){ return 50 }; 24 25$('body').append('<output id="stateMessage" role="state"></output><div id="overLayerWrap"><div id="overLayer"></div></div>');//closeBtnã®é¢ä¿ã§overlayerãå¾ã«ãã 26 27//ããããã¼ã¸ã®ã¿ååã®é¸ææ°ã¨ååã®é¸æåéãèªåé©ç¨ 28if ($('#doujoulogo')[0]) { 29 localStorage.removeItem("CBT"); 30 31 const checkCat = localStorage.getItem("CHECK_CATEGORIES"); 32 if (checkCat) { 33 $('[name="categories[]"]').val(checkCat.split(',')); 34 } 35 const checkTime = localStorage.getItem("CHECK_TIMES"); 36 if (checkTime) { 37 $('[name="times[]"]').val(checkTime.split(',')); 38 } 39} 40 41$('#tabs > div').hide(); 42if (isReview() || isUnanswer() || isBookmark()) { 43 //ã¿ãé¨åã«ã¡ãã»ã¼ã¸ã¨ãã¿ã³ã追å 44 let mes1, mes2; 45 if (isReview()) { 46 mes1 = 'å¦ç¿å±¥æ´å ã®å¾©ç¿'; 47 mes2 = '復ç¿'; 48 } else if (isUnanswer()) { 49 mes1 = 'æªåçåé¡ã®åºé¡'; 50 mes2 = 'æªåç'; 51 } else if (isBookmark()) { 52 mes1 = 'ãã§ãã¯åé¡ã®åºé¡'; 53 mes2 = '復ç¿'; 54 } 55 $('#tabs').append('<div class="content" style="display:block">ç¾å¨ã'+mes1+'ä¸ã§ãã'+mes2+'ã¢ã¼ããçµäºããã«ã¯è©¦é¨åæå®ã»åéæå®çã®åã¿ãã鏿ãã¦ãããæ¬¡ã®åé¡ããã¿ã³ãæ¼ãã¦ãã ããã</div>'); 56 57 //ç´åã®é¸æç¶æ ã復å 58 $('#tabs > ul:not(:has(.active)) a').on('click.restoreSelect', function() { 59 const checkCat = localStorage.getItem("CHECK_CATEGORIES"); 60 if (checkCat) { 61 $('#configform [name="categories[]"]').val(checkCat.split(',')); 62 updateSmallCategoryCount(); 63 } 64 $('#tabs > ul a').off('click.restoreSelect'); 65 return false; 66 }) 67} else { 68 if ($('#tabs li.active a')[0]) { 69 mode = $('#tabs li.active a').attr('href').replace(/#tab/, ''); 70 $('#tab'+mode).show(); 71 } 72} 73if (isMoshi()) { 74 const mes = '模æ¬è©¦é¨ã¢ã¼ãä¸ã®ãããªãã·ã§ã³ã»'; 75 const btn = '模æ¬è©¦é¨ã¢ã¼ããçµäºãã'; 76 $('#tabs').hide().before('<div id="reviewWrap" class="content">â»ç¾å¨ã'+mes+'åºé¡ç¯å²ã®æå®ãã§ãã¾ããã<div class="img_margin"><button type="button" id="review_end">'+btn+'</button></div></div>'); 77 78 $('#configform').on('click', '#review_end', function(){ 79 if (isMoshi()) { 80 $('#tabs>ul>li.active').remove(); 81 $('#tabs>ul>li').first().addClass('active'); 82 $('#tab1').show(); 83 } 84 $('#reviewWrap').remove(); 85 $('#tabs').fadeIn('fast'); 86 }) 87} 88$('#tabs>ul a[href="#tab4"]').click(function(){ 89 if (!$('#tab4').html()) { 90 var matrix = {}; 91 var q = $('#configform [name="q"]').val().split(','); 92 var r = ($('#configform [name="r"]').val() + ',' + $('#result').val()).split(','); 93 94 for (var len=q.length,i=len-1; i>=0; i--) { 95 if (!q[i]) continue; 96 //ç´åã®1åã®ã¿ãè¨é²(_r[i]ã®åãã§ãã¯ãå ¥ããã¨æªåçåé¡ã追å ããã¦ãã¾ã) 97 if (matrix[q[i]] === undefined && r[i] != 0) { 98 matrix[q[i]] = r[i]; 99 } 100 } 101 var reviewArr = []; 102 for (var key in matrix) { 103 if (matrix[key] == 2) {
104 reviewArr.push(key); 105 } 106 } 107 reviewArr.reverse(); 108 var reviewCount = reviewArr.length; 109 var html = ''; 110 if (reviewCount === 0) { 111 html = 'è¦ç´ã対象åé¡ã¯ããã¾ããã'; 112 } else { 113 html = 'è¦ç´ã対象å顿°ã¯<b>'+reviewCount+'</b>åã§ãã<br>'; 114 var dispMax = 20; 115 for (i=0; i<=reviewCount-1; i++) { 116 if (i == dispMax) { 117 html += '<br>ãã®ä»ã'+(reviewCount-dispMax)+'å'; 118 break; 119 } 120 var qidObj = splitQid(reviewArr[i]); 121 html += '<span>'+AD2year_wa(getDirname(qidObj.eid))+' å'+qidObj.q+'</span>'; 122 } 123 } 124 $('#tab4').html('<div class="content">'+html+'</div>'); 125 } 126}) 127if (mode == 4) { 128 $('#tabs>ul a[href="#tab4"]').click(); 129} 130$('button[name="check_all"]').click(function(){ 131 const f = $(this).html() == "ON"; 132 const isTimes = $(this).is('#tab1 [name="check_all"]'); 133 $('[type="checkbox"]', $(this).parent().next()).prop('checked', f); 134 updateSmallCategoryCount(); 135 136 if (isTimes) { 137 updateCheckTime(); 138 } else { 139 updateCheckCat(); 140 } 141}) 142$('button[name="recommend"]').click(function(){ 143 const last12 = getAllTimes().slice(-12); 144 $('.input_times [type="checkbox"]').val(last12); 145 updateSmallCategoryCount(); 146 updateCheckTime(); 147}) 148$('input[name="fields[]"], .input_categories>dt>.count').click(function(e){ 149 let cb, f; 150 if ($(this).is('.count')) { 151 cb = $(this).prev(); 152 f = !cb.prop("checked"); 153 } else { 154 cb = $(this); 155 f = cb.prop("checked"); 156 } 157 const dd = $(this).parent().next(); 158 $('[type="checkbox"]', dd).prop('checked', f); 159 160 updateBigCategoryCount(cb.val()); 161 updateCheckCat(); 162 163 e.stopPropagation(); 164}) 165$('input[name="categories[]"]').change(function(){ 166 updateBigCategoryCount($(this).val()[0]); 167 updateCheckCat(); 168}) 169$('input[name="times[]"]').change(function(){ 170 updateSmallCategoryCount(); 171 updateCheckTime(); 172}) 173function updateSmallCategoryCount(){ 174 const times = $('input[name="times[]"]:checked').map(function(){ 175 return $('input[name="times[]"]').index($(this)); 176 }).get(); 177 const len = times.length; 178 179 $('input[name="categories[]"]').each(function(){ 180 const dataCount = $(this).attr('data-count'); 181 let cnt = 0; 182 for (let i=0; i<len; i++) { 183 cnt += Number(dataCount.charAt(times[i])); 184 } 185 $(this).siblings('.count').text(cnt); 186 }) 187 for (let i=1; i<=bunyalen; i++) { 188 updateBigCategoryCount(i); 189 } 190} 191function updateBigCategoryCount(idx){ 192 var count = 0, checkflag = false; 193 var dt = $('.input_categories dt').eq(idx-1); 194 $('[type="checkbox"]', dt.next()).each(function(){ 195 var elem = $(this).nextAll('.count'); 196 if ($(this).prop('checked')) { 197 checkflag = true; 198 count += Number(elem.text()); 199 } 200 }); 201 $('.count', dt).text(count); 202 $('[type="checkbox"]', dt).prop("checked", checkflag); 203} 204function updateCheckCat() { 205 const checkCat = $('input[name="categories[]"]:checked').map(function(){ 206 return $(this).val(); 207 }).get(); 208 209 if (checkCat.length) { 210 localStorage.setItem("CHECK_CATEGORIES", checkCat.join(',')); 211 } else { 212 localStorage.removeItem("CHECK_CATEGORIES"); 213 } 214} 215function updateCheckTime() { 216 const checkTime = $('input[name="times[]"]:checked').map(function(){ 217 return $(this).val(); 218 }).get(); 219 220 if (checkTime.length) { 221 localStorage.setItem("CHECK_TIMES", checkTime.join(',')); 222 } else { 223 localStorage.removeItem("CHECK_TIMES"); 224 } 225} 226updateSmallCategoryCount(); 227 228//ãªãã·ã§ã³ãã§ãã¯ããã¯ã¹ã®åæ 229$('.options [type="checkbox"]').change(function(){ 230 $('.options [value="'+$(this).val()+'"]').prop('checked', $(this).prop('checked')); 231}) 232$('body').on('click', '.sendConfigform', function(){ 233 if (!validateConfigform()) return false; 234 235 $('#configform').submit(); 236}) 237function validateConfigform(){ 238 function showError(mes) { 239 $('#configform').show(); 240 $('.error', $('#configform')).html(mes).fadeIn('fast'); 241 $('html,body').animate({ scrollTop: $('#tabs').offset().top-40 }, 'normal'); 242 } 243 $('.error', $('#configform')).html('').hide(); 244 245 if ($('#tabs .active')[0]) { 246 mode = $('#tabs .active a').attr('href').replace(/#tab/, ''); 247 $('[name="mode"]', $('#configform')).val(mode); 248 } 249 if ((mode == 1 || mode == 2) && ($('#tab1 .input_times input:checked').length === 0 || $('#tab2 .input_categories input:checked').length === 0)) { 250 showError('â»è©¦é¨åã¨åéãå1ã¤ä»¥ä¸ãã§ãã¯ãã¦ãã ããã'); 251 return false;
252 } 253 if (mode == 4 && !$('#tab4 span')[0]) { 254 showError('â»è¦ç´ã対象åé¡ãããã¾ããã<br>試é¨åã¾ãã¯åéã§åºé¡ç¯å²ãæå®ãã¦ãã ããã'); 255 return false; 256 } 257 if (mode == 3 && $('[value="harf"]').prop('checked') && !$('#loginBtn.member')[0]) { 258 showError('模æ¬è©¦é¨ã®å顿°æå®ã¯ã¡ã³ãã¼éå®ã®æ©è½ã§ãã<br>åºé¡éå§ããã«ã¯ã¡ã³ãã¼ã¨ãã¦ãã°ã¤ã³ããããã§ãã¯ãã¯ããã¦ãã ããã'); 259 return false; 260 } 261 return true; 262} 263$("#config").click(function(){ 264 if ($('#configform').is(':visible')) { 265 $(this).html('<i class="config"></i>åºé¡è¨å®'); 266 $('#configform').hide(); 267 } else { 268 $(this).html('â²éãã'); 269 $('#configform').show(); 270 } 271 return false; 272}) 273$('#pdf_print, #pdf_download').click(function(){ 274 var form = $('<form></form>', { 275 'action' : './generate_test.php', 276 'method' : 'post', 277 'target' : '_blank' 278 }); 279 var compo = ''; 280 compo += '<input type="hidden" name="q" value="'+$(this).attr('id').split('_').pop()+'">'; 281 compo += '<input type="hidden" name="moshi" value="'+$('#configform [name="moshi"]:checked').val()+'">'; 282 $('#tab3 [name="options[]"]:checked').each(function(){ 283 compo += '<input type="hidden" name="'+$(this).val()+'" value="1">'; 284 }) 285 compo += '<input type="hidden" name="moshi_cnt" value="'+$('#configform [name="moshi_cnt"]').val()+'">'; 286 form.html(compo).appendTo($('body')).submit(); 287}) 288 289var ranking = ''; 290function loadUserlog($i){ 291 var dfd = new $.Deferred(); 292 if (!$.isEmptyObject(userlog)) { 293 dfd.resolve(); 294 return dfd.promise(); 295 } 296 297 const iClass = $i.attr('class'); 298 $i.attr('class', 'loading large'); 299 300 var inputParams = { 301 "action" : 'load' 302 }; 303 $.ajax({ 304 type : "POST", 305 url : ajaxScript, 306 cache : false, 307 data : $.param(inputParams), 308 dataType : "json"}) 309 .done(function(data){ 310 if (data.status == "success") { 311 userlog = data.log; 312 ranking = data.ranking; 313 dfd.resolve(); 314 } else if (data.status == "error") { 315 switch (data.errorcode) { 316 case 1: showStateMessage('<i class="caution"></i>ã¾ã å¦ç¿å±¥æ´ã1åãè¨é²ããã¦ãã¾ããã'); break; 317 case 2: showStateMessage('<i class="ng"></i>ã¨ã©ã¼ã«ããå¦ç¿å±¥æ´ãåå¾ã§ãã¾ããã§ããã'); break; 318 case 3: showStateMessage('<i class="ng"></i>æéçµéã«ãããã°ã¤ã³ç¶æ ãåãã¦ãã¾ããåãã°ã¤ã³ãã¦ã試ããã ããã'); break; 319 } 320 dfd.reject(); 321 } 322 }).fail(function(){ 323 dfd.reject(); 324 }).always(function(){ 325 $i.attr('class', iClass); 326 }); 327 return dfd.promise(); 328} 329$('#showReport').click(function() { 330 history(); 331 return false; 332}) 333$('body').on('click', '#history', function(){ 334 if (!uid || !$('#loginBtn').hasClass('login')) { 335 showStateMessage('<i class="caution"></i>䏿£ãªãªã¯ã¨ã¹ãã§ãã'); 336 return false; 337 } 338 const $i = $('i', $(this)); 339 loadUserlog($i).done(function(){ 340 history('all'); 341 }); 342 return false; 343}) 344$('#overLayer').on('change', '[name="targetDate"]', function(){ 345 if ($(this).val() !== "custom") { 346 $('.customDateWrap').hide(); 347 history($(this).val()); 348 } else { 349 $('.rankingStr').hide(); 350 $('.customDateWrap').fadeIn('fast'); 351 } 352}) 353$('#overLayer').on('click', '#custom_ok', function(){ 354 history("custom"); 355}) 356async function history(target) { 357 var i, len, d = [], report = ''; 358 359 if (!target) { 360 var _q = $('#configform [name="q"]').val().split(','), 361 _r = $('#configform [name="r"]').val().split(','), 362 _c = $('#configform [name="c"]').val().split(','); 363 if (!isErrorPage()) { 364 _q.pop(); 365 _c.pop(); 366 } 367 var time = Math.floor(Date.now() / 1000); 368 for (i=0,len=_q.length; i<len; i++) { 369 d.push(time+','+_q[i]+','+_r[i]+','+_c[i]); 370 } 371 } else { 372 d = narrowData(target); 373 } 374 375 if (d.length === 0) { 376 report = '<div id="reportWrap" style="height:650px">'+emptySVG('ãã®æéã®ãã¼ã¿ã¯ããã¾ãã')+'</div>'; 377 } else { 378 const q2c = await getQ2c(); 379 //大åé¡ãã¨ã®åºé¡æ°ã»æ£è§£æ°ã»æ£è§£çãéè¨ãã夿¬¡å é å 380 var bData = []; 381 for (j=0; j<=2; j++) { 382 bData[j] = []; 383 for (i=0; i<=bunyalen; i++) { 384 bData[j].push(0); 385 } 386 } 387 //ä¸åé¡ãã¨ã®åºé¡æ°ã»æ£è§£æ°ã»æ£è§£çãéè¨ãã夿¬¡å é å 388 var mData = []; 389 for (k=1; k<=bunyalen; k++) { 390 mData[k] = []; 391 for (j=0; j<=2; j++) { 392 mData[k][j] = []; 393 len = bunyalist[k].length; 394 for (i=1; i<len; i++) { 395 mData[k][j][i] = 0; 396 } 397 } 398 } 399 400 bData[0][0] = d.length; 401 bData[1][0] = $.grep(d, function(val){ return val.indexOf(',1,') !== -1; }).length; 402 bData[2][0] = (bData[1][0] / bData[0][0] * 100).toFixed(1); 403 404 var qdata, qid, categoryId, midx, sidx; 405 for (i=0,len=d.length; i<len; i++){ 406 if (!d[i]) continue; 407 qdata = d[i].split(','); 408 qid = qdata[1]; 409 categoryId = q2c[qid].split('_'); 410 midx = Number(categoryId[0]); 411 sidx = Number(categoryId[1]); 412 bData[0][midx]++; 413 mData[midx][0][sidx]++; 414 if (qdata[2] === "1"){ 415 bData[1][midx]++; 416 mData[midx][1][sidx]++; 417 } 418 } 419 //åéãã¨ã®æ£è§£çãè¨ç®ãåéãã¨ã®HTMLãçæ 420 var overviewHtml = '', resultClass, percentage; 421 for (i=1; i<=bunyalen; i++) { 422 if (bData[0][i] > 0) { 423 bData[2][i] = (bData[1][i] / bData[0][i] * 100).toFixed(1); 424 percentage = bData[2][i]+'<span class="unit">%</span>'; 425 } else { 426 percentage = ''; 427 } 428 resultClass = (bData[0][i] > 0) ? (bData[2][i] >= passRate) ? ' over' : ' under' : '';
429 overviewHtml += '<dt>'+bunyalist[i][0]+'<dd><p>'+bData[0][i]+'åä¸ '+bData[1][i]+'åæ£è§£</p><p class="percentage'+resultClass+'">'+percentage+'</p>'; 430 try { 431 overviewHtml += '<input type="checkbox" name="more_check" id="more_check'+i+'" class="more_check"><label for="more_check'+i+'" class="more_btn"></label><div class="more_table_wrap">'; 432 overviewHtml += '<table class="more_table"><tr><th>ç´°ç®<th>æ£è§£/åºé¡<th>æ£è§£ç'; 433 var sub_percentage, n1, n2; 434 for (j=1; j<bunyalist[i].length; j++) { 435 if (mData[i][0][j]) { 436 n1 = mData[i][0][j]; 437 n2 = mData[i][1][j]; 438 } else { 439 n1 = n2 = 0; 440 } 441 if (n1 > 0) { 442 sub_percentage = (Math.round(n2 / n1 * 1000) / 10)+'%'; 443 } else { 444 sub_percentage = '-'; 445 } 446 midx = i; 447 sidx = j; 448 overviewHtml += '<tr><td>'+bunyalist[midx][sidx]+'<td>'+n2+' / '+n1+'<td>'+sub_percentage; 449 } 450 overviewHtml += '</table></div>'; 451 } catch (e) { 452 console.log(e.message); 453 } 454 } 455 //ååã®ãã¼ã¿ãåæ 456 var detailRow = '', processingDate = '', currentDate = '', span_open = '', span_end = ''; 457 historyTableRow = []; 458 for (i=0,len=d.length; i<len; i++){ 459 if (!d[i]) continue; 460 qdata = d[i].split(','); 461 span_open = span_end = ''; 462 processingDate = new Date(qdata[0]*1000).toyyyymmdd(); 463 if (processingDate > currentDate) { 464 currentDate = processingDate; 465 span_open = '<span class="dem" data-date="'+currentDate.slice(0,4)+'.'+Number(currentDate.slice(4,6))+'.'+Number(currentDate.slice(6,8))+'">'; 466 span_close = '</span>'; 467 } 468 qid = qdata[1]; 469 var qidObj = splitQid(qid); 470 var dirname = getDirname(qidObj.eid), q = qidObj.q; 471 var year_wa = AD2year_wa(dirname, true); 472 categoryId = q2c[qid].split('_'); 473 midx = Number(categoryId[0]); 474 sidx = Number(categoryId[1]); 475 var bunya = bunyalist[midx][sidx]; 476 resultClass = (qdata[2] === "1") ? 'maru' : (qdata[2] == 2) ? 'batu' : 'un'; 477 detailRow += '<tr><td>'+span_open+(i+1)+span_end+'<td><a href="/kakomon/'+dirname+'/'+('0'+q).slice(-2)+'.html" target="_blank">'+year_wa+' å'+q+'</a><td>'+bunya+'<td><i class="'+resultClass+'"></i>'; 478 if (i % 100 == 99) { 479 historyTableRow.push(detailRow); 480 detailRow = ''; 481 } 482 } 483 historyTableRow.push(detailRow); 484 const detailHtml = historyTableRow.shift(); 485 486 var rankingStr = ''; 487 if (target && target != 'custom' && ranking && /^[0-9]+\/[0-9]+$/.test(ranking)) { 488 var ranknum_userCount = ranking.split('/'); 489 var ranknum = Number(ranknum_userCount[0]) || '- '; 490 var userCount = Number(ranknum_userCount[1]); 491 var crown = ''; 492 if (ranknum <= 3) { 493 crown = '<i class="rank'+(4 - ranknum)+'" style="transform:scale(1.8);transform-origin:center bottom;margin-right:1em"></i>'; 494 } 495 rankingStr = '<div class="rankingStr">'+crown+'ç·åã©ã³ãã³ã°ã<span><span>'+ranknum+'</span> ä½</span> /'+userCount.toLocaleString("ja-JP")+'人ä¸</div>'; 496 } 497 498 var ls = ''; 499 if (bData[0][0] >= 10000) { 500 ls = ' style="letter-spacing:0"'; 501 } 502 503 report = 504`<div id="reportWrap"> 505<style> 506.more_check{display:none} 507.more_btn{cursor:pointer;position:absolute;width:22px;height:22px;bottom:100%;right:0;border-radius:50%;user-select:none} 508.more_btn:hover{box-shadow:0 0 4px rgba(var(--pure-black), 0.3)} 509.more_btn::before, .more_btn::after{content:"";position:absolute;width:10px;height:2px;top:50%;left:6px;margin-top:-1px;background:#999;transition:0.4s} 510.more_btn::after{transform:rotate(90deg)} 511.more_check:checked + .more_btn::after{opacity:0;transform:rotate(360deg)} 512.more_table_wrap{width:100%;position:absolute;left:103%;top:0;z-index:1;transform:translateY(-50%) scale(1, 0);transition:transform 0.6s var(--spring-snappy)} 513.more_check:checked + .more_btn + .more_table_wrap{transform:translateY(-50%) scale(1, 1)} 514.more_table{width:100%;font-size:12px;background:var(--main-bg);border:1px solid var(--color-eee);box-shadow:4px 4px 8px rgba(var(--pure-black),0.1)} 515.more_table tr:nth-child(odd){background:var(--main-bg-sub)} 516.more_table th, .more_table td{white-space:nowrap;padding:5px 8px} 517.more_table td{color:var(--color-444)} 518.more_table::before, .more_table::after{content:"";display:block;position:absolute;width:0;height:0;border:8px solid transparent;border-right-color:var(--color-eee);top:calc(50% - 1.75em);right:100%} 519.more_table::after{border-right-color:var(--main-bg);right:calc(100% - 1px)} 520@media (max-width:770px){ 521.more_table_wrap{position:static;height:0;overflow:hidden} 522.more_check:checked + .more_btn + .more_table_wrap{height:auto;padding:10px 0;transform:none} 523.more_table{box-shadow:none} 524.more_table::before, .more_table::after{display:none} 525} 526</style> 527<div class="overview"> 528<h3>æ¦è¦</h3> 529<div class="content"> 530<dl><dt class="total"${ls}><span class="unit">ðç·å: </span>${bData[0][0]}<span class="unit">åä¸</span>${bData[1][0]}<span class="unit">åæ£è§£</span> 531<p id="canvas_percentage" data-percentage="${bData[2].join(',')}"><span id="NoP"></span><span class="unit">%</span></p> 532</dt></dl>${rankingStr} 533<div id="raderChart">
534<canvas id="canvas_rader_front" width="560" height="420"></canvas> 535<canvas id="canvas_rader_back" width="560" height="420"></canvas> 536</div> 537</div> 538<div class="content"> 539<dl>${overviewHtml}</dl> 540</div> 541</div> 542<div class="detail"> 543<div id="csv-download" style="float:right;font-size:0.75rem;cursor:pointer"><span class="material-symbols-outlined" style="font-size:20px">download</span>CSVå½¢å¼ã§ãã¦ã³ãã¼ã</div> 544<h3>詳細</h3> 545<div class="historyTableWrap" style="clear:both"><table><tr class="h"><td>#<td>åºå ¸<td>åé<td>çµæ${detailHtml}</table></div> 546</div> 547</div>`; 548 } 549 if ($('body').hasClass('modal')) { 550 $('#reportWrap').fadeOut(300, function(){ 551 $(this).replaceWith(report).show(); 552 tableLazyLoad(); 553 updateGraph(); 554 }); 555 } else { 556 const h2 = isMoshi() ? '模æ¬è©¦é¨çµæ' : 'å¦ç¿å±¥æ´åæ'; 557 const header = '<h2>'+h2+'</h2>'; 558 let selectHtml = ''; 559 if (target) { 560 const today = new Date().toyyyymmdd(true); 561 562 const lastYear = new Date(); 563 lastYear.setFullYear(lastYear.getFullYear() - 1); 564 565 const savedStVal = localStorage.getItem('CUSTOM_START_DATE'); 566 const savedEdVal = localStorage.getItem('CUSTOM_END_DATE'); 567 const stVal = isValidDateString(savedStVal) && savedStVal <= today 568 ? savedStVal 569 : lastYear.toyyyymmdd(true); 570 const edVal = isValidDateString(savedEdVal) && savedEdVal <= today 571 ? savedEdVal 572 : today; 573 574 selectHtml = 575`<div class="datePicker"> 576ç¾å¨ã®æé » <select name="targetDate"> 577<option value="all">å ¨æé 578<option value="today">仿¥ï¼ç¾æç¹ã¾ã§ï¼ 579<option value="yesterday">æ¨æ¥ 580<option value="thisMonth">仿ï¼ç¾æç¹ã¾ã§ï¼ 581<option value="lastMonth">å æ 582<option value="past7days">éå»7æ¥é 583<option value="past30days">éå»30æ¥é 584<option value="past90days">éå»90æ¥é 585<option value="past180days">éå»180æ¥é 586<option value="past1years">éå»1å¹´é 587<option value="custom">ã«ã¹ã¿ã ã®æé 588</select> 589<div class="customDateWrap" style="display:none"> 590<input type="date" name="startDate" min="2017-01-01" max="${today}" value="${stVal}"> ï½ 591<input type="date" name="endDate" min="2017-01-01" max="${today}" value="${edVal}"> <button id="custom_ok">表示</button> 592</div> 593</div>`; 594 } 595 showModal(header+selectHtml+report); 596 tableLazyLoad(); 597 updateGraph(); 598 } 599} 600$('body').on('click', '#testgroup', function(){ 601 if (!uid || !$('#loginBtn').hasClass('login')) { 602 showStateMessage('<i class="caution"></i>䏿£ãªãªã¯ã¨ã¹ãã§ãã'); 603 return false; 604 } 605 const $i = $('i', $(this)); 606 loadUserlog($i).done(function(){ 607 testgroup(); 608 }); 609 return false; 610}) 611$('#overLayer').on('change', '[name="targetTest"]', function(){ 612 testgroup($(this).val()); 613}) 614async function testgroup(target) { 615 var results = []; 616 var arr = getAllTimes().reverse(); 617 target = target || arr[0]; //targetã空ãªãææ°è©¦é¨ 618 619 const q2c = await getQ2c(); 620 621 var i, len, d = []; 622 d = narrowData(target); 623 //åéãã¨ã®ãã¼ã¿ãéè¨ //0è¦ç´ ç®ã¯å ¨æç¸¾ç¨ 1ï½bunyalenã¯åéãã¨ã®æç¸¾ 624 var bData = []; 625 for (j=0; j<=2; j++) { 626 bData[j] = []; 627 for (i=0; i<=bunyalen; i++) { 628 bData[j].push(0); 629 } 630 } 631 632 bData[0][0] = d.length; 633 bData[1][0] = $.grep(d, function(val){ return val.indexOf(',1,') !== -1; }).length; 634 bData[2][0] = (bData[1][0] / bData[0][0] * 100).toFixed(1) || '-'; 635 636 for (i=0,len=d.length; i<len; i++){ 637 if (!d[i]) continue; 638 var qdata = d[i].split(','); 639 var qid = qdata[1]; 640 var categoryId = q2c[qid]; 641 var midx = categoryId.split('_')[0]; 642 643 bData[0][midx]++; 644 if (qdata[2] === "1"){ 645 bData[1][midx]++; 646 } 647 var qidObj = splitQid(qid); 648 var q = qidObj.q; 649 if (results[q] === undefined) { 650 results[q] = ''; 651 } 652 results[q] += String(qdata[2]); 653 } 654 //åéãã¨ã®æ£è§£çãè¨ç®ãåéãã¨ã®HTMLãçæ 655 var overviewHtml = '', resultClass, percentage; 656 for (i=1; i<=bunyalen; i++) { 657 if (bData[0][i] > 0) { 658 bData[2][i] = (bData[1][i] / bData[0][i] * 100).toFixed(1); 659 percentage = bData[2][i]+'<span class="unit">%</span>'; 660 } else { 661 percentage = ''; 662 } 663 resultClass = (bData[0][i] > 0) ? (bData[2][i] >= passRate) ? ' over' : ' under' : '';
664 overviewHtml += '<dt>'+bunyalist[i][0]+'<dd><p>'+bData[0][i]+'åä¸ '+bData[1][i]+'åæ£è§£</p><p class="percentage'+resultClass+'">'+percentage+'</p></dd>'; 665 } 666 //ååã®ãã¼ã¿ãåæ 667 var detailHtml = '', dirname = getDirname(target); 668 const maxQ = maxQcount(dirname); 669 for (i=1,len=maxQ; i<=len; i++){ 670 var current_correctStr = 'æªåºé¡', current_correctProb = '-', resultClass = '', historyStr = ''; 671 if (results[i]) { 672 current_qCount = results[i].length; //åãã¨ã®åºé¡æ° 673 current_correctCount = results[i].split('1').length-1; //åãã¨ã®æ£è§£æ° 674 current_correctStr = 'æ£è§£ '+current_correctCount+' / '+current_qCount; 675 current_correctProb = Math.round(current_correctCount / current_qCount * 1000) / 10; //åãã¨ã®æ£è§£ç 676 historyStr = results[i].replace(/1/g, '<i class="maru"></i>').replace(/2/g, '<i class="batu"></i>').replace(/0/g, '<i class="un"></i>'); 677 resultClass = (current_correctProb >= passRate) ? 'ok' : (current_correctProb >= passRate-20) ? 'caution' : 'ng'; 678 current_correctProb += '%'; 679 } 680 var qid = target+'_'+i; 681 var categoryId = q2c[qid].split('_'); 682 var midx = categoryId[0]; 683 var sidx = categoryId[1]; 684 var bunya = bunyalist[midx][sidx]; 685 detailHtml += '<tr class="tr-first"><td rowspan="2"><a href="/kakomon/'+dirname+'/'+('0'+i).slice(-2)+'.html" target="_blank">å'+i+'</a><td>'+bunya+'<td>'+current_correctStr+'<td><span class="'+resultClass+'">'+current_correctProb+'</span><tr class="tr-second"><td colspan="3">'+historyStr; 686 } 687 688 const report = 689`<div id="reportWrap"> 690<div class="overview"> 691<h3>æ¦è¦</h3> 692<div class="content"> 693<dl><dt class="total"><span class="unit">ðç·å: </span>${bData[0][0]}<span class="unit">åä¸</span>${bData[1][0]}<span class="unit">åæ£è§£</span> 694<p id="canvas_percentage" data-percentage="${bData[2].join(',')}"><span id="NoP"></span><span class="unit">%</span></p> 695</dt></dl> 696<div id="raderChart"> 697<canvas id="canvas_rader_front" width="560" height="420"></canvas> 698<canvas id="canvas_rader_back" width="560" height="420"></canvas> 699</div> 700</div> 701<div class="content"> 702<dl>${overviewHtml}</dl> 703</div> 704</div> 705<div class="detail"> 706<h3>詳細</h3> 707<div class="historyTableWrap"><table class="testgroup"><tr class="h"><td>№<td>åé<td>çµæ<td>æ£è§£ç${detailHtml}</table></div> 708</div> 709</div>`; 710 711 if ($('body').hasClass('modal')) { 712 $('#reportWrap').fadeOut(300, function(){ 713 $(this).replaceWith(report).show(); 714 updateGraph(); 715 }); 716 } else { 717 var header = '<h2>試é¨åå¥åæ</h2>'; 718 var options = ''; 719 for (i=0,len=arr.length; i<len; i++){ 720 var year_wa = AD2year_wa(getDirname(arr[i])); 721 options += '<option value="'+arr[i]+'">'+year_wa; 722 } 723 var selectHtml = '<div class="datePicker">ç¾å¨ã®è©¦é¨ » <select name="targetTest">'+options+'</select></div>'; 724 725 showModal(header+selectHtml+report); 726 updateGraph(); 727 } 728} 729function updateGraph(){ 730 if (!$('#canvas_percentage')[0]) return; 731 732 const animTime1 = 1500, animTime2 = 1500, cx = 140, cy = 105, max_r = 85; 733 let r, x, y, x1, x2, y1, y2, px = [], py = []; 734 735 const probs = $('#canvas_percentage').attr('data-percentage').split(','); 736 const anglelen = probs.length - 1; 737 let cr = $('#canvas_rader_back').get(0).getContext('2d'); 738 739 const Nop = probs[0] || NaN; 740 animateNumber('NoP', 0, Nop, animTime1, 1) 741 742 //ã¬ã¼ããã£ã¼ã(å è§å½¢) 743 cr.scale(2, 2); 744 cr.lineWidth = 1; 745 cr.fillStyle = getStyleValue('--color-ddd'); 746 cr.strokeStyle = getStyleValue('--color-ddd'); 747 cr.textBaseline = "bottom"; 748 cr.textAlign = "right"; 749 cr.font = '9px'+fm; 750 751 for (var i=1; i<=5; i++) { 752 r = max_r / 5 * i; 753 x = r * Math.sqrt(3) / 2; 754 y = r * 0.5; 755 cr.beginPath(); 756 cr.moveTo(cx, cy-r); 757 cr.lineTo(cx+x, cy-y); 758 cr.lineTo(cx+x, cy+y); 759 cr.lineTo(cx, cy+r); 760 cr.lineTo(cx-x, cy+y); 761 cr.lineTo(cx-x, cy-y); 762 cr.closePath(); 763 cr.stroke(); 764 cr.fillText((i * 20) + '%', cx, cy - r + 2); 765 } 766 767 x = max_r * Math.sqrt(3) / 2; 768 y = max_r * 0.5; 769 cr.strokeStyle = getStyleValue('--color-ccc'); 770 for (i=1; i<=3; i++) { 771 cr.beginPath(); 772 switch (i) { 773 case 1: x1 = cx; y1 = cy-max_r; 774 x2 = cx; y2 = cy+max_r; 775 break; 776 case 2: x1 = cx+x; y1 = cy-y; 777 x2 = cx-x; y2 = cy+y; 778 break; 779 case 3: x1 = cx-x; y1 = cy-y; 780 x2 = cx+x; y2 = cy+y; 781 break; 782 } 783 cr.moveTo(x1, y1); 784 cr.lineTo(x2, y2); 785 cr.stroke(); 786 } 787 788 //åéåãåºå 789 cr.fillStyle = getStyleValue('--color-555'); 790 cr.font = 'bold 12px'+fm; 791 const lineHeight = cr.measureText("ã").width; 792 const normalFont = '12px' + fm; 793 const boldFont = 'bold 11px' + fm; 794 const positions = [ 795 null, 796 { x: cx, y: cy-max_r-7, align: 'center', baseline: 'bottom' }, 797 { x: cx+x+3, y: cy-y-3, align: 'left', baseline: 'bottom' }, 798 { x: cx+x+3, y: cy+y+3, align: 'left', baseline: 'bottom' }, 799 { x: cx, y: cy+max_r-5, align: 'center', baseline: 'top' }, 800 { x: cx-x-3, y: cy+y+3, align: 'right', baseline: 'bottom' }, 801 { x: cx-x-3, y: cy-y-3, align: 'right', baseline: 'bottom' }, 802 ]; 803 for (i=1; i<=anglelen; i++) { 804 const pos = positions[i]; 805 if (!pos) continue; 806 807 cr.textAlign = pos.align; 808 cr.textBaseline = pos.baseline; 809 810 cr.font = normalFont; 811 cr.fillText(bunyalist_short[i], pos.x, pos.y); 812 813 cr.font = boldFont; 814 cr.fillText(probs[i] + '%', pos.x, pos.y + lineHeight); 815 } 816 817 //åéæç¸¾ãæç¹ 818 for (i=1; i<=anglelen; i++) { 819 r = max_r * probs[i] / 100; 820 x = r * Math.sqrt(3) / 2; 821 y = r * 0.5; 822 switch (i) { 823 case 1: px[i] = cx; py[i] = cy-r; 824 break; 825 case 2: px[i] = cx+x; py[i] = cy-y; 826 break; 827 case 3: px[i] = cx+x; py[i] = cy+y; 828 break; 829 case 4: px[i] = cx; py[i] = cy+r; 830 break; 831 case 5: px[i] = cx-x; py[i] = cy+y; 832 break; 833 case 6: px[i] = cx-x; py[i] = cy-y; 834 break; 835 } 836 //cr.fillStyle = 'rgba(230,152,0,.8)'; 837 //cr.fillRect(px[i]-2, py[i]-2, 4, 4); 838 } 839 px.push(px[1]); py.push(py[1]); //å¤è§å½¢ã®æå¾ç¨ 840 841 cr = $('#canvas_rader_front').get(0).getContext('2d'); 842 cr.scale(2, 2); 843 cr.fillStyle = 'rgba(255,232,162,.2)'; 844 cr.strokeStyle = 'rgba(230,152,0,.8)'; 845 cr.lineWidth = 2; 846 var stx, sty, edx, edy, dx, dy, mx, my, weight; 847 let startTime = null; 848 function loop2(timestamp){ 849 if (!startTime) startTime = timestamp; 850 var e = Math.min((timestamp - startTime) / animTime2, 1); //ããªç§åä½ 851 cr.clearRect(0, 0, cx*2, cy*2); 852 cr.beginPath(); 853 cr.moveTo(cx, cy); //ããªã´ã³éå§ä½ç½® 854 var phase = Math.floor(e * 6) +1; 855 for (var i=1; i<=phase+1; i++) { 856 cr.lineTo(px[i], py[i]); 857 } 858 stx = px[phase]; sty = py[phase]; 859 edx = px[phase+1]; edy = py[phase+1]; 860 dx = edx - stx; 861 dy = edy - sty; 862 const local = e * 6 - (phase - 1); 863 weight = (local < 0.2) ? 0 : local * 1.25 - 0.25; 864 mx = stx + dx * weight; 865 my = sty + dy * weight; 866 cr.lineTo(mx, my); 867 cr.closePath(); 868 cr.fill(); 869 cr.beginPath(); 870 cr.moveTo(px[1], py[1]); //ããªã´ã³æ éå§ä½ç½® 871 for (i=2; i<=phase; i++) { 872 cr.lineTo(px[i], py[i]); 873 } 874 cr.lineTo(mx, my); 875 cr.stroke(); 876 877 if (e < 1) window.requestAnimationFrame(loop2); 878 } 879 window.requestAnimationFrame(loop2); 880} 881let historyTableRow = null; 882function tableLazyLoad(){ 883 $tableWrap = $('.historyTableWrap'); 884 $table = $tableWrap.find('table'); 885 $lastRow = $('tr', $table).eq(-15); 886 const $scrollElem = $(window).width() > 768 ? $tableWrap : $('#overLayer'); 887 $scrollElem.scroll(function(){ 888 if (!historyTableRow.length) { 889 $scrollElem.off('scroll'); 890 return; 891 } 892 // 表示é åã®ä¸ç«¯ã®ä½ç½®
893 const scrollElemBottom = $scrollElem.height() + $scrollElem.offset().top; 894 // æ«å°¾ã®è¦ç´ ã®ä¸ç«¯ã®ä½ç½® 895 const lastRowTop = $lastRow.offset().top; 896 if (lastRowTop < scrollElemBottom) { 897 $table.append(historyTableRow.shift()); 898 $lastRow = $('tr', $table).eq(-15); 899 } 900 }); 901} 902$('#overLayer').on('click', '.coverageTableWrap a', function(){ 903 var matchs = $(this).attr('href').match(/\/(20[0-9]{2})\/([0-9]{2})\.html$/); 904 if (matchs && confirm(AD2year_wa(matchs[1], true)+' å'+Number(matchs[2])+'ãæ°ããã¿ãã§éãã¾ãã')) { 905 return true; 906 } 907 return false; 908}) 909$('body').on('click', '#coverage', function(){ 910 if (!uid || !$('#loginBtn').hasClass('login')) { 911 showStateMessage('<i class="caution"></i>䏿£ãªãªã¯ã¨ã¹ãã§ãã'); 912 return false; 913 } 914 const $i = $('i', $(this)); 915 loadUserlog($i).done(function(){ 916 coverage(); 917 }); 918 return false; 919}) 920function coverage() { 921 var matrix = {}; 922 var arr = getAllTimes().reverse(); 923 for (var i=0,len=arr.length; i<len; i++) { 924 matrix[arr[i]] = []; 925 } 926 for (i=0,len=userlog.length; i<len; i++) { 927 if (!userlog[i]) continue; 928 var qdata = userlog[i].split(','); 929 var r = qdata[2]; 930 if (!Number(r)) continue; 931 932 var qidObj = splitQid(qdata[1]); 933 var eid = qidObj.eid, q = qidObj.q; 934 if (matrix[eid]) { 935 if (matrix[eid][q] === undefined) { 936 matrix[eid][q] = ''; 937 } 938 matrix[eid][q] += String(r); 939 } 940 } 941 let totalCount=0, totalAnswerCount=0, rankCount = [0,0,0,0], rows=''; 942 //åçªå·ã®è¡ã追å 943 rows += '<tr class="header"><td class="fixedCol"> '; 944 const maxCol = maxQcount(2020); 945 for (i=1; i<=maxCol; i++) { 946 rows += '<td>'+i; 947 } 948 for (i=0,len=arr.length; i<len; i++) { 949 var eid = arr[i]; 950 var dirname = getDirname(eid); 951 var year_wa = AD2year_wa(dirname, true); 952 var maxQ = maxQcount(dirname); 953 var star = Object.keys(matrix[eid]).length == maxQ ? '<span class="star">â </span>' : ''; 954 rows += '<tr><td class="fixedCol">'+year_wa+star; 955 let partAnswerCount = 0; 956 for (var j=1; j<=maxQ; j++) { 957 let rank, panelTitle; 958 if (matrix[eid][j] && matrix[eid][j] != 0) {//åçæ´ãããå ´å 959 const last2 = ('0' + matrix[eid][j]).slice(-2); 960 if (last2 == '11') { 961 rank = 3; 962 } else if (last2.charAt(1) == '1') { 963 rank = 2; 964 } else if (last2.charAt(1) == '2') { 965 rank = 1; 966 } 967 rankCount[rank]++; 968 partAnswerCount++; 969 panelTitle = matrix[eid][j].replace(/2/g, 'Ã').replace(/1/g, 'â').replace(/0/g, 'ï¼'); 970 } else { 971 panelTitle = 'æªåºé¡'; 972 rank = '-'; 973 } 974 rows += '<td title="'+panelTitle+'"><a href="/kakomon/'+dirname+'/'+('0'+j).slice(-2)+'.html" target="_blank"><i class="rank'+rank+'"></i></a>'; 975 } 976 totalCount += maxQ; 977 totalAnswerCount += partAnswerCount; 978 } 979 980 const coveragePer = (totalAnswerCount / totalCount * 100).toFixed(1); 981 const rankReiewBtn = []; 982 const dashOffset = []; 983 const dashArray = []; 984 const gap = 0.4; 985 dashOffset[3] = 0; 986 for (let i=3; i>=1; i--) { 987 const rankPer = (rankCount[i] / totalCount * 100).toFixed(1); 988 dashArray[i] = Math.max(rankPer - gap, 0) + ',100'; 989 dashOffset[i-1] = dashOffset[i] - rankPer; 990 rankReiewBtn[i] = rankCount[i] ? '<button class="rank-review-btn" data-target="rank'+i+'">復ç¿</button>' : '<button disabled style="visibility:hidden">復ç¿</button>'; 991 } 992 993 const html = 994`<h2>éæåº¦åæ</h2> 995<div class="coverageSummary"> 996<div class="donutGraphWrap"> 997<svg class="donutGraph" viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg"> 998<defs> 999<filter id="innerShadowLike" x="-50%" y="-50%" width="200%" height="200%"> 1000<feDropShadow dx="-0.3" dy="0.3" stdDeviation="1" flood-color="rgb(0 0 0 / 15%)"/> 1001</filter> 1002<linearGradient id="goldGrad" x1="0%" y1="0%" x2="100%" y2="100%"> 1003<stop offset="0%" stop-color="#F59E0B" /> 1004<stop offset="50%" stop-color="#FDE68A" /> 1005<stop offset="100%" stop-color="#F59E0B" /> 1006</linearGradient> 1007<linearGradient id="silverGrad" x1="0%" y1="0%" x2="100%" y2="100%"> 1008<stop offset="0%" stop-color="#a7b5c7" /> 1009<stop offset="50%" stop-color="#e6e6e6" /> 1010<stop offset="100%" stop-color="#a7b5c7" /> 1011</linearGradient> 1012<linearGradient id="bronzeGrad" x1="0%" y1="0%" x2="100%" y2="100%"> 1013<stop offset="0%" stop-color="#914200" />
1014<stop offset="50%" stop-color="#FDBA74" /> 1015<stop offset="100%" stop-color="#914200" /> 1016</linearGradient> 1017</defs> 1018<circle id="donutBackground" cx="18" cy="18" r="15.915" fill="transparent" stroke="var(--color-eee)" stroke-width="4" class="donut-ring"></circle> 1019<circle id="ringRank1" cx="18" cy="18" r="15.915" fill="transparent" stroke="url(#bronzeGrad)" stroke-width="4" class="donut-ring donutProgress"></circle> 1020<circle id="ringRank2" cx="18" cy="18" r="15.915" fill="transparent" stroke="url(#silverGrad)" stroke-width="4" class="donut-ring donutProgress"></circle> 1021<circle id="ringRank3" cx="18" cy="18" r="15.915" fill="transparent" stroke="url(#goldGrad)" stroke-width="4" class="donut-ring donutProgress"></circle> 1022<circle cx="18" cy="18" r="14" fill="var(--main-bg)" filter="url(#innerShadowLike)"></circle> 1023</svg> 1024<div class="donutGraph-text"><div class="text-top">ðï¸éæç</div><div class="text-percentage"><span id="NoP"></span><span class="unit">%</span></div><div class="text-bottom">${totalAnswerCount} / ${totalCount} å</div></div> 1025</div> 1026<div class="rank3"><div class="summary-img"><i class="rank3"></i></div><div class="summary-text"><div class="summary-text-label">é£ç¶æ£è§£ä¸</div><div class="summary-text-num">${rankCount[3]}<span class="unit"> å</span></div></div>${rankReiewBtn[3]}</div> 1027<div class="rank2"><div class="summary-img"><i class="rank2"></i></div><div class="summary-text"><div class="summary-text-label">ååæ£è§£</div><div class="summary-text-num">${rankCount[2]}<span class="unit"> å</span></div></div>${rankReiewBtn[2]}</div> 1028<div class="rank1"><div class="summary-img"><i class="rank1"></i></div><div class="summary-text"><div class="summary-text-label">åå䏿£è§£</div><div class="summary-text-num">${rankCount[1]}<span class="unit"> å</span></div></div>${rankReiewBtn[1]}</div> 1029<span id="review_ok" style="display:none"></span> 1030</div> 1031<div class="coverageTableWrap"> 1032<table>${rows}</table> 1033â»è¡¨ã®åã»ã«ãã¯ãªãã¯ããã¨ããã®åé¡ãæ°ããã¿ãã§éãã¾ãã`; 1034 showModal(html, "coverage"); 1035 1036 setTimeout(function(){ 1037 animateNumber('NoP', 0, coveragePer, 2000, 1) 1038 $('#donutBackground').css('stroke-dashoffset', 0); 1039 $('#ringRank3').css({ 1040 'stroke-dashoffset': dashOffset[3], 1041 'stroke-dasharray': dashArray[3], 1042 }); 1043 $('#ringRank2').css({ 1044 'stroke-dashoffset': dashOffset[2], 1045 'stroke-dasharray': dashArray[2], 1046 }); 1047 $('#ringRank1').css({ 1048 'stroke-dashoffset': dashOffset[1], 1049 'stroke-dasharray': dashArray[1], 1050 }); 1051 }, 300); 1052} 1053function loadChartJS() 1054{ 1055 var dfd = new $.Deferred(); 1056 if (typeof Chart == 'function') { 1057 dfd.resolve(); 1058 return dfd.promise(); 1059 } else { 1060 var script1 = document.createElement('script'); 1061 script1.src = 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js'; 1062 script1.async = false; 1063 script1.onload = function() { 1064 var script2 = document.createElement('script'); 1065 script2.async = false; 1066 script2.src = 'https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.2.0/chartjs-plugin-datalabels.min.js'; 1067 script2.onload = function() { 1068 dfd.resolve(); 1069 } 1070 script2.onerror = function() { 1071 dfd.reject(); 1072 } 1073 document.body.appendChild(script2); 1074 } 1075 script1.onerror = function() { 1076 dfd.reject(); 1077 } 1078 document.body.appendChild(script1); 1079 } 1080 return dfd.promise(); 1081} 1082$('#overLayer').on('change', '[name="targetPeriod"]', function(){ 1083 progress($(this).val()); 1084}) 1085//å¦ç¿æ¨ç§»åæ 1086$('body').on('click', '#progress', function(){ 1087 if (!uid || !$('#loginBtn').hasClass('login')) { 1088 showStateMessage('<i class="caution"></i>䏿£ãªãªã¯ã¨ã¹ãã§ãã'); 1089 return false; 1090 } 1091 const $i = $('i', $(this)); 1092 loadUserlog($i).done(function(){ 1093 loadChartJS().done(function() { 1094 progress('4'); 1095 }); 1096 }); 1097 return false; 1098}) 1099 1100function progress(weekCount) { 1101 const DAY_PER_WEEK = 7; 1102 const SECOND_PER_DAY = 86400; 1103 1104 function drawGraph() 1105 { 1106 var i, j; 1107 var dataCount = totalResult.length; 1108 var dayWeek, colorPrefix; 1109 if (daysInSection == 1) { 1110 dayWeek = 'æ¥'; 1111 colorPrefix = 'rgb'; 1112 } else { 1113 dayWeek = 'é±'; 1114 colorPrefix = 'rgba'; 1115 } 1116 //Object.assignãstructuredCloneã§ã¯é¢æ°ããã£ã¼ãã³ãã¼ã§ããªãï¼åç §æ¸¡ãã«ãªãï¼ 1117 var questionOptions = { 1118 devicePixelRatio: Math.max(2, window.devicePixelRatio), 1119 responsive: true, 1120 maintainAspectRatio: false, 1121 scales: { 1122 y1: { 1123 grace: '15%', 1124 position: 'left', 1125 min: 0, 1126 suggestedMax: 50, 1127 ticks: { 1128 font: {size: 10}, 1129 padding: 0, 1130 maxTicksLimit: 6, 1131 callback: function(value) { 1132 return value+'å'; 1133 } 1134 }, 1135 grid: { 1136 tickLength: 2, 1137 }, 1138 }, 1139 y2: { 1140 display: false, 1141 min: 0, 1142 suggestedMax: 50, 1143 }, 1144 x: { 1145 ticks: { 1146 color: getStyleValue('--color-666'), 1147 font: {size: 10}, 1148 maxRotation: 0, 1149 }, 1150 grid: {display: false} 1151 } 1152 }, 1153 plugins: { 1154 tooltip: { 1155 callbacks: { 1156 title: function(ctx) { 1157 if (ctx[0].dataset.borderColor.indexOf('rgba') != -1) { 1158 //m/d - m/d 1159 var m_d = ctx[0].label.split('/'); 1160 var d = new Date(new Date().getFullYear(), m_d[0]-1, m_d[1]); 1161 d.setDate(d.getDate()-6); 1162 return (d.getMonth()+1)+'/'+d.getDate()+' - '+ctx[0].label; 1163 } else { 1164 //m/d 1165 return ctx[0].label; 1166 } 1167 }, 1168 }, 1169 }, 1170 legend: { 1171 reverse: true, 1172 labels: { 1173 color: getStyleValue('--color-666'), 1174 }, 1175 }, 1176 }, 1177 layout: { 1178 padding: {right: 8} 1179 }, 1180 }; 1181 1182 var accuracyOptions = { 1183 devicePixelRatio: Math.max(2, window.devicePixelRatio), 1184 responsive: true, 1185 maintainAspectRatio: false, 1186 scales: { 1187 y: { 1188 grace: '15%', 1189 position: 'left', 1190 suggestedMin: 50, 1191 max: 100, 1192 ticks: { 1193 font: {size: 10}, 1194 stepSize: 10, 1195 padding: 0, 1196 callback: function(value) { 1197 return value+'%'; 1198 } 1199 }, 1200 grid: { 1201 color: getStyleValue('--color-eee'), 1202 tickLength: 2, 1203 }, 1204 }, 1205 x: { 1206 ticks: { 1207 color: getStyleValue('--color-666'), 1208 font: {size: 10}, 1209 maxRotation: 0, 1210 }, 1211 grid: {display: false} 1212 } 1213 }, 1214 plugins: { 1215 tooltip: { 1216 callbacks: { 1217 title: function(ctx) { 1218 if (ctx[0].dataset.borderColor.indexOf('rgba') != -1) { 1219 //m/d - m/d 1220 var m_d = ctx[0].label.split('/'); 1221 var d = new Date(new Date().getFullYear(), m_d[0]-1, m_d[1]); 1222 d.setDate(d.getDate()-6); 1223 return (d.getMonth()+1)+'/'+d.getDate()+' - '+ctx[0].label; 1224 } else { 1225 //m/d 1226 return ctx[0].label; 1227 } 1228 }, 1229 }, 1230 }, 1231 legend: { 1232 reverse: true, 1233 labels: { 1234 color: getStyleValue('--color-666'), 1235 }, 1236 }, 1237 }, 1238 layout: { 1239 padding: {right: 8} 1240 }, 1241 }; 1242
1243 var line_datalabels = { 1244 font: {size: 10}, 1245 borderRadius: 4, 1246 backgroundColor: 'rgb(228,67,67)', 1247 color: '#fff', 1248 padding: 2, 1249 display: function(ctx) { 1250 if (!ctx.dataset.data[ctx.dataIndex]) { 1251 return false; 1252 } 1253 var step = Math.ceil(30 / (ctx.chart.chartArea.width / dataCount)); 1254 return (ctx.dataIndex + 1 - dataCount) % step && 1255 (!isNaN(ctx.dataset.data[ctx.dataIndex-1]) || !isNaN(ctx.dataset.data[ctx.dataIndex+1])) 1256 ? false : true; 1257 }, 1258 align: function(ctx) { 1259 return ctx.dataset.data[ctx.dataIndex] % 100 ? 'end' : 'center'; 1260 }, 1261 formatter: function(value, ctx) { 1262 if (ctx.dataset.label.indexOf('å顿°') !== -1) { 1263 return value ? value+'å' : ''; 1264 } else { 1265 return Number(value).toFixed(0)+'%'; 1266 } 1267 } 1268 }; 1269 var bar_datalabels = { 1270 color: getStyleValue('--color-444'), 1271 font: {size: 10}, 1272 anchor: 'end', 1273 align: 'end', 1274 offset: 0, 1275 display: false, 1276 /*function(ctx) { 1277 return false; 1278 var step = Math.ceil(30 / (ctx.chart.chartArea.width / dataCount)); 1279 return (ctx.dataIndex + 1 - dataCount) % step && 1280 (ctx.dataset.data[ctx.dataIndex-1] || ctx.dataset.data[ctx.dataIndex+1]) 1281 ? false : true; 1282 } 1283 formatter: function(value, ctx) { 1284 if (ctx.dataset.label.indexOf('å顿°') !== -1) { 1285 return value ? value+'å' : ''; 1286 } else { 1287 return value ? Number(value).toFixed(0)+'%' : ''; 1288 } 1289 }*/ 1290 }; 1291 var line_obj = { 1292 type: 'line', 1293 tension: 0.2, 1294 borderWidth: 2, 1295 pointStyle: 'cross', 1296 pointBorderWidth: 1, 1297 backgroundColor: 'transparent', 1298 borderColor: colorPrefix+'(228,67,67,1)', 1299 pointRadius: 2, 1300 spanGaps: true, 1301 datalabels: line_datalabels, 1302 } 1303 var bar_obj = { 1304 type: 'bar', 1305 barPercentage: 0.95, 1306 categoryPercentage: 1, 1307 datalabels: bar_datalabels, 1308 } 1309 1310 var dataset1 = []; 1311 var dataset2 = []; 1312 1313 //æãç·ã°ã©ãï¼ç´¯è¨ï¼åé¢ã»å¾é¢ã®é¢ä¿ã§å ã«ï¼ 1314 var obj1 = Object.assign({}, line_obj); 1315 obj1.label = 'å顿°ï¼ç´¯è¨ï¼'; 1316 obj1.yAxisID = 'y2'; 1317 1318 var obj2 = Object.assign({}, line_obj); 1319 obj2.label = 'æ£è§£çï¼ç´¯è¨ï¼'; 1320 obj2.yAxisID = 'y'; 1321 1322 //datasets.dataãè¨å® 1323 var questionDatasets = []; 1324 var accuracyDatasets = []; 1325 for (j=0; j<dataCount; j++) { 1326 questionDatasets.push(totalResult[j].category[0]); 1327 if (totalResult[j].category[0]) { 1328 accuracyDatasets.push((totalResult[j].correct / totalResult[j].category[0] * 100).toFixed(1)); 1329 } else { 1330 accuracyDatasets.push(0); 1331 } 1332 } 1333 1334 obj1.data = questionDatasets; 1335 dataset1.push(obj1); 1336 obj2.data = accuracyDatasets; 1337 dataset2.push(obj2); 1338 1339 //æ£ã°ã©ãï¼åºé 1340 obj1 = Object.assign({}, bar_obj); 1341 obj1.label = 'å顿°ï¼'+dayWeek+'ï¼'; 1342 obj1.yAxisID = 'y1'; 1343 obj1.borderColor = colorPrefix+'(255,200,99,0.8)'; 1344 obj1.backgroundColor = 'rgba(255,200,99,0.6)'; 1345 1346 obj2 = Object.assign({}, bar_obj); 1347 obj2.label = 'æ£è§£çï¼'+dayWeek+'ï¼'; 1348 obj2.borderColor = colorPrefix+'(54,162,235,0.8)'; 1349 obj2.backgroundColor = 'rgba(54,162,235,0.6)'; 1350 obj2.yAxisID = 'y'; 1351 1352 questionDatasets = []; 1353 accuracyDatasets = []; 1354 for (j=0; j<dataCount; j++) { 1355 questionDatasets.push(periodResult[j].category[0]); 1356 if (periodResult[j].category[0]) { 1357 accuracyDatasets.push((periodResult[j].correct / periodResult[j].category[0] * 100).toFixed(1)); 1358 } else { 1359 accuracyDatasets.push(0); 1360 } 1361 } 1362 1363 obj1.data = questionDatasets; 1364 dataset1.push(obj1); 1365 obj2.data = accuracyDatasets; 1366 dataset2.push(obj2); 1367 1368 //åéãã¨ã¬ã¤ã³ãã¼ãã¼ã¸ã§ã³ 1369 /*for (i=1; i<=bunyalen; i++) { 1370 totalDatasets = []; 1371 periodDatasets = []; 1372 var obj1 = { 1373 type: 'bar', 1374 label: bunyanameShort[i], 1375 backgroundColor: colors[i], 1376 borderColor: colors[i], 1377 yAxisID: 'y1', 1378 datalabels: { 1379 display: false 1380 } 1381 } 1382 var obj2 = { 1383 type: 'bar', 1384 label: bunyanameShort[i], 1385 backgroundColor: colors[i], 1386 borderColor: colors[i], 1387 yAxisID: 'y1', 1388 datalabels: { 1389 display: false 1390 } 1391 } 1392 for (j=0; j<weeksInPeriod; j++) { 1393 totalDatasets.push(totalResult[j].category[i]); 1394 periodDatasets.push(periodResult[j].category[i]); 1395 } 1396 obj1.data = totalDatasets; 1397 totalGraphObj.data.datasets.push(obj1); 1398 obj2.data = periodDatasets; 1399 periodGraphObj.data.datasets.push(obj2); 1400 } 1401 */ 1402 1403 //x軸ã®ã©ãã«ãè¨å® 1404 var questionLabels = [], accuracyLabels = []; 1405 for (i=0; i<dataCount; i++) { 1406 //var st = new Date((periodStartTime + (SECOND_PER_DAY * daysInSection) * i) * 1000); 1407 var ed = new Date((periodStartTime + (SECOND_PER_DAY * daysInSection) * (i+1) - SECOND_PER_DAY) * 1000); 1408 1409 questionLabels.push((ed.getMonth() + 1)+'/'+ed.getDate()); 1410 accuracyLabels.push((ed.getMonth() + 1)+'/'+ed.getDate()); 1411 } 1412 1413 var ctx1 = document.getElementById('questionGraph').getContext('2d'); 1414 var ctx2 = document.getElementById('accuracyGraph').getContext('2d'); 1415 ctx1.canvas.height = 250; 1416 ctx2.canvas.height = 250; 1417 new Chart(ctx1, { 1418 plugins: [ChartDataLabels], 1419 data: { 1420 labels: questionLabels, 1421 datasets: dataset1 1422 }, 1423 options: questionOptions, 1424 }); 1425 new Chart(ctx2, { 1426 plugins: [ChartDataLabels], 1427 data: { 1428 labels: accuracyLabels, 1429 datasets: dataset2 1430 }, 1431 options: accuracyOptions, 1432 }); 1433 } 1434 1435 var i, len = [], report = ''; 1436 if (userlog.length === 0) { 1437 report = '<div id="reportWrap" style="height:632px">'+emptySVG('å¦ç¿å±¥æ´ãè¦ã¤ããã¾ãã')+'</div>'; 1438 } else { 1439 var midnight = new Date().setHours(0, 0, 0, 0) / 1000; 1440 var weeksInPeriod; 1441 if (weekCount == 'all') { 1442 var firstlog = userlog[0].split(','); 1443 var firstlogtime = new Date(firstlog[0] * 1000).getTime() / 1000; 1444 weeksInPeriod = Math.ceil((midnight - firstlogtime) / (SECOND_PER_DAY * DAY_PER_WEEK)); 1445 } else { 1446 weeksInPeriod = weekCount; 1447 } 1448 var periodStartTime = midnight - (SECOND_PER_DAY * DAY_PER_WEEK * weeksInPeriod); 1449 var daysInPeriod = weeksInPeriod * DAY_PER_WEEK; //対象æéã®ç·æ¥æ° 1450 var daysInSection = weeksInPeriod > 8 ? DAY_PER_WEEK : 1; //ãã¼ã¿1ã¤ã®éè¨æ¥æ° 1451 1452 //ååéã®å¦ç¿æ°ãéè¨ããããã®é å [0]ç·æ°ã[1]-[bunyalen]ååéã®æ° 1453 var categoryCnt = []; 1454 for (i=0; i<=bunyalen; i++) { 1455 categoryCnt.push(0); 1456 } 1457 1458 var 1459 current = 0, 1460 totalResult = [], 1461 totalCnt = categoryCnt.slice(); //é åã³ãã¼ 1462 totalCorrect = 0; 1463
1464 periodResult = [], 1465 periodCnt = categoryCnt.slice(); //é åã³ãã¼ 1466 periodCorrect = 0, 1467 1468 weekResult = [], 1469 periodDayCnt = 0, 1470 periodDay = []; 1471 1472 for (i=0,len=userlog.length; i<len; i++) { 1473 if (!userlog[i]) continue; 1474 var qdata = userlog[i].split(','); 1475 var time = qdata[0]; 1476 var r = qdata[2]; 1477 var c = qdata[3].charAt(0); 1478 1479 //仿¥ã®å¦ç¿å±¥æ´ã¾ã§éãããå¦çãæãã 1480 if (time >= midnight) { 1481 break; 1482 } 1483 if (time >= periodStartTime) { 1484 //éè¨å¯¾è±¡æ¥ã¾ã§é²ãã 1485 while (time >= (periodStartTime + SECOND_PER_DAY * (current+1))){ 1486 periodDay.push(periodDayCnt); 1487 periodDayCnt = 0; 1488 current++; 1489 if (current % daysInSection == 0) { 1490 //1é±éåã®ãã¼ã¿ãæ¸ãè¾¼ããé åã®åç §ãæ¸¡ããªãããã«ã³ãã¼ãã¦æ¸¡ã 1491 totalResult.push({'category': totalCnt.slice(), 'correct': totalCorrect}); 1492 periodResult.push({'category': periodCnt, 'correct': periodCorrect}); 1493 periodCnt = categoryCnt.slice(); //é åã³ãã¼ 1494 periodCorrect = 0; 1495 } 1496 if (current % DAY_PER_WEEK == 0) { 1497 weekResult.push(periodDay); 1498 periodDay = []; 1499 } 1500 } 1501 //éè¨å¯¾è±¡æéè¨é² 1502 periodCnt[0]++; 1503 periodCnt[c]++; 1504 if (r == 1) { 1505 periodCorrect++; 1506 } 1507 periodDayCnt++; 1508 } 1509 //å ¨æéè¨é² 1510 totalCnt[0]++; 1511 totalCnt[c]++; 1512 if (r == 1) { 1513 totalCorrect++; 1514 } 1515 } 1516 //å¾ãã®ç©ºç½æéãåãã 1517 while (current < daysInPeriod){ 1518 periodDay.push(periodDayCnt); 1519 periodDayCnt = 0; 1520 current++; 1521 if (current % daysInSection == 0) { 1522 //ç¾å¨ã®æéã®ãã¼ã¿ãæ¸ãè¾¼ã 1523 totalResult.push({'category': totalCnt.slice(), 'correct': totalCorrect}); 1524 periodResult.push({'category': periodCnt, 'correct': periodCorrect}); 1525 periodCnt = categoryCnt.slice(); //é åã³ãã¼ 1526 periodCorrect = 0; 1527 } 1528 if (current % DAY_PER_WEEK == 0) { 1529 weekResult.push(periodDay); 1530 periodDay = []; 1531 } 1532 } 1533 1534 var midnightDate = new Date(midnight * 1000); 1535 midnightDate.setDate(midnightDate.getDate() - 1); 1536 midnightDate = midnightDate.getFullYear()+'/'+(midnightDate.getMonth() + 1)+'/'+midnightDate.getDate(); 1537 var periodStartTimeDate = new Date(periodStartTime * 1000); 1538 periodStartTimeDate = periodStartTimeDate.getFullYear()+'/'+(periodStartTimeDate.getMonth() + 1)+'/'+periodStartTimeDate.getDate(); 1539 1540 var detailHtml = ''; 1541 var dayOfWeekStr = ["æ¥", "æ", "ç«", "æ°´", "æ¨", "é", "å"]; 1542 for (i=weekResult.length-1; i>=0; i--) { 1543 var flexItem = ''; 1544 var sum = 0; 1545 for (j=weekResult[i].length-1; j>=0; j--) { 1546 var date = new Date((periodStartTime + SECOND_PER_DAY * (DAY_PER_WEEK * i + j)) * 1000); 1547 date = (date.getMonth() + 1)+'/'+date.getDate()+'('+dayOfWeekStr[date.getDay()]+')'; 1548 var qcount = weekResult[i][j] ? '<b>'+weekResult[i][j]+'å</b>' : '<span class="un">'+weekResult[i][j]+'å</span>' 1549 flexItem += '<div><div class="day">'+date+'</div>'+qcount+'</div>'; 1550 sum += weekResult[i][j]; 1551 } 1552 var stDay = new Date((periodStartTime + SECOND_PER_DAY * DAY_PER_WEEK * i) * 1000); 1553 stDay = (stDay.getMonth() + 1)+'/'+stDay.getDate(); 1554 var edDay = new Date((periodStartTime + SECOND_PER_DAY * (DAY_PER_WEEK * i + 6)) * 1000); 1555 edDay = (edDay.getMonth() + 1)+'/'+edDay.getDate(); 1556 1557 var changeStr = '<span class="un">±0</span>'; 1558 if (i > 0) { 1559 var cnt1 = weekResult[i].reduce(function(sum, val){ 1560 return sum + val; 1561 }); 1562 var cnt2 = weekResult[i-1].reduce(function(sum, val){ 1563 return sum + val; 1564 }); 1565 if (cnt1 > cnt2) { 1566 changeStr = '<span style="color:#1fad52">â²+'+(cnt1-cnt2)+'</span>' 1567 } else if (cnt1 < cnt2) { 1568 changeStr = '<span style="color:#e34a4a">â¼ï¼'+(cnt2-cnt1)+'</span>' 1569 } 1570 } else { 1571 changeStr = ''; 1572 } 1573 detailHtml += '<div class="flexHeader">'+stDay+' - '+edDay+'</div><div id="flexTable">'+flexItem+'<div><div class="day">è¨<b>'+sum+'</b>å</div>'+changeStr+'</div></div>'; 1574 } 1575 1576 report = 1577`<div id="reportWrap"> 1578<style> 1579#reportWrap{flex-direction:column} 1580.radioTable{border:1px solid #555;border-radius:4px;width:max-content;margin:1em auto;font-size:90%;line-height:1.8} 1581.radioTable [type="radio"]{display:none} 1582.radioTable label{display:inline-block;width:100px}
1583.radioTable span{display:block;text-align:center;cursor:pointer} 1584.radioTable [type="radio"]:checked + span{background:#555;color:#fff} 1585#flexTable{display:flex} 1586#flexTable > div{box-sizing:border-box;background:var(--main-bg);flex:1;padding:5px 0;font-size:80%;border-bottom:1px solid var(--dark-border);text-align:center} 1587#flexTable > div b{font-size:120%} 1588.flexHeader{background:var(--main-bg-sub);font-size:80%;font-weight:bold;color:var(--color-444);padding-left:3px} 1589.progressGraphWrap{width:100%;overflow:hidden;background:var(--main-bg);user-select:none} 1590#progressGraph{display:flex;width:200%;transition:transform 0.3s ease-out;height:250px} 1591#progressGraph.slide{transform:translateX(-50%)} 1592#progressGraph > div{flex:1} 1593.progressTableWrap{max-height:280px;overflow-y:scroll;background:var(--main-bg)} 1594.un{color:#888} 1595@media (max-width:770px){ 1596.progressGraphWrap{padding-bottom:30px} 1597.progressTableWrap{max-height:none;overflow:auto} 1598} 1599@media (max-width:600px){ 1600#flexTable{flex-wrap:wrap} 1601#flexTable > div{flex-basis:25%} 1602} 1603</style> 1604<div class="progressGraphWrap"><h3>å¦ç¿å顿°ã¨æ£è§£çï¼${periodStartTimeDate} - ${midnightDate}ï¼</h3> 1605<div class="radioTable"> 1606<label><input type="radio" name="graphChange" value="1" checked><span>å顿°</span></label> 1607<label><input type="radio" name="graphChange" value="2"><span>æ£è§£ç</span></label> 1608</div> 1609<div id="progressGraph"> 1610<div><canvas id="questionGraph"></canvas></div> 1611<div><canvas id="accuracyGraph"></canvas></div> 1612</div> 1613</div> 1614<div class="progressTableWrap"><h3>æ¥ã ã®å¦ç¿ç¶æ³</h3>${detailHtml}</div> 1615</div>`; 1616 } 1617 if ($('body').hasClass('modal')) { 1618 $('#reportWrap').fadeOut(300, function(){ 1619 $(this).replaceWith(report).show(); 1620 setTimeout(drawGraph, 50); 1621 }); 1622 } else { 1623 var header = '<h2>å¦ç¿æ¨ç§»åæ</h2>'; 1624 var selectHtml = 1625`<div class="datePicker"> 1626ç¾å¨ã®æé » <select name="targetPeriod"> 1627<option value="all">å ¨æé 1628<option value="4" selected>éå»4é±é 1629<option value="8">éå»8é±é 1630<option value="13">éå»3ã«æé 1631<option value="26">éå»6ã«æé 1632<option value="52">éå»1å¹´é 1633</select> 1634</div>`; 1635 showModal(header+selectHtml+report); 1636 setTimeout(drawGraph, 350); 1637 } 1638} 1639$('body').on('change', '[name="graphChange"]', function(){ 1640 $('#progressGraph').toggleClass('slide'); 1641}); 1642 1643let confirmTableCache; 1644function getConfirmTable() { 1645 if (!confirmTableCache) { 1646 initReviewWindowEvents(); 1647 1648 const $div = $('<div>').append($('#tab2 .input_categories').clone()); 1649 $div.find('[type="checkbox"]:not(.dummy)').attr('checked', 'checked'); //Property夿´ã§ã¯åæ ãããªã 1650 const $dl = $div.html(); 1651 1652 confirmTableCache = 1653`<style> 1654#overLayer.review{width:650px;height:600px;display:flex;flex-direction:column} 1655#review-checkbox-wrap{flex:1;overflow:auto;scrollbar-gutter:stable;margin-bottom:72px} 1656#floatBtn{bottom:0 !important;padding:15px 0} 1657</style> 1658<dl class="confirmTable"><dt>対象å顿°<dd><i class="note"></i><span id="questionCount"></span></dl> 1659<div id="review-checkbox-wrap"> 1660<div class="checkall"><span>å ¨é ç®ãã§ãã¯</span> <button type="button" name="check_all" value="review-checkbox-wrap">ON</button> <button type="button" name="check_all" value="review-checkbox-wrap">OFF</button></div> 1661${$dl} 1662</div>`; 1663 } 1664 return confirmTableCache; 1665} 1666function updateFieldState($dt) 1667{ 1668 const $field = $dt.find('[name="fields[]"]'); 1669 const $categories = $dt.next('dd').find('[name="categories[]"]'); 1670 let count = 0; 1671 let checked = false; 1672 1673 $categories.each(function(){ 1674 if ($(this).prop('checked')) { 1675 checked = true; 1676 count += Number($(this).closest('label').children('.count').text()) || 0; 1677 } 1678 }); 1679 1680 $field.prop('checked', checked); 1681 $dt.children('.count').text(count); 1682} 1683function initReviewWindowEvents() 1684{ 1685 const $overLayer = $('#overLayer'); 1686 1687 $overLayer.on('click', '#review-checkbox-wrap .accordion dt', function(){ 1688 $(this).toggleClass('open'); 1689 }); 1690 $overLayer.on('click', '#review-checkbox-wrap [name="check_all"]', function(){ 1691 const f = $(this).html() == 'ON'; 1692 $('#review-checkbox-wrap [type="checkbox"]:not(.dummy)').prop('checked', f); 1693 updateQuestionCount(); 1694 }); 1695 $overLayer.on('click', '#review-checkbox-wrap [name="fields[]"], #review-checkbox-wrap .accordion dt>.count', function(e){ 1696 e.stopPropagation(); 1697 1698 const $dt = $(this).closest('dt'); 1699 const $field = $dt.find('[name="fields[]"]'); 1700 const checked = $(this).is('[name="fields[]"]') ? $field.prop('checked') : !$field.prop('checked'); 1701 1702 $field.prop('checked', checked); 1703 $dt.next('dd').find('[name="categories[]"]').prop('checked', checked); 1704 1705 updateQuestionCount($dt); 1706 }); 1707 $overLayer.on('click', '#review-checkbox-wrap [name="categories[]"]', function(){ 1708 const $dt = $(this).closest('dd').prev('dt'); 1709 updateQuestionCount($dt); 1710 }); 1711 1712 $overLayer.on('click', '#review_ok, #unanswer_ok, #bookmark_ok', function(){ 1713 let mode; 1714 if ($('#review_ok')[0]) { 1715 mode = 'review'; 1716 } else if ($('#unanswer_ok')[0]) { 1717 mode = 'unanswer'; 1718 } else if ($('#bookmark_ok')[0]) { 1719 mode = 'bookmark'; 1720 } 1721 1722 $('[name="mode"]', $('#configform')).val(mode); 1723 1724 //復ç¿å¯¾è±¡ã®é¸æåéã¨åéæå®ã®é¸æåéãåæããã 1725 const selectedCategories = $('#review-checkbox-wrap input[name="categories[]"]:checked').map(function(){ 1726 return this.value; 1727 }).get(); 1728 $('#configform .input_categories input[name="categories[]"]').val(selectedCategories); 1729 1730 $('#configform').submit(); 1731 }) 1732 $overLayer.on('click', '#review_cancel, #unanswer_cancel, #bookmark_cancel', function(){ 1733 hideModal(); 1734 }) 1735} 1736 1737$('body').on('click', '#review', function(){ 1738 if (!uid || !$('#loginBtn').hasClass('login')) { 1739 showStateMessage('<i class="caution"></i>䏿£ãªãªã¯ã¨ã¹ãã§ãã'); 1740 return false;
1741 } 1742 const $i = $('i', $(this)); 1743 loadUserlog($i).done(function(){ 1744 review(); 1745 }); 1746 return false; 1747}) 1748async function review() 1749{ 1750 const q2c = await getQ2c(); 1751 1752 const answered = {}; 1753 for (let i=0,len=userlog.length; i<len; i++) { 1754 if (!userlog[i] || userlog[i].indexOf(',0,') !== -1) continue; 1755 1756 const qdata = userlog[i].split(','); 1757 const qid = qdata[1]; 1758 const categoryId = q2c[qid] ?? qdata[3]; 1759 1760 if (!categoryId) continue; 1761 1762 if (!answered[categoryId]) { 1763 answered[categoryId] = {}; 1764 } 1765 answered[categoryId][qid] = qdata[2]; 1766 } 1767 1768 questionCounts = {}; 1769 for (const categoryId in answered) { 1770 questionCounts[categoryId] = Object.values(answered[categoryId]).filter(function(val){ 1771 return val == 2; 1772 }).length; 1773 } 1774 1775 const html = 1776`<h2>ééããåé¡ã®å¾©ç¿</h2> 1777<p style="margin:10px">ç´åã®1åã䏿£è§£ã ã£ãåé¡ï¼éæåº¦ã¬ãã¼ãã§ã®<i class="rank1"></i>ï¼ã ããåºé¡ãããã¨ãã§ãã¾ãã</p> 1778${getConfirmTable()} 1779<div id="floatBtn"><button id="review_cancel">ãã£ã³ã»ã«</button><button id="review_ok">復ç¿éå§</button></div>`; 1780 1781 showModal(html, 'review'); 1782 initCounts = true; 1783 updateQuestionCount(); 1784} 1785$('body').on('click', '#unanswer', function(){ 1786 if (!uid || !$('#loginBtn').hasClass('login')) { 1787 showStateMessage('<i class="caution"></i>䏿£ãªãªã¯ã¨ã¹ãã§ãã'); 1788 return false; 1789 } 1790 const $i = $('i', $(this)); 1791 loadUserlog($i).done(function(){ 1792 unanswer(); 1793 }); 1794 return false; 1795}) 1796async function unanswer() 1797{ 1798 const q2c = await getQ2c(); 1799 1800 if (!bunyaCounts) { 1801 bunyaCounts = {}; 1802 for (const qid in q2c) { 1803 const categoryId = q2c[qid]; 1804 if (bunyaCounts[categoryId] === undefined) { 1805 bunyaCounts[categoryId] = 0; 1806 } 1807 bunyaCounts[categoryId]++; 1808 } 1809 } 1810 1811 const answered = {}; 1812 for (let i=0, len=userlog.length; i<len; i++) { 1813 if (!userlog[i] || userlog[i].indexOf(',0,') !== -1) continue; 1814 1815 const qdata = userlog[i].split(','); 1816 const qid = qdata[1]; 1817 const categoryId = q2c[qid]; 1818 1819 if (!categoryId) continue; 1820 1821 if (!answered[categoryId]) { 1822 answered[categoryId] = new Set(); 1823 } 1824 answered[categoryId].add(qid); 1825 } 1826 1827 questionCounts = {}; 1828 for (const categoryId in answered) { 1829 questionCounts[categoryId] = answered[categoryId].size; 1830 } 1831 1832 const html = 1833`<h2>æªåçåé¡ã®åºé¡</h2> 1834<p style="margin:10px">ç¾å¨ã¾ã§ã«åçæ´ããªãåé¡ã ããåºé¡ãããã¨ãã§ãã¾ãã</p> 1835${getConfirmTable()} 1836<div id="floatBtn"><button id="unanswer_cancel">ãã£ã³ã»ã«</button><button id="unanswer_ok">åºé¡éå§</button></div>`; 1837 1838 showModal(html, 'review'); 1839 initCounts = true; 1840 updateQuestionCount(); 1841} 1842$('body').on('click', '#bookmark', function(){ 1843 if (!uid || !$('#loginBtn').hasClass('login')) { 1844 showStateMessage('<i class="caution"></i>䏿£ãªãªã¯ã¨ã¹ãã§ãã'); 1845 return false; 1846 } 1847 const $i = $('i', $(this)); 1848 loadBookmarkData($i).done(function(){ 1849 bookmark(); 1850 }); 1851 return false; 1852}) 1853async function bookmark() { 1854 const q2c = await getQ2c(); 1855 1856 const bookmarkCount = bookmarks.length || 0; 1857 const bookmarked = {}; 1858 for (let i=0; i<bookmarkCount; i++) { 1859 const qid = bookmarks[i]; 1860 const categoryId = q2c[qid]; 1861 1862 if (!categoryId) continue; 1863 1864 if (!bookmarked[categoryId]) { 1865 bookmarked[categoryId] = {}; 1866 } 1867 bookmarked[categoryId][qid] = 1; //ãã¼ã®ãªã¹ããåºæ¥ãã°ããã®ã§å ¥ãããã¼ã¿ã¯ä½ã§ãOK 1868 } 1869 1870 questionCounts = {}; 1871 for (const categoryId in bookmarked) { 1872 questionCounts[categoryId] = Object.keys(bookmarked[categoryId]).length; 1873 } 1874 1875 const html = 1876`<h2>ãã§ãã¯ããåé¡ã®å¾©ç¿</h2> 1877<p style="margin:10px">ãã§ãã¯ãä»ãã¦ããåé¡ã ããåºé¡ãããã¨ãã§ãã¾ãã</p> 1878${getConfirmTable()} 1879<div id="floatBtn"><button id="bookmark_cancel">ãã£ã³ã»ã«</button><button id="bookmark_ok">åºé¡éå§</button></div>`; 1880 1881 showModal(html, 'review'); 1882 initCounts = true; 1883 updateQuestionCount(); 1884} 1885 1886let questionCounts = {}, bunyaCounts = null, initCounts = false; 1887function updateQuestionCount($dt) 1888{ 1889 let mode = null, questionCount = 0, str = '', zeroMessage = ''; 1890 1891 if ($('#review_ok')[0]) { 1892 mode = 'review'; 1893 str = '復ç¿å¯¾è±¡'; 1894 } else if ($('#unanswer_ok')[0]) { 1895 mode = 'unanswer'; 1896 str = 'æªåç'; 1897 } else if ($('#bookmark_ok')[0]) { 1898 mode = 'bookmark'; 1899 str = 'ãã§ãã¯æ¸'; 1900 } 1901 1902 if (initCounts) { 1903 const $wrap = $('#review-checkbox-wrap'); 1904 $wrap.find('[name="categories[]"]').each(function(){ 1905 const categoryId = $(this).val(); 1906 let count = 0; 1907 1908 if (mode == 'unanswer') { 1909 count = (bunyaCounts[categoryId] ?? 0) - (questionCounts[categoryId] ?? 0); 1910 } else { 1911 count = questionCounts[categoryId] ?? 0; 1912 } 1913 $(this).closest('label').children('.count').text(count); 1914 }); 1915 initCounts = false;
1916 } 1917 1918 if ($dt && $dt.length) { 1919 updateFieldState($dt); 1920 } else { 1921 $('#review-checkbox-wrap .accordion dt').each(function(){ 1922 updateFieldState($(this)); 1923 }); 1924 } 1925 1926 $('#review-checkbox-wrap input[name="categories[]"]:checked').each(function(){ 1927 const categoryId = $(this).val(); 1928 1929 if (mode == 'review' || mode == 'bookmark') { 1930 if (questionCounts[categoryId] === undefined) return true; 1931 questionCount += questionCounts[categoryId]; 1932 } else { 1933 questionCount += (bunyaCounts[categoryId] ?? 0) - (questionCounts[categoryId] ?? 0); 1934 } 1935 }); 1936 1937 if (questionCount === 0) { 1938 zeroMessage = 'ãâ»'+str+'ã®åé¡ã¯ããã¾ããã'; 1939 $('#'+mode+'_ok').prop('disabled', true); 1940 } else { 1941 $('#'+mode+'_ok').prop('disabled', false); 1942 } 1943 $('#questionCount').html(questionCount+'å'+zeroMessage); 1944} 1945$('body').on('click', '.rank-review-btn', function(){ 1946 if ($(this).hasClass('action')) { 1947 const mode = $(this).data('target'); 1948 $('[name="mode"]', $('#configform')).val(mode); 1949 $('#configform').trigger("submit", [true]); 1950 } else { 1951 $('.rank-review-btn').removeClass('action').text('復ç¿'); 1952 $(this).addClass('action').html("éå§"); 1953 } 1954}) 1955//bookmark夿´ãã¼ã¯é¢é£ 1956function bookmarkChange(target, state) 1957{ 1958 if (!/^([0-9]{1,2}_[0-9]{1,2},?)*[0-9]{1,2}_[0-9]{1,2}$/.test(target) || $.inArray(state, ["true", "false"]) === -1) return false; 1959 var dfd = new $.Deferred(); 1960 var inputParams = { 1961 "target" : target, 1962 "state" : state, 1963 "action": "bookmark" 1964 }; 1965 $.ajax({ 1966 type : "POST", 1967 url : ajaxScript, 1968 cache : false, 1969 data : $.param(inputParams), 1970 dataType : "json"}) 1971 .done(function(data){ 1972 if (data.status == "success") { 1973 bookmark_change = true; 1974 dfd.resolve(); 1975 } else if (data.status == "error") { 1976 dfd.reject(); 1977 } 1978 }).fail(function(d, s){ 1979 dfd.reject(); 1980 }) 1981 return dfd.promise(); 1982} 1983let bookmarks = [], bookmark_change = true; 1984function loadBookmarkData($i) { 1985 var dfd = new $.Deferred(); 1986 if (!bookmark_change) { 1987 dfd.resolve(); 1988 return dfd.promise(); 1989 } 1990 1991 const iClass = $i.attr('class'); 1992 $i.attr('class', 'loading large'); 1993 1994 var inputParams = { 1995 "action" : "loadbookmark" 1996 }; 1997 $.ajax({ 1998 type : "POST", 1999 url : ajaxScript, 2000 cache : false, 2001 data : $.param(inputParams), 2002 dataType : "json"}) 2003 .done(function(data){ 2004 if (data.status == "success") { 2005 bookmarks = data.bookmarkdata; 2006 bookmark_change = false; 2007 dfd.resolve(); 2008 } else if (data.status == "error") { 2009 switch (data.errorcode) { 2010 case 1: showStateMessage('<i class="caution"></i>ãã§ãã¯ãªã¹ãã®å½¢å¼ã䏿£ã§ãã'); break; 2011 case 2: showStateMessage('<i class="caution"></i>ãã§ãã¯ãªã¹ãã®åå¾ã«å¤±æãã¾ããã'); break; 2012 case 3: showStateMessage('<i class="caution"></i>æ¥ç¶ã®ã¿ã¤ã ã¢ã¦ãã«ããåå¾ã«å¤±æãã¾ããã'); break; 2013 } 2014 dfd.reject(); 2015 } 2016 }).fail(function(d, s){ 2017 showStateMessage('<i class="ng"></i>['+s+']ãµã¼ãã¨ã®éä¿¡ã«å¤±æãã¾ããã'); 2018 dfd.reject(); 2019 }).always(function(){ 2020 $i.attr('class', iClass); 2021 }); 2022 return dfd.promise(); 2023} 2024$('#bookmarkBtn_checkbox').change(function() { 2025 if (!uid || !$('#loginBtn').hasClass('login')) { 2026 return false; 2027 } 2028 var _this = $(this); 2029 var target = _this.attr('data-key'); 2030 var state = _this.prop('checked') ? 'true' : 'false'; 2031 _this.prop('disabled', true); 2032 bookmarkChange(target, state).always(function(){ 2033 _this.prop('disabled', false); 2034 }); 2035}) 2036$('body').on('click', '#bookmark_edit', function(){ 2037 if (!uid || !$('#loginBtn').hasClass('login')) { 2038 showStateMessage('<i class="caution"></i>䏿£ãªãªã¯ã¨ã¹ãã§ãã'); 2039 return false; 2040 } 2041 const $i = $('i', $(this)); 2042 loadBookmarkData($i).done(function(){ 2043 bookmark_edit(); 2044 }); 2045 return false; 2046}) 2047async function bookmark_edit() { 2048 const q2c = await getQ2c(); 2049 2050 const bookmarked = {}; 2051 for (let i=1; i<=bunyalen; i++) { 2052 bookmarked[i] = new Set(); 2053 } 2054 2055 const bookmarkCount = bookmarks.length || 0; 2056 for (let i=0; i<bookmarkCount; i++) { 2057 const qid = bookmarks[i]; 2058 const categoryId = q2c[qid]; 2059 if (!categoryId) continue; 2060 2061 const fieldId = categoryId.split('_')[0] 2062 bookmarked[fieldId].add(qid); 2063 } 2064 2065 let bookmarkList = [], li = ''; 2066 for (const i in bookmarked) { 2067 bookmarkList[i] = [...bookmarked[i]]; 2068 bookmarkList[i].sort(function(a, b){ 2069 return parseInt(a) < parseInt(b) ? -1 : 1; 2070 }); 2071 for (let j=0,len=bookmarkList[i].length; j<len; j++) { 2072 if (j == 0) { 2073 li += '<dt class="c'+i+'">'+bunyalist[i][0]+'</dt>'; 2074 } 2075 const qid = bookmarkList[i][j]; 2076 const qidObj = splitQid(qid); 2077 const dirname = getDirname(qidObj.eid), q = qidObj.q; 2078 const year_wa = AD2year_wa(dirname, true); 2079 li += '<dd class="c'+i+'"><label><input type="checkbox" value="'+qid+'">'+year_wa+' å'+q+'</label><a href="/kakomon/'+dirname+'/'+('0'+q).slice(-2)+'.html" target="_blank">⇱</a></dd>'; 2080 } 2081 } 2082 2083 if (li) { 2084 li = 2085`<style> 2086#overLayer.review{width:650px;height:600px;display:flex;flex-direction:column} 2087#review-checkbox-wrap{flex:1;overflow:auto;scrollbar-gutter:stable;margin-bottom:72px} 2088#floatBtn{bottom:0 !important;padding:15px 0;background:var(--main-bg)} 2089.checkEditWrap{display:flex;align-items:center;padding:3px 5px} 2090#checkDelete{margin-left:10px;display:none;padding:3px 12px 3px 8px} 2091#checkDelete .material-symbols-outlined{font-size:24px;vertical-align:-7px;margin-right:2px} 2092@media(max-width:770px){ 2093.checkEditWrap{padding:8px 0} 2094} 2095</style> 2096<div class="checkEditWrap"> 2097<label style="padding:5px"><input type="checkbox" name="check-edit-all"></label> 2098<span id="checkCount">ãã¹ã¦é¸æ</span> 2099<button id="checkDelete"><span class="material-symbols-outlined">delete</span>åé¤</button> 2100</div> 2101<dl class="confirmTable bookmarkList">${li}</dl>`; 2102 } else { 2103 li = emptySVG('ãã§ãã¯æ¸ã®åé¡ãããã¾ãã'); 2104 } 2105 const html = '<h2>ãã§ãã¯ããåé¡ã®ç®¡ç</h2>'+li; 2106 2107 showModal(html, 'review'); 2108} 2109$('#overLayer').on('change', '.bookmarkList [type="checkbox"]', function(){ 2110 if ($(this).prop('checked')){ 2111 $(this).closest('dd').addClass('checked'); 2112 } else { 2113 $(this).closest('dd').removeClass('checked'); 2114 } 2115 const checkedCount = $('.bookmarkList [type="checkbox"]:checked').length; 2116 if (checkedCount > 0){ 2117 $('#checkCount').html(checkedCount+' selected'); 2118 $('#checkDelete').show(); 2119 } else {
2120 $('#checkCount').html('ãã¹ã¦é¸æ'); 2121 $('#checkDelete').hide(); 2122 } 2123}) 2124$('#overLayer').on('change', '[name="check-edit-all"]', function(){ 2125 var f = $(this).prop('checked'); 2126 $('.bookmarkList [type="checkbox"]').prop('checked', f).change(); 2127}) 2128$('#overLayer').on('click', '#checkDelete', function(){ 2129 if (!confirm('ãã§ãã¯ããé ç®ããªã¹ãããåé¤ãã¾ãã')) return false; 2130 2131 var arr = []; 2132 $('.bookmarkList [type="checkbox"]:checked').each(function(){ 2133 arr.push($(this).val()); 2134 }) 2135 if (arr.length === 0) return false; 2136 2137 showStateMessage('<i class="loading"></i>åé¤ãã¦ãã¾ãã'); 2138 2139 var promise = bookmarkChange(arr.join(','), 'false'); 2140 promise.done(function(){ 2141 $('.checkEdit').css('visibility', 'hidden'); 2142 $('.bookmarkList [type="checkbox"]:checked').closest('dd').fadeOut('fast', function(){ 2143 $(this).remove(); 2144 if ($('.bookmarkList dd').length === 0){ 2145 $('.checkEditWrap').replaceWith(emptySVG('ãã§ãã¯æ¸ã®åé¡ãããã¾ãã')); 2146 } 2147 }); 2148 $('.bookmarkList dt').each(function(){ 2149 if ($('.'+$(this).attr('class')+':not(:animated)').length === 1) { 2150 $(this).fadeOut('fast', function(){ 2151 $(this).remove(); 2152 }); 2153 } 2154 }) 2155 //åºé¡ä¸ã®åé¡ã®ããã¯ãã¼ã¯ãã¿ã³ãOFFã«ãã 2156 if (arr.indexOf($('#bookmarkBtn_checkbox').attr('data-key')) !== -1) { 2157 $('#bookmarkBtn_checkbox').prop('checked', false); 2158 } 2159 showStateMessage('<i class="ok"></i>'+arr.length+'é ç®ãåé¤ãã¾ããã'); 2160 }); 2161 promise.fail(function(){ 2162 showStateMessage('<i class="ng"></i>ãµã¼ãã¨ã®éä¿¡ã«å¤±æãã¾ããã'); 2163 }); 2164}) 2165$('#overLayer').on('click', '#csv-download', function(){ 2166 $('#csvForm').remove(); 2167 2168 var d = []; 2169 var target = $('[name="targetDate"]').val(); 2170 if (!target) { 2171 var _q = $('#configform [name="q"]').val().split(','), 2172 _r = $('#configform [name="r"]').val().split(','), 2173 _c = $('#configform [name="c"]').val().split(','); 2174 if (!isErrorPage()) { 2175 _q.pop(); 2176 _c.pop(); 2177 } 2178 var time = Math.floor(Date.now() / 1000); 2179 for (i=0,len=_q.length; i<len; i++) { 2180 d.push(time+','+_q[i]+','+_r[i]+','+_c[i]); 2181 } 2182 } else { 2183 d = narrowData(target); 2184 } 2185 d = d.join('|'); 2186 2187 $('<form/>', { 2188 action: './php/csv_download.php', 2189 method: 'post', 2190 id: 'csvForm', 2191 }) 2192 .append($('<input/>', {type:'hidden', name:'data', value:d})) 2193 .append($('<input/>', {type:'hidden', name:'app', value:'doujou'})) 2194 .appendTo(document.body) 2195 .submit(); 2196 2197 return false; 2198}) 2199//userlogããç¯å²ãåãåºã 2200function narrowData(target) { 2201 var filtered = []; 2202 if ($('[name="times[]"][value="'+target+'"]').length) { 2203 var ptn = new RegExp('^[0-9]{10},'+target+'_'); 2204 filtered = $.grep(userlog, function(val) { 2205 return ptn.test(val); 2206 }); 2207 } else { 2208 var st, ed; 2209 const now = new Date(); 2210 const y = now.getFullYear(), 2211 m = now.getMonth(), 2212 d = now.getDate(); 2213 switch (target) { 2214 case 'today': 2215 st = new Date(y, m, d).getTime(); 2216 ed = new Date(y, m, d+1).getTime(); 2217 break; 2218 case 'yesterday': 2219 st = new Date(y, m, d-1).getTime(); 2220 ed = new Date(y, m, d).getTime(); 2221 break; 2222 case 'thisMonth': 2223 st = new Date(y, m).getTime(); 2224 ed = new Date(y, m+1).getTime(); 2225 break; 2226 case 'lastMonth': 2227 st = new Date(y, m-1).getTime(); 2228 ed = new Date(y, m).getTime(); 2229 break; 2230 case 'past7days': 2231 st = new Date(y, m, d-7).getTime(); 2232 ed = new Date(y, m, d).getTime(); 2233 break; 2234 case 'past30days': 2235 st = new Date(y, m, d-30).getTime(); 2236 ed = new Date(y, m, d).getTime(); 2237 break; 2238 case 'past90days': 2239 st = new Date(y, m, d-90).getTime(); 2240 ed = new Date(y, m, d).getTime(); 2241 break; 2242 case 'past180days': 2243 st = new Date(y, m, d-180).getTime(); 2244 ed = new Date(y, m, d).getTime(); 2245 break; 2246 case 'past1years': 2247 st = new Date(y-1, m, d).getTime(); 2248 ed = new Date(y, m, d).getTime(); 2249 break; 2250 case 'custom': 2251 const stVal = $('[name="startDate"]').val(); 2252 const edVal = $('[name="endDate"]').val(); 2253 if (isValidDateString(stVal) && isValidDateString(edVal)) { 2254 if (stVal > edVal) { 2255 showStateMessage('<i class="caution"></i>çµäºæ¥ãéå§æ¥ãããæã®æ¥ä»ã§ãã'); 2256 return filtered; 2257 } 2258 const stYmd = stVal.split('-'); 2259 const edYmd = edVal.split('-'); 2260 // + ã§æ°å¤ã«å¤æãã¦ããå æ¸ããªãã¨æååã®é£çµã«ãªã£ã¦ãã¾ã 2261 st = new Date(+stYmd[0], +stYmd[1]-1, +stYmd[2]).getTime(); 2262 ed = new Date(+edYmd[0], +edYmd[1]-1, +edYmd[2]+1).getTime(); 2263 2264 localStorage.setItem('CUSTOM_START_DATE', stVal); 2265 localStorage.setItem('CUSTOM_END_DATE', edVal); 2266 } 2267 break; 2268 case 'all': return userlog; 2269 } 2270 //ç§åä½ã«å¤æ 2271 st = Math.floor(st / 1000); 2272 ed = Math.floor(ed / 1000); 2273 filtered = $.grep(userlog, function(val, idx) { 2274 var time = val.split(',')[0]; 2275 return time >= st && time < ed; 2276 }); 2277 } 2278 return filtered; 2279} 2280let allTimesCache = null; 2281function getAllTimes() { 2282 if (!allTimesCache) { 2283 allTimesCache = $('[name="times[]"]').map(function(){ 2284 return $(this).val(); 2285 }).get().sort((a, b) => a.localeCompare(b, undefined, {numeric: true, sensitivity: 'base'})); 2286 } 2287 return [...allTimesCache]; 2288} 2289function isErrorPage() { 2290 return $('#errorPage')[0]; 2291} 2292function isMoshi() { 2293 return mode == 3; 2294} 2295function isReview() { 2296 return $('#configform [name="mode"]').val() == 'review'; 2297} 2298function isUnanswer() { 2299 return $('#configform [name="mode"]').val() == 'unanswer'; 2300} 2301function isBookmark() { 2302 return $('#configform [name="mode"]').val() == 'bookmark'; 2303} 2304Date.prototype.toyyyymmdd = function(fDemiliter) { 2305 var dem = (fDemiliter) ? '-' : ''; 2306 return this.getFullYear() + dem + ('0' + (this.getMonth()+1)).slice(-2) + dem + ('0' + this.getDate()).slice(-2); 2307} 2308function isValidDateString(dateStr) { 2309 if (!/^\d{4}-\d{2}-\d{2}$/.test(dateStr)) return false;
2310 2311 const [y, m, d] = dateStr.split('-').map(Number); 2312 const date = new Date(y, m - 1, d); 2313 2314 return ( 2315 date.getFullYear() === y && 2316 date.getMonth() === m - 1 && 2317 date.getDate() === d 2318 ); 2319} 2320})
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.