Showing posts with label Google Charts. Show all posts
Showing posts with label Google Charts. Show all posts

Wednesday, June 24, 2015

Display Donut Chart on Android WebView, using Google Charts


My former post show how to display Google Charts on Android WebView, with Capture image. To display Donut Chart (Pie Chart with pie hole), simple modify the HTML file of pie chart (/assets/pie_chart.html) to add options of pieHole.

Example:

      // Set chart options
      var options = {
        title:'Android-er: Google Charts example of Pie/Donut chart',
        pieHole: 0.4,
      };


Thursday, August 14, 2014

Capture image generated by Google Charts API

Previous posts show how to "Display Google Charts (pie chart) on Android WebView" and "More Google Charts examples on Android WebView". To capture the PNG image of a chart, we can use the getImageURI() method, it return a string in "data:image/png;base64,..." format.


We can pass this string to Android code, decode and generate bitmap. To decode string in "data:image/png;base64,..." format, to Bitmap, we can use the code:
 private Bitmap decodeBase64PNG(String src){

  String imageDataBytes = src.substring(src.indexOf(",") + 1);
  
  InputStream stream = 
   new ByteArrayInputStream(
    Base64.decode(imageDataBytes.getBytes(), 
    Base64.DEFAULT));
  
     Bitmap bitmap = BitmapFactory.decodeStream(stream);
     return bitmap;
 }

For MainActivity.java, activity_main.xml and AndroidManifest.xml, refer to last post "Display Google Charts (pie chart) on Android WebView".

Other files modify from last post "More Google Charts examples on Android WebView".

Modify layout_webchart.xml to add a Button to Capture the image.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />
    
    <Spinner
        android:id="@+id/spcharts"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    
    <Button
        android:id="@+id/capture"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Capture" />
    
    <WebView
        android:id="@+id/web"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

ShowWebChartActivity.java
package com.example.androidwebchart;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Base64;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.Toast;

@SuppressLint("SetJavaScriptEnabled") 
public class ShowWebChartActivity extends ActionBarActivity {
 
 WebView webView;
 int num1, num2, num3, num4, num5;
 
 Spinner spCharts;
 List<String> listCharts;
 List<String> listHtml;
 
 Button btnCapture;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_webchart);
        
        Intent intent = getIntent();
        num1 = intent.getIntExtra("NUM1", 0);
        num2 = intent.getIntExtra("NUM2", 0);
        num3 = intent.getIntExtra("NUM3", 0);
        num4 = intent.getIntExtra("NUM4", 0);
        num5 = intent.getIntExtra("NUM5", 0);
        
        spCharts = (Spinner) findViewById(R.id.spcharts);
        
        listCharts = new ArrayList<String>();
        listCharts.add("Pie Chart");
        listCharts.add("Pie Chart 3D");
        listCharts.add("Scatter Chart");
        listCharts.add("Column Chart");
        listCharts.add("Bar Chart");
        listCharts.add("Histogram");
        listCharts.add("Line Chart");
        listCharts.add("Area Chart");
        
        listHtml = new ArrayList<String>();
        listHtml.add("file:///android_asset/pie_chart.html");
        listHtml.add("file:///android_asset/pie_chart_3d.html");
        listHtml.add("file:///android_asset/scatter_chart.html");
        listHtml.add("file:///android_asset/column_chart.html");
        listHtml.add("file:///android_asset/bar_chart.html");
        listHtml.add("file:///android_asset/histogram.html");
        listHtml.add("file:///android_asset/line_chart.html");
        listHtml.add("file:///android_asset/area_chart.html");
        
     ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
      android.R.layout.simple_spinner_item, listCharts);
     dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
     spCharts.setAdapter(dataAdapter);
     spCharts.setOnItemSelectedListener(new OnItemSelectedListener(){

   @Override
   public void onItemSelected(AdapterView<?> parent, View view,
     int position, long id) {
    String chartHtml = listHtml.get(parent.getSelectedItemPosition());
    webView.loadUrl(chartHtml);
   }

   @Override
   public void onNothingSelected(AdapterView<?> parent) {
    // TODO Auto-generated method stub
    
   }});
        
        webView = (WebView)findViewById(R.id.web);
        webView.addJavascriptInterface(new WebAppInterface(), "Android");

        webView.getSettings().setJavaScriptEnabled(true); 

        btnCapture = (Button)findViewById(R.id.capture);
        btnCapture.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View v) {
    //call Javascript in WebView/HTML
    webView.loadUrl("javascript:capture()");
   }});
 }
 
 private void showCaptured(String imageuri){

  Bitmap bmp = decodeBase64PNG(imageuri);
  
  Dialog dialog = new Dialog(this);
     ImageView imageView = new ImageView(this);
     imageView.setImageBitmap(bmp);
     dialog.addContentView(
       imageView, 
       new LayoutParams(
        LayoutParams.MATCH_PARENT, 
        LayoutParams.MATCH_PARENT));
     dialog.show();
  
 }
 
 private Bitmap decodeBase64PNG(String src){

  String imageDataBytes = src.substring(src.indexOf(",") + 1);
  
  InputStream stream = 
   new ByteArrayInputStream(
    Base64.decode(imageDataBytes.getBytes(), 
    Base64.DEFAULT));
  
     Bitmap bitmap = BitmapFactory.decodeStream(stream);
     return bitmap;
 }

 public class WebAppInterface {

     @JavascriptInterface
  public int getNum1() {
   return num1;
  }
  
  @JavascriptInterface
  public int getNum2() {
   return num2;
  }
  
  @JavascriptInterface
  public int getNum3() {
   return num3;
  }
  
  @JavascriptInterface
  public int getNum4() {
   return num4;
  }
  
  @JavascriptInterface
  public int getNum5() {
   return num5;
  }
  
  @JavascriptInterface
  public void captureCallback(String imageURI){
   Toast.makeText(ShowWebChartActivity.this, 
    imageURI, Toast.LENGTH_LONG).show();
   showCaptured(imageURI);
  }
 }

}

All other HTMLs:

  • add a method Javascript function capture() to be called from Android, and call chart.getImageURI() to get image, and pass back to Android by calling captureCallback().
  • Make chart to global by removing "var" in front of it.

pie_chart.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/quick_start-->
<html>
  <head>
    <!--Load the AJAX API-->
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
    
      // Load the Visualization API and the piechart package.
      google.load('visualization', '1.0', {'packages':['corechart']});
      
      // Set a callback to run when the Google Visualization API is loaded.
      google.setOnLoadCallback(drawChart);


      // Callback that creates and populates a data table, 
      // instantiates the pie chart, passes in the data and
      // draws it.
      function drawChart() {

      // Create the data table.
      var data = new google.visualization.DataTable();
      data.addColumn('string', 'ITEM');
      data.addColumn('number', 'VALUE');
      data.addRows([
        ['Item 1', Android.getNum1()],
        ['Item 2', Android.getNum2()],
        ['Item 3', Android.getNum3()], 
        ['Item 4', Android.getNum4()],
        ['Item 5', Android.getNum5()]
      ]);

      // Set chart options
      var options = {'title':'Android-er: Google Charts example of Pie chart'};

      // Instantiate and draw our chart, passing in some options.
      chart = new google.visualization.PieChart(document.getElementById('chart_div'));
      chart.draw(data, options);
    }
    </script>
    
    <script type="text/javascript">
    function capture(){
     Android.captureCallback(chart.getImageURI());
    }
    </script>
    
  </head>

  <body>
 <!--Div that will hold the pie chart-->
    <div id="chart_div" style="width:100%; height:100%"></div>
  </body>
</html>

pie_chart_3d.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/gallery/piechart-->
<html>
  <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Items',  'Value'],
          ['Item 1', Android.getNum1()],
          ['Item 2', Android.getNum2()],
          ['Item 3', Android.getNum3()],
          ['Item 4', Android.getNum4()],
          ['Item 5', Android.getNum5()]
        ]);

        var options = {
          title: 'Android-er: Google Charts example of 3D Pie chart',
          is3D: true,
        };

        chart = new google.visualization.PieChart(document.getElementById('piechart_3d'));
        chart.draw(data, options);
      }
    </script>
    
    <script type="text/javascript">
    function capture(){
     Android.captureCallback(chart.getImageURI());
    }
    </script>
    
  </head>
  <body>
    <div id="piechart_3d" style="width: 100%; height: 100%;"></div>
  </body>
</html>

scatter_chart.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/gallery/scatterchart-->
<html>
  <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['x', 'Value'],
          [ 1, Android.getNum1()],
          [ 2, Android.getNum2()],
          [ 3, Android.getNum3()],
          [ 4, Android.getNum4()],
          [ 5, Android.getNum5()]
        ]);

        var options = {
          title: 'Android-er: Google Charts example of Scatter chart',
          hAxis: {title: 'X'},
          vAxis: {title: 'Value'},
          legend: 'none'
        };

        chart = new google.visualization.ScatterChart(document.getElementById('chart_div'));
        chart.draw(data, options);
      }
    </script>
    
    <script type="text/javascript">
    function capture(){
     Android.captureCallback(chart.getImageURI());
    }
    </script>
    
  </head>
  <body>
    <div id="chart_div" style="width: 100%; height: 100%;"></div>
  </body>
</html>

column_chart.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/gallery/columnchart-->
<html>
  <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {

  var data = google.visualization.arrayToDataTable([
    ['Items', 'Value'],
    ['Item 1',  Android.getNum1()],
    ['Item 2',  Android.getNum2()],
    ['Item 3',  Android.getNum3()],
    ['Item 4',  Android.getNum4()],
    ['Item 5',  Android.getNum5()]
  ]);

  var options = {
    title: 'Android-er: Google Charts example of Column chart',
    hAxis: {title: 'Value', titleTextStyle: {color: 'red'}}
  };

  chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));

  chart.draw(data, options);

}
    </script>
    
    <script type="text/javascript">
    function capture(){
     Android.captureCallback(chart.getImageURI());
    }
    </script>
    
  </head>
  <body>
    <div id="chart_div" style="width: 100%; height: 100%;"></div>
  </body>
</html>

bar_chart.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/gallery/barchart-->
<html>
  <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Items', 'Value'],
          ['Item 1',  Android.getNum1()],
          ['Item 2',  Android.getNum2()],
          ['Item 3',  Android.getNum3()],
          ['Item 4',  Android.getNum4()],
          ['Item 5',  Android.getNum5()]
        ]);

        var options = {
          title: 'Android-er: Google Charts example of Bar chart',
          vAxis: {title: 'Value',  titleTextStyle: {color: 'red'}}
        };

        chart = new google.visualization.BarChart(document.getElementById('chart_div'));

        chart.draw(data, options);
      }
    </script>
    
    <script type="text/javascript">
    function capture(){
     Android.captureCallback(chart.getImageURI());
    }
    </script>
    
  </head>
  <body>
    <div id="chart_div" style="width: 100%; height: 100%;"></div>
  </body>
</html>

histogram.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/gallery/histogram-->
<html>
  <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Items', 'Value'],
          ['Item 1', Android.getNum1()],
          ['Item 2', Android.getNum2()],
          ['Item 3', Android.getNum3()],
          ['Item 4', Android.getNum4()],
          ['Item 5', Android.getNum5()]]);

        var options = {
          title: 'Android-er: Google Charts example of Histogram',
          legend: { position: 'none' },
        };

        chart = new google.visualization.Histogram(document.getElementById('chart_div'));
        chart.draw(data, options);
      }
    </script>
    
    <script type="text/javascript">
    function capture(){
     Android.captureCallback(chart.getImageURI());
    }
    </script>
    
  </head>
  <body>
    <div id="chart_div" style="width: 100%; height: 100%;"></div>
  </body>
</html>

line_chart.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/gallery/linechart-->
<html>
  <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Items', 'Value'],
          ['Item 1',  Android.getNum1()],
          ['Item 2',  Android.getNum2()],
          ['Item 3',  Android.getNum3()],
          ['Item 4',  Android.getNum4()],
          ['Item 5',  Android.getNum5()]
        ]);

        var options = {
          title: 'Android-er: Google Charts example of Line chart'
        };

        chart = new google.visualization.LineChart(document.getElementById('chart_div'));
        chart.draw(data, options);
      }
    </script>
    
    <script type="text/javascript">
    function capture(){
     Android.captureCallback(chart.getImageURI());
    }
    </script>
    
  </head>
  <body>
    <div id="chart_div" style="width: 100%; height: 100%;"></div>
  </body>
</html>

area_chart.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/gallery/areachart-->
<html>
  <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Items', 'Value'],
          ['Item 1',  Android.getNum1()],
          ['Item 2',  Android.getNum2()],
          ['Item 3',  Android.getNum3()],
          ['Item 4',  Android.getNum4()],
          ['Item 5',  Android.getNum5()]
        ]);

        var options = {
          title: 'Android-er: Google Charts example of Area chart',
          hAxis: {title: 'Value',  titleTextStyle: {color: '#333'}},
          vAxis: {minValue: 0}
        };

        chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
        chart.draw(data, options);
      }
    </script>
    
    <script type="text/javascript">
    function capture(){
     Android.captureCallback(chart.getImageURI());
    }
    </script>
    
  </head>
  <body>
    <div id="chart_div" style="width: 100%; height: 100%;"></div>
  </body>
</html>

download filesDownload the files.

More Google Charts examples on Android WebView

Last post show simple example of using Google Charts API in WebView. Now I show more chart examples, include: Pie Chart, 3D Pie Chart, Scatter Chart, Column Chart, Bar Chart, Histogram, Line Chart and Area Chart.



For MainActivity.java, activity_main.xml and AndroidManifest.xml, refer to last post "Display Google Charts (pie chart) on Android WebView".

Modify ShowWebChartActivity.java to provide a Spinner for user to select various type of charts, and load coresponding html accordingly.

package com.example.androidwebchart;

import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;

@SuppressLint("SetJavaScriptEnabled") 
public class ShowWebChartActivity extends ActionBarActivity {
 
 WebView webView;
 int num1, num2, num3, num4, num5;
 
 Spinner spCharts;
 List<String> listCharts;
 List<String> listHtml;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_webchart);
        
        Intent intent = getIntent();
        num1 = intent.getIntExtra("NUM1", 0);
        num2 = intent.getIntExtra("NUM2", 0);
        num3 = intent.getIntExtra("NUM3", 0);
        num4 = intent.getIntExtra("NUM4", 0);
        num5 = intent.getIntExtra("NUM5", 0);
        
        spCharts = (Spinner) findViewById(R.id.spcharts);
        
        listCharts = new ArrayList<String>();
        listCharts.add("Pie Chart");
        listCharts.add("Pie Chart 3D");
        listCharts.add("Scatter Chart");
        listCharts.add("Column Chart");
        listCharts.add("Bar Chart");
        listCharts.add("Histogram");
        listCharts.add("Line Chart");
        listCharts.add("Area Chart");
        
        listHtml = new ArrayList<String>();
        listHtml.add("file:///android_asset/pie_chart.html");
        listHtml.add("file:///android_asset/pie_chart_3d.html");
        listHtml.add("file:///android_asset/scatter_chart.html");
        listHtml.add("file:///android_asset/column_chart.html");
        listHtml.add("file:///android_asset/bar_chart.html");
        listHtml.add("file:///android_asset/histogram.html");
        listHtml.add("file:///android_asset/line_chart.html");
        listHtml.add("file:///android_asset/area_chart.html");
        
     ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
      android.R.layout.simple_spinner_item, listCharts);
     dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
     spCharts.setAdapter(dataAdapter);
     spCharts.setOnItemSelectedListener(new OnItemSelectedListener(){

   @Override
   public void onItemSelected(AdapterView<?> parent, View view,
     int position, long id) {
    String chartHtml = listHtml.get(parent.getSelectedItemPosition());
    webView.loadUrl(chartHtml);
   }

   @Override
   public void onNothingSelected(AdapterView<?> parent) {
    // TODO Auto-generated method stub
    
   }});
        
        webView = (WebView)findViewById(R.id.web);
        webView.addJavascriptInterface(new WebAppInterface(), "Android");

        webView.getSettings().setJavaScriptEnabled(true); 

 }

 public class WebAppInterface {

     @JavascriptInterface
  public int getNum1() {
   return num1;
  }
  
  @JavascriptInterface
  public int getNum2() {
   return num2;
  }
  
  @JavascriptInterface
  public int getNum3() {
   return num3;
  }
  
  @JavascriptInterface
  public int getNum4() {
   return num4;
  }
  
  @JavascriptInterface
  public int getNum5() {
   return num5;
  }
 }

}

layout_webchart.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />
    
    <Spinner
        android:id="@+id/spcharts"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    
    <WebView
        android:id="@+id/web"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

Create various html for various type.

/assets/pie_chart.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/quick_start-->
<html>
  <head>
    <!--Load the AJAX API-->
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
    
      // Load the Visualization API and the piechart package.
      google.load('visualization', '1.0', {'packages':['corechart']});
      
      // Set a callback to run when the Google Visualization API is loaded.
      google.setOnLoadCallback(drawChart);


      // Callback that creates and populates a data table, 
      // instantiates the pie chart, passes in the data and
      // draws it.
      function drawChart() {

      // Create the data table.
      var data = new google.visualization.DataTable();
      data.addColumn('string', 'ITEM');
      data.addColumn('number', 'VALUE');
      data.addRows([
        ['Item 1', Android.getNum1()],
        ['Item 2', Android.getNum2()],
        ['Item 3', Android.getNum3()], 
        ['Item 4', Android.getNum4()],
        ['Item 5', Android.getNum5()]
      ]);

      // Set chart options
      var options = {'title':'Android-er: Google Charts example of Pie chart'};

      // Instantiate and draw our chart, passing in some options.
      var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
      chart.draw(data, options);
    }
    </script>
  </head>

  <body>
 <!--Div that will hold the pie chart-->
    <div id="chart_div" style="width:100%; height:100%"></div>
  </body>
</html>

/assets/pie_chart_3d.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/gallery/piechart-->
<html>
  <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Items',  'Value'],
          ['Item 1', Android.getNum1()],
          ['Item 2', Android.getNum2()],
          ['Item 3', Android.getNum3()],
          ['Item 4', Android.getNum4()],
          ['Item 5', Android.getNum5()]
        ]);

        var options = {
          title: 'Android-er: Google Charts example of 3D Pie chart',
          is3D: true,
        };

        var chart = new google.visualization.PieChart(document.getElementById('piechart_3d'));
        chart.draw(data, options);
      }
    </script>
  </head>
  <body>
    <div id="piechart_3d" style="width: 100%; height: 100%;"></div>
  </body>
</html>

/assets/scatter_chart.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/gallery/scatterchart-->
<html>
  <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['x', 'Value'],
          [ 1, Android.getNum1()],
          [ 2, Android.getNum2()],
          [ 3, Android.getNum3()],
          [ 4, Android.getNum4()],
          [ 5, Android.getNum5()]
        ]);

        var options = {
          title: 'Android-er: Google Charts example of Scatter chart',
          hAxis: {title: 'X'},
          vAxis: {title: 'Value'},
          legend: 'none'
        };

        var chart = new google.visualization.ScatterChart(document.getElementById('chart_div'));
        chart.draw(data, options);
      }
    </script>
  </head>
  <body>
    <div id="chart_div" style="width: 100%; height: 100%;"></div>
  </body>
</html>

/assets/column_chart.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/gallery/columnchart-->
<html>
  <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {

  var data = google.visualization.arrayToDataTable([
    ['Items', 'Value'],
    ['Item 1',  Android.getNum1()],
    ['Item 2',  Android.getNum2()],
    ['Item 3',  Android.getNum3()],
    ['Item 4',  Android.getNum4()],
    ['Item 5',  Android.getNum5()]
  ]);

  var options = {
    title: 'Android-er: Google Charts example of Column chart',
    hAxis: {title: 'Value', titleTextStyle: {color: 'red'}}
  };

  var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));

  chart.draw(data, options);

}
    </script>
  </head>
  <body>
    <div id="chart_div" style="width: 100%; height: 100%;"></div>
  </body>
</html>

/assets/bar_chart.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/gallery/barchart-->
<html>
  <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Items', 'Value'],
          ['Item 1',  Android.getNum1()],
          ['Item 2',  Android.getNum2()],
          ['Item 3',  Android.getNum3()],
          ['Item 4',  Android.getNum4()],
          ['Item 5',  Android.getNum5()]
        ]);

        var options = {
          title: 'Android-er: Google Charts example of Bar chart',
          vAxis: {title: 'Value',  titleTextStyle: {color: 'red'}}
        };

        var chart = new google.visualization.BarChart(document.getElementById('chart_div'));

        chart.draw(data, options);
      }
    </script>
  </head>
  <body>
    <div id="chart_div" style="width: 100%; height: 100%;"></div>
  </body>
</html>

/assets/histogram.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/gallery/histogram-->
<html>
  <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Items', 'Value'],
          ['Item 1', Android.getNum1()],
          ['Item 2', Android.getNum2()],
          ['Item 3', Android.getNum3()],
          ['Item 4', Android.getNum4()],
          ['Item 5', Android.getNum5()]]);

        var options = {
          title: 'Android-er: Google Charts example of Histogram',
          legend: { position: 'none' },
        };

        var chart = new google.visualization.Histogram(document.getElementById('chart_div'));
        chart.draw(data, options);
      }
    </script>
  </head>
  <body>
    <div id="chart_div" style="width: 100%; height: 100%;"></div>
  </body>
</html>

/assets/line_chart.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/gallery/linechart-->
<html>
  <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Items', 'Value'],
          ['Item 1',  Android.getNum1()],
          ['Item 2',  Android.getNum2()],
          ['Item 3',  Android.getNum3()],
          ['Item 4',  Android.getNum4()],
          ['Item 5',  Android.getNum5()]
        ]);

        var options = {
          title: 'Android-er: Google Charts example of Line chart'
        };

        var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
        chart.draw(data, options);
      }
    </script>
  </head>
  <body>
    <div id="chart_div" style="width: 100%; height: 100%;"></div>
  </body>
</html>

/assets/area_chart.html
<!--ref: https://google-developers.appspot.com/chart/interactive/docs/gallery/areachart-->
<html>
  <head>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Items', 'Value'],
          ['Item 1',  Android.getNum1()],
          ['Item 2',  Android.getNum2()],
          ['Item 3',  Android.getNum3()],
          ['Item 4',  Android.getNum4()],
          ['Item 5',  Android.getNum5()]
        ]);

        var options = {
          title: 'Android-er: Google Charts example of Area chart',
          hAxis: {title: 'Value',  titleTextStyle: {color: '#333'}},
          vAxis: {minValue: 0}
        };

        var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
        chart.draw(data, options);
      }
    </script>
  </head>
  <body>
    <div id="chart_div" style="width: 100%; height: 100%;"></div>
  </body>
</html>


download filesDownload the files.


Wednesday, August 13, 2014

Display Google Charts (pie chart) on Android WebView

This example show how to use Google Charts to display pie chart on Android WebView. Google chart tools are powerful, simple to use, and free. It not only display a static graphic, but also provide user touch interactive operation, check the video on the bottom.

Display Google Charts (pie chart) displayed Android WebView
We have a MainActivity to collect data from user:
package com.example.androidwebchart;

import android.support.v7.app.ActionBarActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;


public class MainActivity extends ActionBarActivity {
 
 EditText num1, num2, num3, num4, num5;
 Button btnShow;

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

        num1 = (EditText)findViewById(R.id.num1);
        num2 = (EditText)findViewById(R.id.num2);
        num3 = (EditText)findViewById(R.id.num3);
        num4 = (EditText)findViewById(R.id.num4);
        num5 = (EditText)findViewById(R.id.num5);
        btnShow = (Button)findViewById(R.id.show);
        
        btnShow.setOnClickListener(btnShowOnClickListener);
    }
    
    OnClickListener btnShowOnClickListener =
     new OnClickListener(){

   @Override
   public void onClick(View v) {
    Intent intent = new Intent(
     MainActivity.this, 
     ShowWebChartActivity.class);
    
    intent.putExtra("NUM1", getNum(num1));
    intent.putExtra("NUM2", getNum(num2));
    intent.putExtra("NUM3", getNum(num3));
    intent.putExtra("NUM4", getNum(num4));
    intent.putExtra("NUM5", getNum(num5));

    startActivity(intent);
   }
     
    };
    
    private int getNum(EditText editText){
     
     int num = 0;

     String stringNum = editText.getText().toString();
     if(!stringNum.equals("")){
      num = Integer.valueOf(stringNum);
     }
     
     return (num);
    }

}

/res/layout/activity_main.xml, layout of MainActivity.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.example.androidwebchart.MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />
    <EditText
        android:id="@+id/num1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="number"/>
    <EditText
        android:id="@+id/num2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="number"/>
    <EditText
        android:id="@+id/num3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="number"/>
    <EditText
        android:id="@+id/num4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="number"/>
    <EditText
        android:id="@+id/num5"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="number"/>
    <Button
        android:id="@+id/show"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Show Chart"/>

</LinearLayout>

When User click on the "Show Chart" button, it will start another activity, ShowWebChartActivity.java, and pass user data. ShowWebChartActivity load a WebView with our HTML to display Google Charts with Javascript. We have to implement WebAppInterface, with methods of @JavascriptInterface, getNum1()...getNum5(). It will be called by Javascript inside HTML to retrieve user data.
package com.example.androidwebchart;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;

@SuppressLint("SetJavaScriptEnabled") 
public class ShowWebChartActivity extends ActionBarActivity {
 
 WebView webView;
 int num1, num2, num3, num4, num5;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_webchart);
        
        Intent intent = getIntent();
        num1 = intent.getIntExtra("NUM1", 0);
        num2 = intent.getIntExtra("NUM2", 0);
        num3 = intent.getIntExtra("NUM3", 0);
        num4 = intent.getIntExtra("NUM4", 0);
        num5 = intent.getIntExtra("NUM5", 0);
        
        webView = (WebView)findViewById(R.id.web);
        webView.addJavascriptInterface(new WebAppInterface(), "Android");

        webView.getSettings().setJavaScriptEnabled(true); 
        webView.loadUrl("file:///android_asset/chart.html");
 }

 public class WebAppInterface {

     @JavascriptInterface
  public int getNum1() {
   return num1;
  }
  
  @JavascriptInterface
  public int getNum2() {
   return num2;
  }
  
  @JavascriptInterface
  public int getNum3() {
   return num3;
  }
  
  @JavascriptInterface
  public int getNum4() {
   return num4;
  }
  
  @JavascriptInterface
  public int getNum5() {
   return num5;
  }
 }

}

/res/layout/layout_webchart.xml, layout of ShowWebChartActivity.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />
    
    <WebView
        android:id="@+id/web"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

/assets/chart.html, our HTML to load and display Google Charts. Actually it is modified from Google Quick Start example of pie chart. The main difference is it retrieve user data by calling Android JavascriptInterface methods (getNum1()...getNum5()), instead of fixed data.
<html>
  <head>
    <!--Load the AJAX API-->
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
    
      // Load the Visualization API and the piechart package.
      google.load('visualization', '1.0', {'packages':['corechart']});
      
      // Set a callback to run when the Google Visualization API is loaded.
      google.setOnLoadCallback(drawChart);


      // Callback that creates and populates a data table, 
      // instantiates the pie chart, passes in the data and
      // draws it.
      function drawChart() {

      // Create the data table.
      var data = new google.visualization.DataTable();
      data.addColumn('string', 'ITEM');
      data.addColumn('number', 'VALUE');
      data.addRows([
        ['Item 1', Android.getNum1()],
        ['Item 2', Android.getNum2()],
        ['Item 3', Android.getNum3()], 
        ['Item 4', Android.getNum4()],
        ['Item 5', Android.getNum5()]
      ]);

      // Set chart options
      var options = {'title':'Android-er: Load Google Charts (pie chart) with WebView',
                     'width':600,
                     'height':600};

      // Instantiate and draw our chart, passing in some options.
      var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
      chart.draw(data, options);
    }
    </script>
  </head>

  <body>
 <!--Div that will hold the pie chart-->
    <div id="chart_div" style="width:600; height:600"></div>
  </body>
</html>

Finally, modify AndroidManifest.xml to add <activity> of ShowWebChartActivity, and <uses-permission> of "android.permission.INTERNET".
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.androidwebchart"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".ShowWebChartActivity"
            android:label="@string/app_name" >
        </activity>
    </application>

</manifest>


download filesDownload the files.

- More Google Charts examples on Android WebView
Capture image generated by Google Charts API
Display Donut Chart on Android WebView, using Google Charts