写在前面
作为一块哪里需要就往哪搬,前一阵子得到需求,需要在一个搜索下添加词云,高版本好看,低版本兼容。于是自己在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 +='  <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。