调试 DataWorks 数据服务接口与界面的可视化渲染

244 阅读5分钟

前言

在制作 BI 报表时,我们常需要在数据引擎上封装一层 API,透过界面上的参数变化查询 API,拿到数据进行渲染。DataWorks 数据服务提供了快速封装 API 的能力,且能在上面进行开发、上线、下线、版本比对等操作。基于采用不同类型的 BI 报表,调试 API 的方式也不同,有一些 BI 平台已经内建了数据服务能力、有一些则是依赖三方的数据服务平台,而后者又分为自建 BI 报表或使用 BI 平台的方式。本文将对自建 BI 报表及使用 BI 平台的两种方式与 DataWorks 数据服务如何进行调试进行说明。

BI 平台 + DataWorks 数据服务

目前数据源类型明确支持 DataWorks 数据服务的 BI 平台有 DataV,如果 BI 平台支持 API 为数据源的也是在此类的范畴中,DataV 很好地支持 DataWorks 数据服务,包含能透过下拉框的方式选用已上线 API,且还封装了 API 的 AK,这边以 DataV 的操作方式为范例。

创建数据源

进入工作台,于左侧选择数据源、新建数据源,于右侧数据源类型选择 DataWorks 数据服务,进行添加。

image

创建 API

进入 DataWorks 数据服务选用数据引擎、撰写 SQL 并上线一个 API。

image

搭建报表

进去 DataV 开发报表,从左侧组件库拖拽图型后,对此图型选用我们上述添加的 DataWorks 数据服务的数据源及新增加的 API。

image

比较需要注意的是设定过滤器的部份,因为 API 出来的格式是固定的,BI 报表上不一样的图表需要的格式却不一定,我们需要用过滤器将格式整理一下。

每个组件会附上查看示例的内容,如折线图的格式为 { "x", "y", "colorField"}。

image

我们新建一个过滤器将 API 返回的 data 字段转成 { "x", "y", "colorField"} 格式。

image

整理好格式后,DataWorks 数据服务的接口数据就能放到 DataV 上,并能快速地使用上 DataV 提供的能力。

image

自建 BI 报表 + DataWorks 数据服务

另外一种是用户自建 BI 报表,也可能是自建一个报表再透过 IFrame 的方式放到其它 BI 平台,如 Grafana。此方式通常需要用户自己搭建开发环境进行接口调试,这边我们提供使用 VSCode 开发工具、图形则使用 AntV 为例。

VSCode

VSCode 是前端热门的开发工具,且提供很多利于开发的插件,这边我们使用 Live Server (Five Server) 插件来负责建立本地 Server 的联调工作 (它提供了运行本地 Server 与 支持 PHP,能帮助做到如动态页面内容、封装 API AK 等能力)。

image

AntV

AntV 是蚂蚁集团支持的可视化工具包,里面有各式各样的可视化组件,我们这边主要以 G2 和 G2 Plot 为例 (G2 图形交互设定弹性高但不好上手,G2Plot 是简化设定的版本)。下面为 G2 / G2 Plot 的范例页面,我们能从里面挑选出例子来搭建我们的 BI 报表。

环境设定

  1. 下载 VSCode 并安装 Live Server (Five Server) 插件。

  2. 安装 php (以 mac 为例)

brew install php
  1. 建立文件夹 bi-report,并使用 VSCode 打开,在 bi-report 下建立 www 文件夹。

image

  1. 于 bi-report 文件夹下建立 fiveserver.config.json,并设定入口文件 index.html 与 php 指令的运行路径。
module.exports = {
  root: 'www',
  open: 'index.html',
  php: "/opt/homebrew/bin/php",
  higlight: true,
  injectBody: true,
};

image

搭建 API

至 DataWorks 数据服务搭建 API 并上线,点击带参数运行地址,拷贝 API 的 URL。

image

调示 API 及可视化渲染

于 index.html 设定引入 AntV 的包

下面我们以 G2 Plot 为例,参考此热力图范例

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/g2plot/2.4.31/g2plot.min.js" chartset="utf-8"></script>
</head>
<body>
  <div id="chart"></div>
  <script src="./index.js" chartset="utf-8"></script>
</body>
</html>

将图表渲染逻辑放在 index.js 里。

const { Heatmap } = G2Plot;
// 此 url 为 DataWorks 数据服务上线 API 点击带参数运行地址,拷贝的 API URL。
fetch('http://xxx-cn-shanghai.alicloudapi.com/B/west-lake-people-heatmap?appCode=xxx')
  .then((res) => res.json())
  .then((data) => {
    const heatmapPlot = new Heatmap(document.getElementById('chart'), {
      data,
      type: 'density',
      xField: 'g',
      yField: 'l',
      colorField: 'tmp',
      color: '#F51D27-#FA541C-#FF8C12-#FFC838-#FAFFA8-#80FF73-#12CCCC-#1890FF-#6E32C2',
      legend: {
        position: 'bottom',
      },
      annotations: [
        {
          type: 'image',
          start: ['min', 'max'],
          end: ['max', 'min'],
          src: 'https://gw.alipayobjects.com/zos/rmsportal/NeUTMwKtPcPxIFNTWZOZ.png',
        },
      ],
    });
    heatmapPlot.render();
  });

在 VSCode 左侧 bi-report 文件夹空白处点右键,选择 Open with Five Server (root),运行本地 Server。

image

动态联调 BI 内容

image

封装 API AK

上面的例子是直接将 API 的调用 AK 暴露在 HTML 请求上,安全性不高,如果要防止 AK 被拿走有以下几种方式。

建立登录态

透过登录机制来访问 BI 报表,此方式可以参考此文 developer.aliyun.com/article/138…

透过注册 API

于 DataWorks 数据服务注册 API,并将调用 AK 的信息封装在常量参数里,但此方式无法管理调用来源。

image

透过 PHP

此方式基于 Live Server (Five Server) 插件提供的 PHP 能力,建立一个 PHP Server,将调用的请求工作在 Server 内完成,用户无法查看到实际接口请求的过程。此方式一样无法管理调用来源,但少了注册 API 与开发登录态代码的麻烦。

这边我们以 G2 为例,范例为此中国地图

<html>
    <head>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/antv-g2/5.1.19/g2.min.js" chartset="utf-8"></script>
        <script src="https://cdn.jsdelivr.net/npm/@antv/data-set@0.8.7/dist/data-set.min.js" chartset="utf-8"></script>
      </head>
<body>
    <script>
        <?php 
            include('get.php');
        ?>
    </script>
    <div id="chart"></div>
    <script src="index.js" chartset="utf-8"></script>
</body>
</html>

将数据放在 dataStr ,并写入 HTML 上。

<?php 
    // $page = $_GET['page']; // use php command to run app and request index.php?page=1, can use $_GET['page'] to get value.
    $url = 'http://xxx-cn-shanghai.alicloudapi.com/B/west-lake-people-heatmap?appCode=xxx';
    // use key 'http' even if you send the request to https://...
    $options = [
        'http' => [
            'method' => 'GET',
        ],
    ];
    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);
    if ($result === false) {
        /* Handle error */
        echo "var dataStr = '[]';";
        return;
    }
    function append_string ($str1, $str2) { 
      
        // Using Concatenation assignment 
        // operator (.=) 
        $str1 .=$str2; 
          
        // Returning the result  
        return $str1; 
    } 
    
    $export = append_string("var dataStr = ", json_encode($result, true)); 
    $export = append_string($export, ";"); 
    echo $export;
?>

从 HTML 拿到 dataStr,放到 AntV 上。

const { Chart } = G2;
const chart = new Chart({
  container: 'chart',
  autoFit: true,
});
// 从 dataStr 拿到数据
const data = dataStr ? JSON.parse(dataStr) : [];
chart
  .polygon()
  .data({
    type: 'fetch',
    value: data,
    transform: [
      {
        type: 'custom',
        callback: (data) => {
          const dv = new DataSet.View().source(data).transform({
            type: 'bin.hexagon',
            fields: ['longitude', 'latitude'],
            binWidth: [2, 3],
            as: ['longitude', 'latitude', 'count'],
          });
          return dv.rows;
        },
      },
    ],
  })
  .encode('x', 'longitude')
  .encode('y', 'latitude')
  .encode('color', 'count')
  .scale('color', {
    range: '#BAE7FF-#1890FF-#0050B3',
  })
  .style('lineWidth', 5)
  .style('stroke', '#fff')
  .axis(false)
  .legend(false)
  .tooltip({
    field: 'count',
  })
  .state('active', { fill: 'orange' })
  .state('inactive', { opacity: 0.8 })
  .interaction('elementHighlight', true);
chart.render();

image

上线 BI Report

此处使用 PHP Server 为例,也可以使用其他方式如 nodejs 或 nginx 等。建立一台服务器,并安装 php,将上文 bi-report 文件夹拷贝到此服务器,于此文件夹下执行指令,打通服务器的网络,即可将此 BI 报表透过 IFrame 的方式输出。

php -S localhost:9000

其它

页面参数

fiveserver 本地调试的时候,PHP 不支持页面参数,如 index.php?page=2,取不到 page 参数。但报表上线后,可透过 $_GET 拿到页面参数。

post 方法的 PHP 写法

<?php 
    // $page = $_GET['page']; // use php command to run app and request index.php?page=1, can use $_GET['page'] to get value.
    $url = 'https://url.xxx/xxx';
    $data = ['key1' => 'value1', 'key2' => 'value2'];
    // use key 'http' even if you send the request to https://...
    $options = [
        'http' => [
            'header' => "Content-type: application/x-www-form-urlencoded\r\n",
            'method' => 'GET',
            'content' => http_build_query($data),
        ],
    ];
    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);
    if ($result === false) {
        /* Handle error */
        echo "var dataStr = '[]';";
        return;
    }
    function append_string ($str1, $str2) { 
      
        // Using Concatenation assignment 
        // operator (.=) 
        $str1 .=$str2; 
          
        // Returning the result  
        return $str1; 
    } 
    
    $export = append_string("var dataStr = ", json_encode($result, true)); 
    $export = append_string($export, ";"); 
    echo $export;
?>