昨天 I asked如何將帶有自包含數據的d3js javacript文件轉化爲Shiny來繪製一個強制網絡圖。現在我正在尋找下一步:server.R將讀取一個JSON數據文件以顯示在圖中。我一直在嘗試改編使用messageHandlers的this example將數據傳遞給d3JS。這超出了我的專業知識,所以我正在尋求一些幫助。我很確定它是在messageHandler中出現錯誤的地方。如何使用Shiny集成數據驅動的d3JS圖形?
我會很樂意發佈完整的工作示例,因爲這將使我對R,Shiny和d3JS集成有了新的瞭解。 PS:是的,我查看了networkD3和其他工具。我的d3JS圖表比這裏的簡單例子複雜得多。 :)接下來的步驟還包括使圖形在Shiny中選擇輸入,但我首先需要解決這個問題。 非常感謝! Tim
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", function(d,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',
'id':function(d,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',function(d,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
您是否找到解決方案? – Stophface 2016-07-14 09:11:09