user2760
user2760

Reputation: 2283

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

I am trying to create an interactive visualization within an android app.

The data that will be visualized will be stored locally in a sqlite database and will be queried to generate visualizations.

I have not yet decided whether to build a native app or a web app.

Based on my research d3.js seems to fit the needs very well but I am unsure about how to use it in a mobile environment.

Upvotes: 21

Views: 20498

Answers (5)

Wugliwu
Wugliwu

Reputation: 1

For those of you, like me, trying to learn how to integrate D3 in Android via the referenced tutorial here is the js code for the D3 Pie Chart for the current D3 Version V5.

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

Upvotes: 0

Nebel22
Nebel22

Reputation: 508

I got D3 to work on my Android app by following this tutorial. From there, it was easy to extend the tutorial's code to fit my needs.

Here is a slightly modified version of the tutorial (I added zoom controls and scaling):

  1. Create a JS assets folder (ProjectName/app/src/main/assets/js)
  2. Download D3 (https://d3js.org/) and copy the minified d3.min.js source file into ProjectName/app/src/main/assets/js
  3. Create a directory for HTML assets: (ProjectName/app/src/main/assets/html)
  4. Create file ProjectName/app/src/main/assets/html/graph.html. Copy this code into the new file:
<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. Create the JS file that will run D3: ProjectName/app/src/main/assets/js/drawGraph.js. Add the following code to it:
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. Create an activity layout that will host D3 code:
<?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. Initialize the webview in your activity:


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

}

Upvotes: 10

Prostil Hardi
Prostil Hardi

Reputation: 61

Hi I had an issue of rendering the graph on the installable app using D3, C3 along with phonegap. The issue was if you try to execute c3.generate it will work fine on the browser but not on the installable app, solution is to write your own directive and use C3 inside it.

Hope this helps someone.

Upvotes: 0

Jay Askren
Jay Askren

Reputation: 10444

You can easily embed Javascript into an Android app using the WebView component or you can use PhoneGap or a similar platform. Unfortunately, before Android 3.0 the native android browser did not display svg and D3 is based on SVG, so it will not work in the android 2.3 (or below) browser. It does however work in the Firefox browser.

Another option would be to use InfoVis Toolkit in a WebView or in phone gap. InfoVis Toolkit seems to work better on Android.

I don't know of a comparable Android visualization platform, but D3, and it's predecessors Protovis, Flare, and Prefuse are all open source. You could try porting one of them to Android perhaps.

Here is a related question: visualization tool for mobile (tablet)

Upvotes: 15

Phil H
Phil H

Reputation: 20141

As far as I'm aware, Android apps are java only. So to use d3, you would need either a java javascript engine/wrapper (like Rhino, or apparently PhoneGap) or to just make an HTML5 application (not an Android app as such).

That link about PhoneGap seems to be about generating an app from HTML5, but you'll need to check you can include arbitrary additonal libraries.

Does it have to be an app? D3 is better suited to writing an HTML5 site rather than an app.

Upvotes: 2

Related Questions