HistogramHeatGraph_html5.user.js

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

Verzia zo dňa 07.11.2017. Pozri najnovšiu verziu.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==UserScript==
// @name           HistogramHeatGraph_html5.user.js
// @namespace      sotoba
// @version        0.20171108
// @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 () {

    const MINIMUMBARNUM=50;
    const DEFAULTINTERBAL=10;
    const MAXCOMMENTNUM=30;
    const  GRAPHHEIGHT = 30;
    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;
    }
    #comment-list:empty {
      display: none;
    }
  */}
    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;
    var video_id;
    var user_id;
    if(ApiJsonData.video.dmcInfo !== null){
        thread_id=ApiJsonData.video.dmcInfo.thread.thread_id;
        video_id=ApiJsonData.video.dmcInfo.video.video_id;
        user_id=ApiJsonData.video.dmcInfo.user.user_id;
    }else{
        thread_id=ApiJsonData.thread.ids.default;
        video_id=ApiJsonData.video.id;
        user_id=ApiJsonData.viewer.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){
        const playerWidth =parseFloat($("#CommentRenderer").children('canvas').eq(0).css("width"));
        var videoTotalTime = ApiJsonData.video.dmcInfo !== null ?  ApiJsonData.video.dmcInfo.video.length_seconds : ApiJsonData.video.duration;
        var barTimeInterval;
        var barIndexNum;
        if(videoTotalTime > MINIMUMBARNUM*DEFAULTINTERBAL){
            barTimeInterval=DEFAULTINTERBAL;
            barIndexNum=Math.ceil(videoTotalTime / barTimeInterval);
        }else if(videoTotalTime>MINIMUMBARNUM){
            barIndexNum=MINIMUMBARNUM;
            barTimeInterval=Math.round(videoTotalTime/MINIMUMBARNUM);
        }else{
            barIndexNum=Math.floor(videoTotalTime);
            barTimeInterval=1;
        }
        $('#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]<=MAXCOMMENTNUM){
                var comment=$(this).text().replace(/"|<|&lt;/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[barIndexNum-1] += `${("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;


        $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();
            }
        });

    }
})();