HistogramHeatGraph_html5.user.js

ニコニコ動画でコメントの盛り上がりをグラフで表示(html5版)

Fra 04.11.2017. Se den seneste versjonen.

  1. // ==UserScript==
  2. // @name HistogramHeatGraph_html5.user.js
  3. // @namespace sotoba
  4. // @version 0.20171105
  5. // @description ニコニコ動画でコメントの盛り上がりをグラフで表示(html5版)
  6. // @match http://www.nicovideo.jp/watch/*
  7. // @include http://www.nicovideo.jp/watch/*
  8. // @require http://code.jquery.com/jquery-latest.min.js
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. function setStyle() {/*
  14. #comment-graph {
  15. background: repeating-linear-gradient(to top, #000, #222 10px);
  16. border: 1px solid #000;
  17. border-top: 0;
  18. float: left;
  19. font-size: 0;
  20. white-space: nowrap;
  21. }
  22. #comment-list {
  23. background: #000;
  24. color: #fff;
  25. font-size: 12px;
  26. line-height: 1.25;
  27. padding: 4px 4px 0;
  28. pointer-events: none;
  29. position: absolute;
  30. z-index: 9999;
  31. }
  32. #comment-list:empty {
  33. display: none;
  34. }
  35. */}
  36. const style = document.createElement('style');
  37. const styleText = setStyle.toString().match(/\/\*([^]*)\*\//)[1];
  38. style.appendChild(document.createTextNode(styleText));
  39. document.body.appendChild(style);
  40.  
  41. var ControllerBox=$('.ControllerBoxContainer').eq(0);
  42. var PlayerContainer=$('.PlayerContainer').eq(0);
  43.  
  44. PlayerContainer.append('<div id=comment-graph></div>');
  45. $('.MainContainer').eq(0).append('<div id=comment-list></div>');
  46. const $commentgraph = $('#comment-graph');
  47.  
  48. const $list = $('#comment-list');
  49. var ApiJsonData=JSON.parse(document.getElementById('js-initial-watch-data').getAttribute('data-api-data'));
  50. var thread_id=ApiJsonData.video.dmcInfo.thread.thread_id;
  51. var video_id=ApiJsonData.video.id;
  52. var user_id=ApiJsonData.video.dmcInfo.user.user_id;
  53.  
  54. if(video_id.startsWith('sm')||video_id.startsWith('nm')){
  55. $.ajax({
  56. url:'http://nmsg.nicovideo.jp/api/thread?thread='+thread_id+'&version=20061206&res_from=-1000&scores=1',
  57. type:'GET',
  58. dataType:'xml',
  59. timeout:3000,
  60. error:function() {
  61. console.log("Ajax:failed");
  62. },
  63. success:function(xml){
  64. drowgraph(xml,ApiJsonData);
  65. }
  66. });
  67. }else{
  68. $.ajax({
  69. url:'http://flapi.nicovideo.jp/api/getthreadkey?thread='+thread_id,
  70. type:'GET',
  71. timeout:3000,
  72. error:function() {
  73. console.log("Ajax:failed");
  74. },
  75. success:function(response){
  76. $.ajax({
  77. url:'http://nmsg.nicovideo.jp/api/thread?thread='+thread_id+'&version=20061206&res_from=-1000&scores=1&user='+user_id+'&'+response,
  78. type:'GET',
  79. dataType:'xml',
  80. timeout:3000,
  81. error:function() {
  82. console.log("Ajax:failed...");
  83. },
  84. success:function(xml){
  85. drowgraph(xml,ApiJsonData);
  86. }
  87. });
  88. }
  89. });
  90. }
  91.  
  92. function drowgraph(commentData,ApiJsonData){
  93.  
  94. var videoTotalTime =ApiJsonData.video.dmcInfo.video.length_seconds;
  95. var barTimeInterval=videoTotalTime > 10 ? 10 : Math.ceil(videoTotalTime);
  96. const barIndexNum = Math.ceil(videoTotalTime / barTimeInterval);
  97. const playerWidth =parseFloat($("#CommentRenderer").children('canvas').eq(0).css("width"));
  98. $('#comment-graph').css( "width" , playerWidth );
  99. const barColors = [
  100. '126da2', '1271a8', '1275ae', '1279b4', '137dba',
  101. '1381c0', '1385c6', '1489cc', '148dd2', '1491d8'
  102. ];
  103. var listCounts = (new Array(barIndexNum)).fill(0);
  104. var listMessages = (new Array(barIndexNum)).fill("");
  105. var listTimes = (new Array(barIndexNum)).fill("");
  106. var lastBarTimeIntervalGap = Math.floor(videoTotalTime- (barIndexNum * barTimeInterval));
  107. var barWidth = playerWidth / barIndexNum;
  108. var barTimePoint = 0;
  109.  
  110. $(commentData).find('chat').each(function(index){
  111. var vpos = $(this).attr('vpos')/100;
  112. var section=Math.floor(vpos/barTimeInterval);
  113. listCounts[section]++;
  114. if(listCounts[section]<=30){
  115. var comment=$(this).text().replace(/"|<|&lt;/g, ' ').replace(/\n/g, '<br>');
  116. listMessages[section]+=comment+'<br>';
  117. }
  118. });
  119. var startMin=0;
  120. var startSec=0;
  121. var min=0;
  122. var sec=0;
  123. for (var i = 0; i < barIndexNum-1; i++) {
  124. startMin=min;
  125. startSec=sec;
  126. sec+=barTimeInterval;
  127. if(59 < sec){
  128. min+=1;
  129. sec-=60;
  130. }
  131. listTimes[i] += `${("0"+startMin).slice(-2)}:${("0"+startSec).slice(-2)}-${("0"+min).slice(-2)}:${("0"+sec).slice(-2)}`;
  132. }
  133. startMin=min;
  134. startSec=sec;
  135. sec+=(barTimeInterval+lastBarTimeIntervalGap);
  136. if(59 < sec){
  137. min+=1;
  138. sec-=60;
  139. }
  140. listTimes[i] += `${("0"+startMin).slice(-2)}:${("0"+startSec).slice(-2)}-${("0"+min).slice(-2)}:${("0"+sec).slice(-2)}`;
  141.  
  142. // TODO なぜかbarIndexNum以上の配列ができる
  143. listCounts=listCounts.slice(0, barIndexNum);
  144. var listCountMax = Math.max.apply(null,listCounts);
  145. const barColorRatio = (barColors.length - 1) / listCountMax;
  146. var graphHeight = listCountMax > 30 ? 30:listCountMax;
  147.  
  148. $commentgraph.empty();
  149. $commentgraph.height(graphHeight);
  150. var barColor;
  151. var barBackground;
  152. for (i = 0; i < barIndexNum; i++) {
  153. barColor = barColors[Math.floor(listCounts[i] * barColorRatio)];
  154. barBackground = `linear-gradient(to top, #${barColor}, #${barColor} ` +
  155. `${listCounts[i]}px, transparent ${listCounts[i]}px, transparent)`;
  156.  
  157. var barText = listCounts[i] ?
  158. `${listMessages[i]}<br><br>${listTimes[i]} コメ ${listCounts[i]}` : '';
  159.  
  160. $('<div>')
  161. .css('background-image', barBackground)
  162. .css('float','left')
  163. .data('text', barText)
  164. .height(graphHeight)
  165. .width(barWidth)
  166. .appendTo($commentgraph);
  167. }
  168. $commentgraph.children().on({
  169. 'mouseenter': function(val) {
  170. $list
  171. .css({
  172. 'left': $(this).offset().left,
  173. 'top': $commentgraph.offset().top - $list.height() - 10
  174. })
  175. .html($(this).data('text'));
  176. },
  177. 'mousemove': function(val) {
  178. $list.offset({
  179. 'left': $(this).offset().left,
  180. 'top': $commentgraph.offset().top - $list.height() - 10
  181. });
  182. },
  183. 'mouseleave': function() {
  184. $list.empty();
  185. }
  186. });
  187.  
  188. }
  189. })();