注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

悠游自在

似水流年,悠游天地,自在我心

 
 
 

日志

 
 
 
 

Echarts+R,显示关系图  

2016-07-22 09:45:03|  分类: IT技术 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
利用R将igraph生成的关系图,输出到json中,再利用js读出图数据,通过Echarts显示,这样曲折的路线,我也是不容易。
先看R的部分,函数定义如下:
#将关系图graph保存到json文件中,g是igraph生成的关系图,file是要保存的json文件名,nameOfV这个参数看上去有点蠢,是用来指示g中不同节点类型的名称。
AnaUtil.Graph2json <- function(g,file='temp.json',nameOfV=c())
其中处理节点的部分如下:
  #获取图中的nodes信息
  #取节点名称,颜色
  nodecols=V(g)$color
  nodenames=V(g)$name
  nodecount=length(nodenames)
  #根据颜色获取节点的类别
  colCategories=unique(nodecols)
  categoryCount=length(colCategories)
  #如果输入的类别名称数少于颜色数,则用类别n的样式补齐(假设nameOfV里面不会有和构造的类别n同名的名称)
  tcount=length(nameOfV)
  if(tcount<categoryCount)
    nameOfV=c(nameOfV,paste('类别',(tcount+1):categoryCount))
  #根据颜色计算每个节点的类别
  cates=c()
  for(nn in nodecols)
  {
    idx=which(colCategories==nn)
    cates=c(cates,nameOfV[idx[1]])
  }
  #构造节点dataframe
  cat('构造节点dataframe\n')
  nodes=data.frame(name=nodenames,value=nodenames,category=cates,stringsAsFactors=F)
获取图中link信息,我用了一个特别低效的办法,其实E(g)就可以取出g中所有的edges,可是我找了半天,也不知道如何解析E(g)里的信息,只好用笨办法先凑合一下。真的只能是凑合,我试了只有1000个节点的图,就要将近运算1-2分钟,更大的图可能就根本不可接受了。
  #获取图中的links信息
  cat('构造links\n')
  sources=c()
  targets=c()
  for(i in 1:(nodecount-1))#两重循环获取节点间的连接关系,效率很低
  {
    for(j in (i+1):nodecount)
    {
      if(edge.connectivity(g, i, j)>0)
      {
        sources=c(sources,nodenames[i])
        targets=c(targets,nodenames[j])
      }
    }
  }
  links=data.frame(source=sources,target=targets,stringsAsFactors = F)
接下来就是,将从图中解析并准备好的信息,写入json,因为要使用echarts,所以,要准备categoryNames、category、nodes、links
  #构造json
  #categoryNames
  cat('构造categoryNames\n')
  categoryNames=paste('\"categoryNames\":[',paste('\"',nameOfV,'\"',collapse = ',',sep=''),']',sep='')
  #category
  cat('构造mcategory\n')
  tmp=paste('\"name\":\"',nameOfV,'\"',sep='')
  tmp2=paste('\"itemStyle\":{\"normal\":{\"color\":\"',colCategories,'\"}}',sep='')
  tmp3=paste('{',tmp,',',tmp2,'}',sep='')
  tmp=paste(tmp3,collapse = ',\n')
  mcategory=paste('\"mcategory\":[',tmp,']',sep='')
  #nodes,links
  tmp=AnaUtil.dataframe2json2(nodes)
  tmp2=AnaUtil.dataframe2json2(links)
  tdata=paste('\"tdata\":[{\n\"nodes\":',tmp,',\n\"links\":',tmp2,'\n}]',sep='')
  #将categoryNames、category、nodes、links字符串拼接在一起,并写入文件中
  tmp2=paste('{\n',tdata,',\n',categoryNames,',\n',mcategory,'\n}',sep='')
  if(file!='')
  {
    #Encoding(tmp2) <- 'gbk'
    tmp2=enc2utf8(tmp2)
    cat(tmp2,file=file,sep='')
  }
其中用到了dataframe转json的函数,如下:
#将dataframe中的数据输出成json,因为是数组,最外层为[]
AnaUtil.dataframe2json2 <- function(v)
{
  tcount=length(v[,1])  #获取数据的总行数
  colnames=names(v)     #获取数据的列名称
  cols=length(v[1,])    #获取数据的列数
 
  tmp=c()
  for(i in 1:tcount)
  {
    tmp2=c()
    for(j in 1:cols)
    {
      if(is.numeric(v[i,j])  && !is.na(v[i,j]))
      {
        tmp3=paste('\"',colnames[j],'\":',v[i,j],sep='')  # 构造字符串向量,类似于:"x":1
      }
      else
      {
        tmp3=paste('\"',colnames[j],'\":\"',v[i,j],'\"',sep='')  # 构造字符串向量,类似于:"本方QQ号": "355382142"
      }
      tmp2=c(tmp2,tmp3)
    }
    tmp3=paste(tmp2,collapse = ',\n')
    tmp=c(tmp,tmp3)
  }
  tmp2=paste('{\n',tmp,'\n}',collapse = ',\n',sep='')
  tmp2=paste('[\n',tmp2,'\n]',sep='')
  return(tmp2)
}
js的部分,就是做一个函数,指定一个json文件,从json文件中读取数据,初始化option数据结构,并赋给echarts对象,如下所示。其中和html网页上对应的元素id什么的就不再解释了。
//显示关系图
function colRelations(filename) {
var dom = document.getElementById("right");
var myChart = echarts.init(dom);
var app = {};
option = null;
myChart.showLoading();
$.getJSON(filename, function (json_data) {
myChart.hideLoading();
option = {
legend: {
data: json_data.categoryNames
},
tooltip: {
show: true,
formatter: '{c}'
},
series: [{
type: 'graph',
layout: 'force',
symbolSize: 16,
edgeSymbol: ["", "arrow"],
animation: false,
roam: true,
label: {
normal: {
show: true,
position: 'bottom'
}
},
draggable: true,
nodes: json_data.tdata[0].nodes,
links: json_data.tdata[0].links,
categories: json_data.mcategory,
force: {
gravity: 0.1,
edgeLength: 50,
repulsion: 100
}
}]
};
if (option && typeof option === "object") {
myChart.setOption(option, true);
}

});
}
  评论这张
 
阅读(84)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018