熱詞雲圖實踐

寫在前面

做爲一塊哪裏須要就往哪搬,前一陣子獲得需求,須要在一個搜索下添加詞雲,高版本好看,低版本兼容。因而本身在github上找了用wordcloud2.js來實現,低版本(沒辦法用canvas的)就本身寫span構造,這裏記錄下實現。javascript

習慣的原型對象

把雲圖單獨做爲原型對象實現,這裏由於時間(懶)的問題,沒有把雲圖的html構造也放在原型裏面。html

<%--熱門查詢--%>
            <div class="hot_search">
                <div class="hot_search_title">
                    <span class="hot_search_span">你們都在搜:</span>
                </div>
                <div id="hot_search_keyword" class="hot_search_keyword">
                </div>
            </div>
            <!-- 雲圖內容 -->
            <div class="wordcloud">
                <!-- 雲圖容器 -->
                <div id="wordcloud_model" class = "wordcloud_model">
                </div>
            </div>

既然有了雲圖,本身就順手加了各熱門查詢的功能,小灰字顯示。java

在本身的基類(CLASS)中添加個判斷是否可用canvasgit

//檢測是否支持canvas
CLASS.prototype.checkCanvas = function(){
    var tempHtml = '<canvas id="testCanvas" style="display:none"></canvas> '
    $('body').append(tempHtml);
    var $temp = $('#testCanvas');
    if (!document.getElementById("testCanvas").getContext){
        this.canvas = 'not';
        $temp.remove();
        return false;
    }else{
        this.canvas = 'ok';
        $temp.remove();
        return true;
    }
}

而後創建雲圖對象(ps:在set缺乏判斷· ⊙﹏⊙)github

//熱門搜索對象
//雲圖以及熱門關鍵詞生成
var WORD_CLOUD = function(cloudId,keyId,javatarget){
    that = this;
    //雲圖容器id
    this.cloudId = cloudId||'';
    //關鍵詞容器id
    this.keyId = keyId||'';
    //獲取數據的後臺方法
    this.javatarget = javatarget||'';

    //採用的時間段
    this.startTime = '';
    this.endTime = '';

    //顯示關鍵詞個數
    this.keysize = 5;
    //手動創建雲圖,數目
    this.spansize = 80;

    //按鈕id
    this.searchBtn = '';
    //查詢框id
    this.searchInput = '';

    //查詢參數
    this.dataTemp = {};
    //接收數據
    this.data = [];
    //實際使用的處理數據
    //子元素爲數組[內容,熱值(處理後的等級),(類型)]
    this.useData = [];
    //最大以及最小數據
    this.maxData = -1;
    this.minData = NaN;


    this.wordCloudFortSize = 10;
    //雲圖設置
    this.option = {
        //gridSize: Math.round(16 * $('#wordCloud').width() / 1024),
        //weightFactor: function (size) {return Math.pow(size, 2.3)},
        fontFamily: 'Times, serif',
        color: function (word, weight) {
            return (weight === 12) ? '#f02222' : '#c09292';
        },
        //旋轉
        rotateRatio: 0,
        //旋轉範圍
        rotationSteps: 1,
        backgroundColor: '#ffe0e0',
        click:function(item, dimension, event){
            that.search(item[0]);
        },
        hover:function(item, dimension, event){
        }
    };

}

//繼承基礎類
WORD_CLOUD.prototype = new CLASS();

//獲取數據
WORD_CLOUD.prototype.getDataFromJava = function(dataTemp,javatarget){
    var dataTemp=dataTemp||this.dataTemp;
    var javaTarget = javatarget||this.javatarget

    that = this;

    $.post(javaTarget, dataTemp,
        function (data,status) {
            if(status == 'success'){
                that.setData(data);
                that.createHotWord();
                that.createCloud();
                $('.wordcloud').addClass('hide')
            }
        });
}

//設置數據
WORD_CLOUD.prototype.setData = function(str){
    //待添加str處理
    //str要求值在前,內容在後,確保不會被內容中的空格影響
    var resultList = [];
    var max = -1,min=NaN;
    $.each(str.split('\n'), function each(i, line) {
        if (!$.trim(line))
            return;
        var lineArr = line.split(' ');
        var count = parseFloat(lineArr.shift()) || 0;
        if(count>max){
            max = count;
        }else if(isNaN(min)||count<min){
            min = count;
        }
        //最終內容在前,值在後
        resultList.push([lineArr.join(' '), count]);
    });
    this.data = resultList;
    this.minData = min;
    this.maxData = max;

    var max = this.maxData||20;
    var min = this.minData||10;
    var size = (max-min)/4;//0,1,2,3,4

    //循環給數據添加級別
    for (var i = 0; i <resultList.length; i++) {
        if(!!resultList[i][1]){
            var countsize = parseInt((resultList[i][1]-min)/size)+1;
            //countsize 1,2,3,4,5
            resultList[i][1] = countsize*this.wordCloudFortSize;
        }
    }

    //模擬數據添加
    //for (var i = 300; i >= 0; i--) {
    //    resultList.push([''+parseInt(Math.random(i)*1000),parseInt(Math.random(i)*4+1)*10])
    //}

    //截取雲圖用數據
    var spansize =resultList.length < this.spansize ? resultList.length : this.spansize;

    this.useData = resultList.slice(0,spansize);

    return true;
}


//選擇雲圖方法
WORD_CLOUD.prototype.createCloud = function(){
    if($('#'+this.cloudId).length != 1)return;
    $('#'+this.cloudId).html('');
    if(this.checkCanvas()){
        return this.createWordcloud();
    }else{
        return this.createSpanCloud();
    }
    //this.createSpanCloud();
}

//利用WordCloud2.js建立雲圖
WORD_CLOUD.prototype.createWordcloud = function(){

    var array = this.useData;

    this.option['list'] = array;
    WordCloud(document.getElementById(this.cloudId),this.option);
}

//手動構建span雲
WORD_CLOUD.prototype.createSpanCloud = function(){

    var spansize =this.useData.length

    //取前面的spansize個(扣掉第一個)
    var newArray = this.useData.slice(1,spansize)||[];
    //隨機順序
    newArray.sort(function(){ return 0.5 - Math.random() })
    newArray.unshift(this.useData[0]);

    var $cloud = $('#'+this.cloudId)
    if($cloud.length == 0)return;
    var html = '';

    for(var i = 0;i<spansize;i++){
        //1\2\3\4\5
        html +='&nbsp&nbsp<span class="cloudspan'+newArray[i][1]/10+'">'+newArray[i][0]+'</span>'
    }

    $cloud.append(html);

    that = this;
    $cloud.find('span').click(function(){
        that.search(this.innerText);
    });

    return true;
}

//建立熱門搜索關鍵詞
WORD_CLOUD.prototype.createHotWord = function(){
    var $keyId = $('#'+this.keyId);
    if($('.hot_keyword').length>0)$('.hot_keyword').unbind();
    $keyId.html('');

    if($keyId.length == 0)return;
    var size = this.data.length < this.keysize ? this.data.length : this.keysize;
    if(size == 0)return;
    var html = '<span class="hot_keyword">'+this.data[0][0]+'</span>';
    for (var i = 1; i < size; i++) {
        html+='|<span class="hot_keyword">'+this.data[i][0]+'</span>';
    }

    $keyId.append(html)

    that = this;
    $('.hot_keyword').click(function(){
        that.search(this.innerText);
    });
}

//點擊以後觸發查詢
WORD_CLOUD.prototype.search = function(val){
    //隱藏雲圖(與外頁面耦合)
    window.hideCloud();
    //適當延遲
    setTimeout(function(){},500);

    var searchBtn = this.searchBtn;
    var searchInput = this.searchInput;
    var value = val||'';

    var $searchBtn = $('#'+searchBtn);
    var $searchInput = $('#'+searchInput);

    if($searchBtn.length > 0 && $searchInput.length > 0){
        $searchInput.val(value);
        $searchBtn.trigger('click');
    }
}

//****************get/set***********start***********
WORD_CLOUD.prototype.setStartTime = function(startTime){
    if(this.isString(startTime))this.startTime = startTime||'';
};
WORD_CLOUD.prototype.getStartTime = function(){
    return this.startTime;
};

WORD_CLOUD.prototype.setOption = function(option){
    this.option = option;
}
WORD_CLOUD.prototype.getOption = function(){
    return this.option;
}
WORD_CLOUD.prototype.setSearchBtn = function(searchBtn){
    if(this.isString(searchBtn))this.searchBtn = searchBtn;
}
WORD_CLOUD.prototype.getSearchBtn = function(){
    return this.searchBtn;
}
WORD_CLOUD.prototype.setSearchInput = function(searchInput){
    if(this.isString(searchInput))this.searchInput = searchInput;
}
WORD_CLOUD.prototype.getSearchInput = function(){
    return this.searchInput;
}
WORD_CLOUD.prototype.setDataTemp = function(dataTemp){
    this.dataTemp = dataTemp;
}
WORD_CLOUD.prototype.getDataTemp = function(){
    return this.dataTemp;
}
//****************get/set***********edn*************

具體ps

ps1:wordcloud的從他的官方demo學習(抄)來的,中間有一點設計很巧妙。canvas

//str要求值在前,內容在後,確保不會被內容中的空格影響
    var resultList = [];
    var max = -1,min=NaN;
    $.each(str.split('\n'), function each(i, line) {
        if (!$.trim(line))
            return;
        var lineArr = line.split(' ');
        var count = parseFloat(lineArr.shift()) || 0;
        if(count>max){
            max = count;
        }else if(isNaN(min)||count<min){
            min = count;
        }
        //最終內容在前,值在後
        resultList.push([lineArr.join(' '), count]);
    });

原始數據在值在前內容在後,一會兒就解決若是內容中手賤有分隔符號的問題。。(而後數據與數據間用換行分隔同理)數組

ps2:本身構造span雲,由於從後臺傳過來的其實排序好的,大的靠前,爲了好看,因此咱們要打亂順序,利用sort排序中,正的交換,負的不變。app

//隨機順序
    newArray.sort(function(){ return 0.5 - Math.random() })

ps3:爲了好看,排的雲圖,不能直接用熱值。要判斷使用那個固定的size。dom

相關文章
相關標籤/搜索