HistogramHeatGraph_html5.user.js

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

Stan na 04-11-2017. Zobacz najnowsza wersja.

// ==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(/"|<|&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[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();
            }
        });

    }
})();