21

我正在尝试在 android 应用程序中创建交互式可视化。

将被可视化的数据将存储在本地的 sqlite 数据库中,并将被查询以生成可视化。

我还没有决定是构建原生应用还是网络应用。

根据我的研究,d3.js 似乎非常适合需求,但我不确定如何在移动环境中使用它。

4

5 回答 5

14

您可以使用 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 上。

这是一个相关的问题:移动(平板电脑)的可视化工具

于 2012-05-26T03:28:50.147 回答
9

按照本教程,我让 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. 在您的活动中初始化网络视图:


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");
}

}

于 2016-03-23T02:33:36.700 回答
2

据我所知,Android 应用程序仅适用于 Java。因此,要使用 d3,您需要一个 java javascript 引擎/包装器(如 Rhino,或者显然是 PhoneGap),或者只需要制作一个 HTML5 应用程序(而不是 Android 应用程序本身)。

关于 PhoneGap 的链接似乎是关于从 HTML5 生成应用程序,但您需要检查是否可以包含任意附加库。

它必须是一个应用程序吗?D3 更适合编写 HTML5 网站而不是应用程序。

于 2012-05-15T10:27:12.220 回答
0

嗨,我在使用 D3、C3 和 phonegap 在可安装应用程序上渲染图表时遇到了问题。问题是,如果您尝试执行 c3.generate,它将在浏览器上正常工作,但在可安装应用程序上却不行,解决方案是编写您自己的指令并在其中使用 C3。

希望这可以帮助某人。

于 2015-07-12T12:27:00.223 回答
0

对于像我一样尝试通过参考教程学习如何将 D3 集成到 Android 中的人来说,这里是当前 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; });
    }
于 2020-05-31T10:55:08.343 回答