昨天
I asked 如何将带有自包含数据的d3js javacript文件带入Shiny中以绘制强制网络图.现在我正在寻找下一步:server.R将读取JSON数据文件以在图中显示.我一直在努力调整使用messageHandlers将数据传递到d3JS的
this example .这超出了我的专业知识,所以我正在寻求一些帮助.我很确定它出现在messageHandler中,哪里出了问题.
我很乐意发表完整的工作实例,因为这将使我对R,Shiny和d3JS集成有一个新的理解. PS:是的,我看过networkD3和其他工具.我的d3JS图表比这里的简单示例复杂得多. :)接下来的步骤还将包括使图表在Shiny中选择输入有反应,但我首先需要解决这个问题.
非常感谢!
蒂姆
ui.R – 按下按钮,接收图表!
shinyUI(fluidPage( titlePanel("Shiny Binding to d3JS"),sidebarLayout( sidebarPanel( tags$head(tags$link(rel = "stylesheet",type = "text/css",href = "twoNodes.css")),actionButton("var_run",label="Create Graph!") ),mainPanel( h3("D3JS FN OUTPUT:"),# load D3JS library tags$script(src="d3.min.js"),# load javascript tags$script(src="twoNodes.js"),# create div tags$div(id="div_graph") ) ) ))
server.R – 当前读入两个节点及其链接. IRL它会查询数据存储.
library(shiny) library(rjson) # Read JSON from the file json_data <- fromJSON(file="twoNodes.JSON") shinyServer( function(input,output,session) { # exception handler for when action button is clicked # session$sendCustomMessage is where things start to fall apart observe({ if (input$var_run == 0){ return() } session$sendCustomMessage(type="jsondata",json_data) }) } )
twoNodes.JSON – 数据
{ "nodes":[ {"id":0,"name":"Observations","group":"1"},{"id":1,"name":"DataSet","group":"2"} ],"edges":[ {"source":0,"target":1,"value":""} ] }
twoNodes.css – 样式表
#nodegroup1{ fill:#000000; fon-family: Serif,Georgia; font-size: 14px; font-weight: bold; } .nodetext{ font-size:8; color: red; } .edgelabel{ font-size:12px; fill:darkblue; } .edges{ stroke: #ccc; stroke-width: 2; }
twoNodes.js – 我试图利用的d3JS魔法
Shiny.addCustomMessageHandler("jsondata",function(message){ var dataset = [message]; d3.select("#tempID").remove() // lines from original d3JS follow //Width and height for SVG area var w = 300; var h = 200; // changed from body to #div_graph. Added tempID var svg = d3.select("#div_graph").append("svg") .attr("id","tempID") .attr("width",w) .attr("height",h); svg.append("text") .text("Two Nodes in a Force Network") .attr("x",10) .attr("y",15); // Data source - Now comes in with message handler // d3.json("/d3/CubeStructure/twoNodes.JSON",function(dataset) { var force = d3.layout.force() .nodes(dataset.nodes) .links(dataset.edges) .gravity(.05) .charge(-180) .linkdistance(100) .size([w,h]) .start(); var drag = force.drag() .on("dragstart",dragstart); var edges = svg.selectAll("line") .data(dataset.edges) .enter() .append("line") .attr("id",function(d,i){return 'edge'+i}) .attr("class","edges") .attr("marker-end","url(#end)"); var nodes = svg.selectAll("g.node") .data(dataset.nodes) .enter() .append("g") .attr("class","node") .on("dblclick",dblclick) .call(drag); nodes.append("circle") .attr("r",10) .style("stroke","black") // Mousover Node - highlight node by fading the node colour during mouSEOver .on('mouSEOver',function(d){ var nodeselection = d3.select(this).style({opacity:'0.5'}); }) //MouSEOut Node - bring node back to full colour .on('mouSEOut',function(d){ var nodeselection= d3.select(this).style({opacity:'1.0',}) }) // Node label nodes.append("text") .attr("class","nodetext") .attr("dx",12) .attr("dy",".35em") .attr("id",i){return 'nodegroup1'}) // all get the same style .text(function(d) { return d.name }); // Just the name // Paths along which to apply the edge label var edgepaths = svg.selectAll(".edgepath") .data(dataset.edges) .enter() .append('path') .attr({'d': function(d) {return 'M '+d.source.x+' '+d.source.y+' L '+ d.target.x +' '+d.target.y},'class':'edgepath','fill-opacity':0,'stroke-opacity':0,'fill':'blue','stroke':'red','id':function(d,i) {return 'edgepath'+i}}) .style("pointer-events","none"); // dx : the starting distance of the label from the source node var edgelabels = svg.selectAll(".edgelabel") .data(dataset.edges) .enter() .append('text') .style("pointer-events","none") .attr({'class':'edgelabel',i){return 'edgelabel'+i},'dx':40,'dy':0 }) ; force.on("tick",function() { edges.attr("x1",function(d) { return d.source.x; }) .attr("y1",function(d) { return d.source.y; }) .attr("x2",function(d) { return d.target.x; }) .attr("y2",function(d) { return d.target.y; }); nodes.attr("transform",function(d) { return "translate(" + d.x + "," + d.y + ")"; }); edgepaths.attr('d',function(d) { var path='M '+d.source.x+' '+d.source.y+' L '+ d.target.x +' '+d.target.y; //console.log(d) return path}); // positioning of the label along the edge edgelabels.attr('transform',i){ if (d.target.x<d.source.x){ bBox = this.getBBox(); rx = bBox.x+bBox.width/2; ry = bBox.y+bBox.height/2; return 'rotate(180 '+rx+' '+ry+')'; } else { return 'rotate(0)'; } }); }); // }); // not needed due to msg handler End of reading in JSON from file // Double click to 'unfix' the node and have forces start to act on it again. function dblclick(d) { d3.select(this).classed("fixed",d.fixed = false); } // Set the "fixed" property of the dragged node to TRUE when a dragstart event is initiated,// - removes "forces" from acting on that node and changing its position. function dragstart(d) { d3.select(this).classed("fixed",d.fixed = true); } }); // end of new function
解决方法
你很近.它只需稍加修改即可使用; twoNodes.js中的第3行应该是
var dataset = message;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。