Android客户端使用highcharts进行图表展示

StanleyManc 3年前

来自: http://blog.csdn.net//guijiaoba/article/details/50493619


Android客户端使用highcharts进行图表展示


前面用过MPAndroidChart作为安卓客户端的图表展示库,以前的博客地址,这个是Github地址,但是领导说客户端的图表展示最好不用使用Native,然后推荐了一款Web 图表展示的库highcharts,进过尝试,发现效果还不错,这样满足了Android客户端和iOS客户端显示图表UI一致性,而且代码只需要一套,只需要在对应客户端把json数据发送给网页即可,废话少说,先给出效果图。

highcharts效果图

集成步骤

官方Demo

根据官方的Demo和效果编辑器,选择自己想要的效果,然后可以按照想要的效果进行编辑。

http://www.hcharts.cn/demo/index.php?p=10
http://www.hcharts.cn/test/index.php?from=demo&p=55

最终网页的代码是这样的:

<!doctype html>  <html lang="en">  <head>    <script type="text/javascript" src="http://cdn.hcharts.cn/jquery/jquery-1.8.3.min.js"></script>    <script type="text/javascript" src="http://cdn.hcharts.cn/highcharts/highcharts.js"></script>    <script type="text/javascript" src="http://cdn.hcharts.cn/highcharts/exporting.js"></script>    <script> //左侧Javascript代码 </script>  </head>  <body>    <div id="container" style="min-width:700px;height:400px"></div>  </body>  </html>

然后在<script>//左侧Javascript代码 </script> 里面填上你自己想要的js代码就可以了,下面的是官方的demo。

$(function () {       $('#container').highcharts({          chart: {              type: 'column'          },          title: {              text: 'My first Highcharts chart'          },          xAxis: {              categories: ['my', 'first', 'chart']          },          yAxis: {              title: {                  text: 'something'              }          },          series: [{              name: 'Jane',              data: [1, 0, 4]          }, {              name: 'John',              data: [5, 7, 3]          }]      });  });             

资源文件放在客户端

上面的网页文件显示每次需要加载jquery-1.8.3.min.js和highcharts.js,由于网络速度问题,为了加快加载速度,需要把这个两个文件放到本地,然后把所有必要的所有的文件放到assets中,下面是我自己的文件。

这里写图片描述

<!doctype html>  <html lang="en">  <head>      <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>  </head>  <body>  <div id="container" style='backgroundcolor:#ffffff'>    </div>  </body>  <script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>  <script type="text/javascript" src="js/highcharts.js"></script>  <script type="text/javascript" src="js/data.js" charset="utf-8"></script>  </html>

data.js就是自己需要展示数据的代码。

$(function () {      refresh(null);  });    function refresh(jsonStr){      if(jsonStr==null){          return;      }      var json = JSON.parse(jsonStr);      $('#container').highcharts({              chart: {                   type: 'column'              },              title: {                  text: 'Highcharts'              },              xAxis: {                  categories: json.categories              },              yAxis:[{                  labels: {                      format: '{value}¥'                  },                  title: {                      text: '单价'                  }                  },{                  labels: {                      format: '{value}%'                  },                  title: {                      text: '比率'                  },                  opposite: true              }],              series: [{                  color: '#4572A7',                  type: 'spline',                  yAxis: 1,                  name: '单价',                  data: json.series[0].data,                  tooltip: {                      valueSuffix: '¥'                  }              }, {                  color: '#89A54E',                  type: 'spline',                  name: '比率',                  data: json.series[1].data,                  tooltip: {                      valueSuffix: '%'                  }              }],              credits:{                  enabled:false              }          });  };

Android代码

下面介绍如何加载网页,以及如何刷新数据。由于就是显示一个网页,只需要在Activity中添加一个WebView即可。

layout资源文件

<?xml version="1.0" encoding="utf-8"?>  <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:orientation="vertical" tools:context="cn.mycommons.hchartsdemo.MainActivity">      <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button" />      <WebView android:id="@+id/webView" android:layout_width="match_parent" android:layout_height="match_parent" />  </LinearLayout>

然后是Java代码,代码里面定义每次点击按钮,就在Java层随机生成一些数据,然后把这些数据转成json字符串

public class MainActivity extends AppCompatActivity {        WebView webView;        @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);            findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  loadUrl("javascript:refresh('" + getJsData() + "')");              }          });          webView = (WebView) findViewById(R.id.webView);          //覆盖WebView默认使用第三方或系统默认浏览器打开网页的行为,使网页用WebView打开          webView.setWebViewClient(new WebViewClient() {                @Override              public boolean shouldOverrideUrlLoading(WebView view, String url) {                  // 返回值是true的时候控制去WebView打开,为false调用系统浏览器或第三方浏览器                  view.loadUrl(url);                  return true;              }                @Override              public void onPageFinished(WebView view, String url) {                  if (!webView.getSettings().getLoadsImagesAutomatically()) {                      webView.getSettings().setLoadsImagesAutomatically(true);                  }              }          });          // 启用支持javascript          WebSettings settings = webView.getSettings();          settings.setJavaScriptEnabled(true);          settings.setCacheMode(WebSettings.LOAD_DEFAULT);          settings.setDomStorageEnabled(true);          settings.setAppCacheMaxSize(8 * 1024 * 1024);          settings.setAllowFileAccess(true);          settings.setAppCacheEnabled(true);          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {              webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);          }          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {              settings.setLoadsImagesAutomatically(true);          } else {              settings.setLoadsImagesAutomatically(false);          }            // 加载网页文件          loadUrl("file:///android_asset/index.html");      }        void loadUrl(final String url) {          runOnUiThread(new Runnable() {              @Override              public void run() {                  webView.loadUrl(url);              }          });      }        String getJsData() {          JsData data = new JsData();          data.categories = new String[]{"春", "夏", "秋", "冬"};          data.series = new YData[2];          Random random = new Random();          for (int i = 0; i < data.series.length; i++) {              data.series[i] = new YData();              data.series[i].name = "Name" + (i + 1);              int j = i;              data.series[i].data = new int[]{100 * j + random.nextInt(100), 100 * j + random.nextInt(100), 100 * j + random.nextInt(100), 100 * j + random.nextInt(100)};          }          String json = new Gson().toJson(data);          System.out.println("json = " + json);          return json;      }  }

当json字符串生成时候,再调用loadUrl("javascript:refresh('" + getJsData() + "')"); 传递给网页,这样网页就能刷新表格了。

在下面是json结构体。

class JsData {      String[] categories;      YData[] series;  }    class YData {        String name;        int[] data;  }

当数据到底js层时候,先把json字符串转成Json对象,然后进行适当复制,刷新下界面即可。

$(function () {     refresh(null);  });function refresh(jsonStr){     if(jsonStr==null){          return;      }      var json = JSON.parse(jsonStr);      $('#container').highcharts({              chart: {                   type: 'column'             },              title: {                  text: 'Highcharts'             },              xAxis: {                  categories: json.categories              },              yAxis:[{                  labels: {                      format: '{value}¥'                 },                  title: {                      text: '单价'                 }                  },{                  labels: {                      format: '{value}%'                 },                  title: {                      text: '比率'                 },                  opposite: true             }],              series: [{                  color: '#4572A7',                  type: 'spline',                  yAxis: 1,                  name: '单价',                  data: json.series[0].data,                  tooltip: {                      valueSuffix: '¥'                 }              }, {                  color: '#89A54E',                  type: 'spline',                  name: '比率',                  data: json.series[1].data,                  tooltip: {                      valueSuffix: '%'                 }              }],              credits:{                  enabled:false             }          });  };

总结

实际上现在移动客户端有很多优秀的图表展示框架,比如前面提到的MPAndroidChart。MPAndroidChart的动画效果简直是吊炸天。但是有时候可以牺牲吊炸天,使用较为低效的web界面来展示图表。

优点:
集成简单,公司内部Web前端工程师较多,遇到复杂难题,可以进行交流讨论。
Android,iOS,Web三个界面,可以做到UI统一,用户没有学习成本。
Android,iOS客户端可以使用同样一套代码(html+js)。

缺点:
展示较慢,因为是WebView展示,多少会比Native卡顿许多。

问答:
有人问,为什么不直接使用一个H5页面,并且使用Native加载数据,然后再由Native传递json给Webview。
答:其实这样也是可以的,但是有些客户端加载数据不一定是走http协议,那么由H5加载则需要添加新的接口。有的客户端加载数据,需要传递session和cookies,比较麻烦,所以我在这边选择了Native加载数据的方式。