热词云图实践

写在前面

作为一块哪里需要就往哪搬,前一阵子得到需求,需要在一个搜索下添加词云,高版本好看,低版本兼容。于是自己在github上找了用wordcloud2.js来实现,低版本(没办法用canvas的)就自己写span构造,这里记录下实现。

习惯的原型对象

把云图单独作为原型对象实现,这里因为时间(懒)的问题,没有把云图的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>

既然有了云图,自己就顺手加了各热门查询的功能,小灰字显示。

在自己的基类(CLASS)中添加个判断是否可用canvas

//检测是否支持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缺少判断· ⊙﹏⊙)

//热门搜索对象
//云图以及热门关键词生成
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学习(抄)来的,中间有一点设计很巧妙。

 //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排序中,正的交换,负的不变。

   //随机顺序
    newArray.sort(function(){ return 0.5 - Math.random() })

ps3:为了好看,排的云图,不能直接用热值。要判断使用那个固定的size。

 

转载于:https://my.oschina.net/u/2367690/blog/1544630

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值