如何将R源代码中的JSON对象链接到d3.js以构建闪亮的应用程序 - 闪亮不会渲染d3

时间:2016-06-25 19:32:01

标签: json d3.js shiny

更新:将json链接到d3的问题已经解决了。代码已更新。现在闪亮只是不会渲染d3代码。(我读过this post但是什么都不懂)

我是闪亮的新手,当然是D3新手。我开发了一个模拟生物物种进化的程序(实际上有4种),并希望构建一个闪亮的应用程序,从用户获取参数并呈现一个交互式图表,说明它们随时间的演变。

问题是我的.js文件似乎不想集成到我的应用程序,或者如果它,我只是不知道如何将源代码中创建的JSON对象链接到.js文件。我很害怕,但我认为在这里复制整个应用文件是个好主意。

Here is the link to my source code

以下是ui.R文件:

library(plotly)



shinyUI(fluidPage(
  titlePanel(h1("Language Game")),

  sidebarLayout(
    sidebarPanel(
      h2("Parameters"),
      checkboxInput("wealth.reset", label = h5("Reset wealth of replicated organisms"),value = FALSE),
      actionButton("start", label = h5("Start")),
      actionButton("reset", label = h5("Reset")),
      sliderInput("n", label = h5("Number of organisms"), min = 50, max = 200, value = 100,step = 50),
      sliderInput("iter", label = h5("Number of Iterations"), min = 10, max = 500,value = 200, step = 10),
      sliderInput("memSpan", label = h5("Memory Span"),min = 1,max = 50,value = 5, step = 5),
      sliderInput("dial_change_rate (in percentage)", label = h5("Dialect Update Probability"), min = 0, max = 100, value = 1, step= 1),
      sliderInput("repr_rate", label = h5("Reproduction Rate"), min= 1, max= 20, value = 20, step = 1),
      sliderInput("Beta", label = h5("Decay Factor"), min = 1, max = 1.05, value = 1.029), step = 0.005),

    mainPanel(
      position = "left",
      h3("About the Game"),
      p("This game simulates interactions between the members of a population of organisms that are assigned some randome characteristics.
        Organims are distributed randomly on a linear space, and interact with their neighbours.
        The nature of the interactions is defined by the strategies of organisms."),
      plotlyOutput("encounter"),
      plotOutput("d3outplot"),
      tags$head(tags$link(rel = "stylesheet", type = "text/css", href = "style.css")),
      tags$script(src="https://d3js.org/d3.v3.min.js"),
      tags$script(src="shinyd3.js"),
      tags$div(id="body")
      )
    )
  )
)

这是server.R:

 #source("global.R")



shinyServer(function(input, output, session){


  val <- reactiveValues(doPlot = FALSE)

  observeEvent(input$start, {
    val$doPlot <- input$start
    output$d3outplot <- renderPlot({
        var_json <- reactive({
          lang.game(
            input$iter,
            input$n,
            input$repr_rate,
            input$Beta)
        })
        session$sendCustomMessage(type="jsondata",message= var_json)
      })
    })


  observeEvent(input$reset, {
    val$doPlot <- FALSE
  })

  output$encounter <- renderPlotly({

    p("The plot below illustrates the number of encounters for each organism. By hoovering on the points you can see the identity (assign by position in linear space), and the number of encounters")
    if (val$doPlot == FALSE) return()
    isolate({
      data <- reactive({
        lang.game(
          input$iter,
          input$n,
          input$repr_rate,
          input$Beta
          )
      })
      OrganismID <- c(1:input$n)
      Encounters <- rowSums(encounter.mat(input$n, input$Beta))
      q <- qplot(OrganismID,
          Encounters,
          data = data.frame(encounter.mat(input$n, input$Beta)),
          main = "Encounter Probability",
          xlab = "Organisms", ylab="Number of encounters", alpha = 0)
      ply <- ggplotly(q,kwargs=list(layout=list(hovermode="closest")))
    })
  })
})

对于.js文件,问题是我只是不知道如何将源代码中创建的JSON文件链接到.js。我使用了闪亮的消息处理程序和会话,但它只显示d3代码作为文本。另一方面,我的源代码似乎无法将json文件保存在目录中的某个位置。我希望我能清楚地解决问题,并高度赞赏任何建议。

(d3代码:我想建立像this

之类的东西
Shiny.addCustomMessageHandler("jsondata",
  function(message){
    var  JS = message;

    function truncate(str, maxLength, suffix) {     if(str.length > maxLength) {
            str = str.substring(0, maxLength + 1); 
            str = str.substring(0, Math.min(str.length, str.lastIndexOf(" ")));
            str = str + suffix;
        }
        return str;
    };

    var margin = {top: 20, right: 20, bottom: 0, left: 200},
        width = 300,
        height = 650;

    var c = d3.scale.category20c();

    var x = d3.scale.linear()
        .range([0, width]);

    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("top");

    var formatCy = d3.format("0");
        xAxis.tickFormat(formatCy);

    var svg = d3.select("body").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .style("margin-right", margin.right + "px")
        .append("g")
        .attr("transform", "translate(" + margin.right + "," + margin.bottom + ")");

    d3.json(JS, function(jsondata) {
        x.domain(jsondata["Cycle"]);
        var xScale = d3.scale.linear()
            .domain(jsondata["Cycle"])
            .range([0, width]);

        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + 0 + ")")
            .call(xAxis);

        for (var j = 0; j < jsondata.length; j++) {
            var g = svg.append("g").attr("class","variable");

            var circles = g.selectAll("circle")
                .jsondata(jsondata[j]['variable'])
                .enter()
                .append("circle");

            var text = g.selectAll("text")
                .jsondata(jsondata[j]['variable'])
                .enter()
                .append("text");

            var rScale = d3.scale.linear()
                .domain([0, d3.max(jsondata[j]['variable'], function(d) { return d[1]; })])
                .range([0, 100]);

            circles
                .attr("cx", function(d, i) { return xScale(d[0]); })
                .attr("cy", j*20+20)
                .attr("r", function(d) { return rScale(d[1]); })
                .style("fill", function(d) { return c(j); });

            text
                .attr("y", j*20+25)
                .attr("x",function(d, i) { return xScale(d[0])-5; })
                .attr("class","value")
                .text(function(d){ return d[1]; })
                .style("fill", function(d) { return c(j); })
                .style("display","none");

            g.append("text")
                .attr("y", j*20+25)
                .attr("x",width+20)
                .attr("class","label")
                .text(truncate(jsondata[j]['name'],30,"..."))
                .style("fill", function(d) { return c(j); })
                .on("mouseover", mouseover)
                .on("mouseout", mouseout);
        };

        function mouseover(p) {
            var g = d3.select(this).node().parentNode;
            d3.select(g).selectAll("circle").style("display","none");
            d3.select(g).selectAll("text.value").style("display","block");
        }


    function mouseout(p) {
        var g = d3.select(this).node().parentNode;
        d3.select(g).selectAll("circle").style("display","block");
        d3.select(g).selectAll("text.value").style("display","none");
        }
    });
  })    

1 个答案:

答案 0 :(得分:1)

我不是D3专家,对这个问题没有完整的答案。但我相信你不想在这种情况下使用d3.json函数,因为你已经有了JSON(在JS变量中)。相反,我认为您可以选择要在其中渲染绘图的DOM元素,选择所有圆圈并使用数据输入退出将数据转换为新元素。