簡體   English   中英

我可以使用 d3.js 在 android 應用程序中創建交互式可視化嗎?

[英]Can i use d3.js for creating interactive visualizations inside an android app?

我正在嘗試在 android 應用程序中創建交互式可視化。

將被可視化的數據將本地存儲在一個 sqlite 數據庫中,並將被查詢以生成可視化。

我還沒有決定是構建原生應用程序還是網絡應用程序。

根據我的研究,d3.js 似乎非常適合需求,但我不確定如何在移動環境中使用它。

您可以使用 WebView 組件輕松地將 Javascript 嵌入到 Android 應用程序中,也可以使用 PhoneGap 或類似平台。 不幸的是,在Android 3.0 之前,原生Android 瀏覽器不顯示svg,而D3 基於SVG,因此在Android 2.3(或更低版本)瀏覽器中無法運行。 然而,它確實在 Firefox 瀏覽器中工作。

另一種選擇是在 WebView 或電話間隙中使用InfoVis Toolkit InfoVis Toolkit 似乎在 Android 上運行得更好。

我不知道有什么可比的 Android 可視化平台,但 D3 以及它的前輩 Protovis、Flare 和 Prefuse 都是開源的。 您可以嘗試將其中之一移植到 Android。

這是一個相關的問題: 移動可視化工具(平板電腦)

我按照本教程讓 D3 在我的 Android 應用程序上工作。 從那里,很容易擴展教程的代碼以滿足我的需要。

這是教程的稍微修改版本(我添加了縮放控件和縮放):

  1. 創建一個 JS 資產文件夾(ProjectName/app/src/main/assets/js)
  2. 下載 D3 ( https://d3js.org/ ) 並將縮小后的 d3.min.js 源文件復制到 ProjectName/app/src/main/assets/js
  3. 為 HTML 資產創建一個目錄:(ProjectName/app/src/main/assets/html)
  4. 創建文件 ProjectName/app/src/main/assets/html/graph.html。 將此代碼復制到新文件中:
<html>
<head>
    <script type="text/javascript" src="file:///android_asset/js/d3.min.js"></script>
    <script type="text/javascript" src="file:///android_asset/js/drawGraph.js"></script>
    <meta name="viewport" content="width=device-width, user-scalable=yes" />
</head>

<body>
<svg id="piechart"></svg>
</body>
</html>
  1. 創建將運行 D3 的 JS 文件:ProjectName/app/src/main/assets/js/drawGraph.js。 向其中添加以下代碼:
function initGraph(dataset, pHeight, pWidth) {
  var height = parseInt(pHeight);
  var width = parseInt(pWidth);        
  var svg = d3.select("#piechart");
  var textLabelSuffix = "%";

  showPieChart(dataset, svg, height, width, 
      textLabelSuffix);
}

function showPieChart(dataset, svg, height, width, 
  textLabelSuffix)
{
  var outerRadius = width / 2;
  var innerRadius = 0;

  // set height/width to match the SVG element
  svg.attr("height", height).attr("width", width);

  // create a new pie layout
  var pie = d3.layout.pie();

  // initialize arcs/wedges to span 
  // the radius of the circle
  var arc = d3.svg.arc()
               .innerRadius(innerRadius)
               .outerRadius(outerRadius);

  // create groups
  var arcs = svg.selectAll("g.arc")   
                // bind dataset to pie layout
                .data(pie(dataset))   
                // create groups
                .enter()              
                // append groups
                .append("g")          
                // create arcs
                .attr("class", "arc") 
                // position each arc in the pie layout
                .attr("transform", "translate(" + 
                 outerRadius + "," + 
                 outerRadius + ")");


  // initialize color scale - refer to
  // https://github.com/mbostock/d3/wiki/Ordinal-Scales
  var color = d3.scale.category10();

  arcs.append("path")
      .attr("fill", function(d,i) { return color(i); })
      .attr("d", arc);

  arcs.append("text")
      .attr("transform", function(d) {
          return "translate(" + arc.centroid(d) + ")";
       })
      .attr("text-anchor", "middle")
      .text(function(d) { return d.value + 
         textLabelSuffix; });
}
  1. 創建將托管 D3 代碼的活動布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/tvOutgoing"
        android:layout_alignParentBottom="true"/>
</RelativeLayout>
  1. 在您的活動中初始化 webview:


public class VisualizationActivity extends AppCompatActivity {

private WebView webview;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_visualization);

    // Prepare webview: add zoom controls and start zoomed out
    webview = (WebView) findViewById(R.id.webview);
    final WebSettings webSettings = webview.getSettings();
    webSettings.setJavaScriptEnabled(true);
    webSettings.setBuiltInZoomControls(true);
    webSettings.setSupportZoom(true);
    webSettings.setUseWideViewPort(true);
    webview.setWebChromeClient(new WebChromeClient());
    webview.setInitialScale(1);

    webview.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {
            // after the HTML page loads, run JS to initialize graph
            int dataset[] = new int[] {5,10,15,20,35};
            String text = Arrays.toString(dataset);

            webview.loadUrl("javascript:initGraph(" + 
                    text + ", "
                    (webview.getHeight()) + ", "
                    + (webview.getWidth()) + ")");
        }
    });

    // Load base html from the assets directory
    webview.loadUrl("file:///android_asset/html/graph.html");
}

}

據我所知,Android 應用程序只是 Java。 因此,要使用 d3,您需要一個 java javascript 引擎/包裝器(如 Rhino,或者顯然是 PhoneGap ),或者只需要制作一個 HTML5 應用程序(而不是 Android 應用程序)。

關於 PhoneGap 的鏈接似乎是關於從 HTML5 生成應用程序,但您需要檢查是否可以包含任意附加庫。

它必須是一個應用程序嗎? D3 更適合編寫 HTML5 站點而不是應用程序。

嗨,我在使用 D3、C3 和 phonegap 在可安裝應用程序上渲染圖形時遇到了問題。 問題是,如果您嘗試執行 c3.generate,它將在瀏覽器上正常工作,但在可安裝的應用程序上卻無法正常工作,解決方案是編寫您自己的指令並在其中使用 C3。

希望這可以幫助某人。

對於像我一樣,試圖通過參考教程學習如何在 Android 中集成 D3 的人,這里是當前 D3 版本 V5 的 D3 餅圖的 js 代碼。

function loadPieChart(dataset) {
      var svg = d3.select("#piechart");
      var height = 500;
      var width = 500;
      var textLabelSuffix = "%";

      showPieChart(dataset, svg, height, width,
          textLabelSuffix);
    }

    function showPieChart(dataset, svg, height, width,
      textLabelSuffix)
    {
      var outerRadius = width / 2;
      var innerRadius = 0;

      // set height/width to match the SVG element
      svg.attr("height", height).attr("width", width);

      // create a new pie layout
      var pie = d3.pie();

      // initialize arcs/wedges to span
      // the radius of the circle
      var arc = d3.arc()
                   .innerRadius(innerRadius)
                   .outerRadius(outerRadius);

      // create groups
      var arcs = svg.selectAll("g.arc")
                    // bind dataset to pie layout
                    .data(pie(dataset))
                    // create groups
                    .enter()
                    // append groups
                    .append("g")
                    // create arcs
                    .attr("class", "arc")
                    // position each arc in the pie layout
                    .attr("transform", "translate(" +
                     outerRadius + "," +
                     outerRadius + ")");


      // initialize color scale - refer to
      // <a href="https://github.com/mbostock/d3/wiki/Ordinal-Scales" target="_blank">https://github.com/mbostock/d3/wiki/Ordinal-Scales</a>
      var color = d3.scaleOrdinal(d3.schemeAccent);



      arcs.append("path")
          .attr("fill", function(d,i) { return color(i); })
          .attr("d", arc);

      arcs.append("text")
          .attr("transform", function(d) {
              return "translate(" + arc.centroid(d) + ")";
           })
          .attr("text-anchor", "middle")
          .text(function(d) { return d.value +
             textLabelSuffix; });
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM