gpt4 book ai didi

r - 如何将数据驱动的 d3JS 图与 Shiny 集成?

转载 作者:行者123 更新时间:2023-12-04 09:23:04 38 4
gpt4 key购买 nike

昨天 I asked 如何将带有自包含数据的d3js javacript 文件带入Shiny 中绘制力网络图。现在我正在寻找下一步:server.R 将读取一个 JSON 数据文件以在图表中显示。我一直在努力适应 this example 使用 messageHandlers 将数据传递到 d3JS。这超出了我的专业知识,所以我正在寻求帮助。我很确定它是在 messageHandler 出现问题的地方。

我很乐意发布完整的工作示例,因为这将使我对 R、Shiny 和 d3JS 集成有一个新的理解。 PS:是的,我看过networkD3和其他工具。我的 d3JS 图表比这里的简单示例复杂得多。 :) 接下来的步骤还将包括使图表对在 Shiny 中选择输入使用react,但我当然需要首先解决这个问题。
非常感谢!
蒂姆

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

最佳答案

你相当接近。它只需稍作修改即可工作; twoNodes.js 中的第 3 行应该是

var dataset = message;

关于r - 如何将数据驱动的 d3JS 图与 Shiny 集成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29355119/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com