// ==UserScript==
// @name HistogramHeatGraph_html5.user.js
// @namespace sotoba
// @version 0.20171105
// @description ニコニコ動画でコメントの盛り上がりをグラフで表示(html5版)
// @match http://www.nicovideo.jp/watch/*
// @include http://www.nicovideo.jp/watch/*
// @require http://code.jquery.com/jquery-latest.min.js
// @grant none
// ==/UserScript==
(function () {
function setStyle() {/*
#comment-graph {
background: repeating-linear-gradient(to top, #000, #222 10px);
border: 1px solid #000;
border-top: 0;
float: left;
font-size: 0;
white-space: nowrap;
}
#comment-list {
background: #000;
color: #fff;
font-size: 12px;
line-height: 1.25;
padding: 4px 4px 0;
pointer-events: none;
position: absolute;
z-index: 9999;
}
*/}
const style = document.createElement('style');
const styleText = setStyle.toString().match(/\/\*([^]*)\*\//)[1];
style.appendChild(document.createTextNode(styleText));
document.body.appendChild(style);
var ControllerBox=$('.ControllerBoxContainer').eq(0);
var PlayerContainer=$('.PlayerContainer').eq(0);
PlayerContainer.append('<div id=comment-graph></div>');
$('.MainContainer').eq(0).append('<div id=comment-list></div>');
const $commentgraph = $('#comment-graph');
const $list = $('#comment-list');
var ApiJsonData=JSON.parse(document.getElementById('js-initial-watch-data').getAttribute('data-api-data'));
var thread_id=ApiJsonData.video.dmcInfo.thread.thread_id;
var video_id=ApiJsonData.video.id;
var user_id=ApiJsonData.video.dmcInfo.user.user_id;
if(video_id.startsWith('sm')||video_id.startsWith('nm')){
$.ajax({
url:'http://nmsg.nicovideo.jp/api/thread?thread='+thread_id+'&version=20061206&res_from=-1000&scores=1',
type:'GET',
dataType:'xml',
timeout:3000,
error:function() {
console.log("Ajax:failed");
},
success:function(xml){
drowgraph(xml,ApiJsonData);
}
});
}else{
$.ajax({
url:'http://flapi.nicovideo.jp/api/getthreadkey?thread='+thread_id,
type:'GET',
timeout:3000,
error:function() {
console.log("Ajax:failed");
},
success:function(response){
$.ajax({
url:'http://nmsg.nicovideo.jp/api/thread?thread='+thread_id+'&version=20061206&res_from=-1000&scores=1&user='+user_id+'&'+response,
type:'GET',
dataType:'xml',
timeout:3000,
error:function() {
console.log("Ajax:failed...");
},
success:function(xml){
drowgraph(xml,ApiJsonData);
}
});
}
});
}
function drowgraph(commentData,ApiJsonData){
var videoTotalTime =ApiJsonData.video.dmcInfo.video.length_seconds;
var barTimeInterval=videoTotalTime > 10 ? 10 : Math.ceil(videoTotalTime);
const barIndexNum = Math.ceil(videoTotalTime / barTimeInterval);
const playerWidth =parseFloat($("#CommentRenderer").children('canvas').eq(0).css("width"));
$('#comment-graph').css( "width" , playerWidth );
const barColors = [
'126da2', '1271a8', '1275ae', '1279b4', '137dba',
'1381c0', '1385c6', '1489cc', '148dd2', '1491d8'
];
var listCounts = (new Array(barIndexNum)).fill(0);
var listMessages = (new Array(barIndexNum)).fill("");
var listTimes = (new Array(barIndexNum)).fill("");
var lastBarTimeIntervalGap = Math.floor(videoTotalTime- (barIndexNum * barTimeInterval));
var barWidth = playerWidth / barIndexNum;
var barTimePoint = 0;
$(commentData).find('chat').each(function(index){
var vpos = $(this).attr('vpos')/100;
var section=Math.floor(vpos/barTimeInterval);
listCounts[section]++;
if(listCounts[section]<=30){
var comment=$(this).text().replace(/"|<|</g, ' ').replace(/\n/g, '<br>');
listMessages[section]+=comment+'<br>';
}
});
var startMin=0;
var startSec=0;
var min=0;
var sec=0;
for (var i = 0; i < barIndexNum-1; i++) {
startMin=min;
startSec=sec;
sec+=barTimeInterval;
if(59 < sec){
min+=1;
sec-=60;
}
listTimes[i] += `${("0"+startMin).slice(-2)}:${("0"+startSec).slice(-2)}-${("0"+min).slice(-2)}:${("0"+sec).slice(-2)}`;
}
startMin=min;
startSec=sec;
sec+=(barTimeInterval+lastBarTimeIntervalGap);
if(59 < sec){
min+=1;
sec-=60;
}
listTimes[i] += `${("0"+startMin).slice(-2)}:${("0"+startSec).slice(-2)}-${("0"+min).slice(-2)}:${("0"+sec).slice(-2)}`;
// TODO なぜかbarIndexNum以上の配列ができる
listCounts=listCounts.slice(0, barIndexNum);
var listCountMax = Math.max.apply(null,listCounts);
const barColorRatio = (barColors.length - 1) / listCountMax;
var graphHeight = listCountMax > 30 ? 30:listCountMax;
$commentgraph.empty();
$commentgraph.height(graphHeight);
var barColor;
var barBackground;
for (i = 0; i < barIndexNum; i++) {
barColor = barColors[Math.floor(listCounts[i] * barColorRatio)];
barBackground = `linear-gradient(to top, #${barColor}, #${barColor} ` +
`${listCounts[i]}px, transparent ${listCounts[i]}px, transparent)`;
var barText = listCounts[i] ?
`${listMessages[i]}<br><br>${listTimes[i]} コメ ${listCounts[i]}` : '';
$('<div>')
.css('background-image', barBackground)
.css('float','left')
.data('text', barText)
.height(graphHeight)
.width(barWidth)
.appendTo($commentgraph);
}
$commentgraph.children().on({
'mouseenter': function(val) {
$list
.css({
'left': $(this).offset().left,
'top': $commentgraph.offset().top - $list.height() - 10
})
.html($(this).data('text'));
},
'mousemove': function(val) {
$list.offset({
'left': $(this).offset().left,
'top': $commentgraph.offset().top - $list.height() - 10
});
},
'mouseleave': function() {
$list.empty();
}
});
}
})();