web-dev-qa-db-ja.com

javascript(d3.js)をshinyにバインドする

まず、javascriptとそのライブラリd3.jsにはあまり馴染みがありませんが、Rには精通しています。Shinyを使用してダッシュボードを作成するのは楽しく簡単です(stackoverflowのおかげです)。次に、d3要素を接続して拡張します。

JavaScriptを実際にShiny(Rダッシュボード)にバインドし、実際に何が起こっているのかを説明する方法に関する情報源を探しています。

背景:私はw3schoolsでjsとjqueryのチュートリアルを行い、スコットマレーの本(Web用のインタラクティブデータの視覚化)を使用してd3について(少し)学びました。 Shiny Webサイトでカスタム入出力バインディングを構築する方法に関する例と説明を理解するのにこれで十分であることを願っています。

http://shiny.rstudio.com/articles/building-inputs.html

しかし、残念ながら私はそうしていませんし、最小限のコードで動作する例は見当たりません。 githubの多くの例は、javascriptの経験がほとんどないために、分析するのが複雑です。 JavaScriptを使用したカスタム入力バインディングの例を次に示します。

https://github.com/jcheng5/shiny-js-examples/tree/master/input

展開しようとする入力と出力のバインディングの例を次に示します。

<script src="http://d3js.org/d3.v3.js"></script>
<script type="text/javascript">
(function(){
  // Probably not idiomatic javascript.

  this.countValue=0;

  // BEGIN: FUNCTION
  updateView = function(message) {

    var svg = d3.select(".d3io").select("svg")

    svg.append("text")
      .transition()
      .attr("x",message[0])
      .attr("y",message[1])
      .text(countValue)
      .each("end",function(){
        if(countValue<100) {
          countValue+=1;
          $(".d3io").trigger("change");
        }
      })
  }
  // END: FUNCTION

  //BEGIN: OUTPUT BINDING
  var d3OutputBinding = new Shiny.OutputBinding();
  $.extend(d3OutputBinding, {
    find: function(scope) {
      return $(scope).find(".d3io");
    },
    renderError: function(el,error) {
      console.log("Foe");
    },
    renderValue: function(el,data) {
      updateView(data);
      console.log("Friend");
    }
  });
  Shiny.outputBindings.register(d3OutputBinding);
  //END: OUTPUT BINDING

  //BEGIN: INPUT BINDING
  var d3InputBinding = new Shiny.InputBinding();
  $.extend(d3InputBinding, {
    find: function(scope) {
      return $(scope).find(".d3io");
    },
    getValue: function(el) {
      return countValue;
    },
    subscribe: function(el, callback) {
      $(el).on("change.d3InputBinding", function(e) {
        callback();
      });
    }
  });
  Shiny.inputBindings.register(d3InputBinding);
 //END: OUTPUT BINDING

})()
</script>

「d3io」がuiのdiv要素である場合、updateView()は関数です。 UIは次のとおりです。

#UI
library(shiny)

d3IO <- function(inputoutputID) {
  div(id=inputoutputID,class=inputoutputID,tag("svg","")) #; eerst zat ; erbij, maar werkt blijkbaar ook zonder
}

# Define UI for shiny d3 chatter application
shinyUI(pageWithSidebar(

  # Application title
  headerPanel("D3 Javascript chatter",
              "Demo of how to create D3 I/O and cumulative data transfer"),

  sidebarPanel(
    tags$p("This widget is a demonstration of how to wire shiny direct to javascript, without any input elements."),
    tags$p("Each time a transition ends, the client asks the server for another packet of information, and adds it
            to the existing set"),
    tags$p("I can't claim this is likely to be idiomatic javascript, because I'm a novice, but it allows d3 apps
            to do progressive rendering.  In real use, a more complex request/response protocol will probably be
            required.  -AlexBBrown")
  ),

  mainPanel(
    includeHTML("d3widget.js"),
    d3IO("d3io") #Creates div element that d3 selects
    )
))

サーバーファイルは次のとおりです。

# SERVER
library(shiny)
# Define server logic required to respond to d3 requests
shinyServer(function(input, output) {

  # Generate a plot of the requested variable against mpg and only 
  # include outliers if requested
  output$d3io <- reactive(function() {
    if (is.null(input$d3io)) {
      0;
    } else {
      list(rnorm(1)*400+200,rnorm(1)*400+200);
    }
  })
})

具体的な質問:

1)server.rは "d3io"(input $ d3io)と呼ばれる入力を取得しているようです。これはui.rで定義されていないため、javascriptファイルから取得する必要があると判断したためです。実際にどの要素を参照していますか?

2)カスタムバインディングパーツの理解に問題があります。

var d3OutputBinding = new Shiny.OutputBinding();
  $.extend(d3OutputBinding, {
    find: function(scope) {
      return $(scope).find(".d3io");
    },
    renderError: function(el,error) {
      console.log("Foe");
    },
    renderValue: function(el,data) {
      updateView(data);
      console.log("Friend");
    }
  });
  Shiny.outputBindings.register(d3OutputBinding);

私の理解は:

新しい光沢のある出力バインディングを作成し、最初にクラス.d3io(div要素)を見つけ、エラーの場合はコンソール「Foe」に書き込み(この特別なコードですか?)、エラーでない場合はデータを使用して関数updateViewを使用してrenderValueこの値は?)からコンソール「Friend」に書き込みます。最後に出力を登録します。

皆さんが助けてくれることを願っています! 「javascriptを知らないときにjavascriptを光沢のあるものに実装する方法を学ぶために必要な手順」の手順を含むドキュメントを作成しています。

乾杯、ロング

39
Sweetbabyjesus

こんにちはSweetbabyjesus(言うのはとても楽しい)。次の2つの質問がありました。

1)server.rは "d3io"(input $ d3io)と呼ばれる入力を取得しているようです。これはui.rで定義されていないため、javascriptファイルから取得する必要があると判断したためです。実際にどの要素を参照していますか?

そのフレーズ_input$d3io_には次のコンポーネントがあります。

  • inputは、関数に渡されるパラメーターです。アプリ内のすべてのウィジェットの現在の値を保存するリストです。
  • _$_はメンバーセレクターです。
  • _d3io_は、UIのmainPanel内のそのID( 'd3IO( "d3io")')を持つdiv要素のコンテンツを参照します。

2)カスタムバインディングパーツの理解に問題があります。

_var d3OutputBinding = new Shiny.OutputBinding();
_

そうです、これによりShiny.OutputBindingのインスタンスが作成され、変数d3OutputBindingに割り当てられます。

_$.extend(d3OutputBinding, {
  find: function(scope) {
    return $(scope).find(".d3io");
  },
  renderError: function(el,error) {
    console.log("Foe");
  },
  renderValue: function(el,data) {
    updateView(data);
    console.log("Friend");
  }
});
_

このコードは、findrenderError、およびrenderValueと呼ばれる3つの関数でd3OutputBindingの動作を拡張します。これらの3つの関数は、Shiny.OutputBindingに必要です。

findは、elパラメーターを介して2つのレンダリング関数に渡す必要がある要素のリストを返すため、キーです。 cssクラスが「d3io」である要素を返していることに注意してください-これは前述のdivです。

extend()はjQuery javascriptライブラリの関数であり、このコンテキストの_$_はjQueryオブジェクトのエイリアスであることに注意してください。

_Shiny.outputBindings.register(d3OutputBinding);
_

この新しく構成されたオブジェクトを今すぐ使用する必要があることをShinyに知らせます。

乾杯、ニック

11
gknicker

私は一歩後退して、D3で可能な素晴らしい結果が欲しいと仮定しますが、必ずしもD3に結び付けられるわけではありません。基本的に、私はこの質問に答えます。

JavaScriptを知らないときにJavaScriptをShinyに実装する方法を学ぶために必要な手順は何ですか?

D3は驚くほど強力ですが、JavaScriptを非常に使い慣れている多くの人にとっても、習得するのが難しいことで有名です。私はD3が大好きで、ほぼ毎日使用していますが、この場合は使用しないことをお勧めします。代わりに、 Plotly と呼ばれるライブラリがあります。これはバックグラウンドでD3を使用しますが、科学コミュニティとデータ科学者専用に構築されているため、Rコミュニティに非常にフレンドリーです。

Shinyに接続するための完全なチュートリアル があり、Rの世界の多くの人がそうであるように、その構文に既に慣れている場合は ggplot2コンバーター もあります。あなたのニーズが非常に珍しい場合を除き、Plotlyは、D3で直接書くのと同じように、はるかに友好的な学習曲線であなたのニーズに応えるでしょう。

8
Chris Fritz

仕事でとても忙しいので、投稿する機会がありません。これは、customMessageHandlerを使用した回避策であることに注意してください(カスタム入出力バインディングを使用していません)。ここに行く:

目的:データフレームからデータを送信して、customMessageHandlerを使用してD3JSツリーを作成します。

パス:data.frame形式のデータをd3jsツリーに送信できました。アクションボタンをクリックすると、データフレーム内のデータがJSON形式に変更され、ツリーを作成するjsファイルに送信されます。ツリーのデータは「server.r」にハードコーディングされています。

コードはどこにありますか?私のgithubで! https://github.com/SweetBabyJesus/shiny-d3js-simple-binding

オリジナル:CHAIDに基づいてツリーアルゴリズムを作成し、大規模なデータセットから洞察を作成しました。人々はdsjsツリーを吐き出すダッシュボードにcsvをアップロードできます:)コードはやや長いので、私はあなたのためにそれを削減し、最小限のコード例を作成しました。

あなたがそれを好き願っています。

乾杯、ロング

3
Sweetbabyjesus

rChartsパッケージ に精通していますか?それはShinyでかなりうまく機能し、出力オプションのほとんどはD3バリアントに基づいています。 2

3
Joe Jansen