返回介绍

插件 - 可视化开发示例

发布于 2020-06-28 10:03:46 字数 14626 浏览 1000 评论 0 收藏 0

上一节,我们看到了一个完整的 Kibana 插件的官方用例。一般来说,我们不太会需要自己从头到尾写一个 angular app 出来。最常见的情况,应该是在 Kibana 功能的基础上做一定的二次开发和扩展。其中,可视化效果应该是重中之重。本节,以一个红绿灯效果,演示如何开发一个 Kibana 可视化插件。

可视化开发示例 - 图1

插件目录生成

Kibana 开发组提供了一个简单的工具,辅助我们生成一个 Kibana 插件的目录结构:

  1. npm install -g yo
  2. npm install -g generator-kibana-plugin
  3. mkdir traffic_light_vis
  4. cd traffic_light_vis
  5. yo kibana-plugin

但是这个是针对完整的 app 扩展的,很多目录对于可视化插件来说,并没有用。所以,我们可以自己手动创建目录:

  1. mkdir -p traffic_light_vis/public
  2. cd traffic_light_vis
  3. touch index.js package.json
  4. cd public
  5. touch traffic_light_vis.html traffic_light_vis.js traffic_light_vis.less traffic_light_vis_controller.js traffic_light_vis_params.html

其中 index.js 内容如下:

  1. 'use strict';
  2. module.exports = function (kibana) {
  3. return new kibana.Plugin({
  4. uiExports: {
  5. visTypes: ['plugins/traffic_light_vis/traffic_light_vis']
  6. }
  7. });
  8. };

package.json 内容如下:

  1. {
  2. "name": "traffic_light_vis",
  3. "version": "0.1.0",
  4. "description": "An awesome Kibana plugin for red/yellow/green status visualize"
  5. }

这两个基础文件格式都比较固定,除了改个名就基本 OK 了。

然后我们看最关键的可视化对象定义 public/traffic_light_vis.js 内容:

  1. define(function (require) {
  2. // 加载样式表
  3. require('plugins/traffic_light_vis/traffic_light_vis.less');
  4. // 加载控制器程序
  5. require('plugins/traffic_light_vis/traffic_light_vis_controller');
  6. // 注册到 vis_types
  7. require('ui/registry/vis_types').register(TrafficLightVisProvider);
  8. function TrafficLightVisProvider(Private) {
  9. // TemplateVisType 基类,适用于基础的 metric 和数据表格式的可视化定义。实际上,Kibana4 的 metric_vis 和 table_vis 就继承自这个,
  10. // Kibana4 还有另一个基类叫 VisLibVisType,其他使用 D3.js 做可视化的,继承这个。
  11. var TemplateVisType = Private(require('ui/template_vis_type/TemplateVisType'));
  12. var Schemas = Private(require('ui/Vis/Schemas'));
  13. // 模板化的 visType 对象定义,用来配置和展示
  14. return new TemplateVisType({
  15. name: 'traffic_light',
  16. // 显示在 visualize 选择列表里的名称,描述,小图标
  17. title: 'Traffic Light',
  18. description: 'Great for one-glance status readings, the traffic light visualization expresses in green / yellow / red the position of a single value in relation to low and high thresholds.',
  19. icon: 'fa-car',
  20. // 可视化效果模板页面
  21. template: require('plugins/traffic_light_vis/traffic_light_vis.html'),
  22. params: {
  23. defaults: {
  24. fontSize: 60
  25. },
  26. // 编辑参数的页面
  27. editor: require('plugins/traffic_light_vis/traffic_light_vis_params.html')
  28. },
  29. // 在编辑页面上可以选择的 aggregation 类型。
  30. schemas: new Schemas([
  31. {
  32. group: 'metrics',
  33. name: 'metric',
  34. title: 'Metric',
  35. min: 1,
  36. defaults: [
  37. { type: 'count', schema: 'metric' }
  38. ]
  39. }
  40. ])
  41. });
  42. }
  43. // export the provider so that the visType can be required with Private()
  44. return TrafficLightVisProvider;
  45. });

然后就是可视化效果的模板页面了,traffic_light_vis.html 毫无疑问也是一个 angular 风格的:

  1. <div ng-controller="TrafficLightVisController" class="traffic-light-vis">
  2. <div class="metric-container" ng-repeat="metric in metrics">
  3. <div class="traffic-light-container" ng-style="{'width': vis.params.width+'px', 'height': (2.68 * vis.params.width)+'px' }">
  4. <div class="traffic-light">
  5. <div class="light red" ng-class="{'on': (!vis.params.invertScale && metric.value <= vis.params.redThreshold) || (vis.params.invertScale && metric.value >= vis.params.redThreshold) }"></div>
  6. <div class="light yellow" ng-class="{'on': (!vis.params.invertScale && metric.value > vis.params.redThreshold && metric.value < vis.params.greenThreshold) || (vis.params.invertScale && metric.value < vis.params.redThreshold && metric.value > vis.params.greenThreshold) }"></div>
  7. <div class="light green" ng-class="{'on': (!vis.params.invertScale && metric.value >= vis.params.greenThreshold) || (vis.params.invertScale && metric.value <= vis.params.greenThreshold) }"></div>
  8. </div>
  9. </div>
  10. <div>{{metric.label}}</div>
  11. </div>
  12. </div>

这里可以看到:

  1. 把 div 绑定到了 TrafficLightVisController 控制器上,这个也是之前在 js 里已经加载过的。
  2. 通过 ng-repeat 循环展示不同的 metric,也就是说模板渲染的时候,收到的是一个 metrics 数组。这个来源当然是在控制器里。
  3. 然后具体的数据判断,即什么灯亮什么灯灭,通过了 vis.params.* 的运算判断。这些变量当然是在编辑页面里设置的。

所以下一步看编辑页面 traffic_light_vis_params.html

  1. <div class="form-group">
  2. <label>Traffic light width - {{ vis.params.width }}px</label>
  3. <input type="range" ng-model="vis.params.width" class="form-control" min="30" max="120"/>
  4. </div>
  5. <div class="form-group">
  6. <label>Red threshold <span ng-bind-template="({{!vis.params.invertScale ? 'below':'above'}} this value will be red)"></span></label>
  7. <input type="number" ng-model="vis.params.redThreshold" class="form-control"/>
  8. </div>
  9. <div class="form-group">
  10. <label>Green threshold <span ng-bind-template="({{!vis.params.invertScale ? 'above':'below'}} this value will be green)"></span></label>
  11. <input type="number" ng-model="vis.params.greenThreshold" class="form-control"/>
  12. </div>
  13. <div class="form-group">
  14. <label>
  15. <input type="checkbox" ng-model="vis.params.invertScale">
  16. Invert scale
  17. </label>
  18. </div>

内容很简单,就是通过 ng-model 设置绑定变量,跟之前 HTML 里的联动。

最后一步,看控制器 traffic_light_vis_controller.js

  1. define(function (require) {
  2. var module = require('ui/modules').get('kibana/traffic_light_vis', ['kibana']);
  3. module.controller('TrafficLightVisController', function ($scope, Private) {
  4. var tabifyAggResponse = Private(require('ui/agg_response/tabify/tabify'));
  5. var metrics = $scope.metrics = [];
  6. $scope.processTableGroups = function (tableGroups) {
  7. tableGroups.tables.forEach(function (table) {
  8. table.columns.forEach(function (column, i) {
  9. metrics.push({
  10. label: column.title,
  11. value: table.rows[0][i]
  12. });
  13. });
  14. });
  15. };
  16. $scope.$watch('esResponse', function (resp) {
  17. if (resp) {
  18. metrics.length = 0;
  19. $scope.processTableGroups(tabifyAggResponse($scope.vis, resp));
  20. }
  21. });
  22. });
  23. });

要点在:

  1. $scope.$watch('esResponse', function(resp){}) 监听整个页面的请求响应,在有新数据过来的时候更新页面效果;
  2. agg_response/tabify/tabify 把响应结果转换成二维表格形式。

最后加上一段样式表,这里就不贴了,见:https://github.com/logzio/kibana-visualizations/blob/master/traffic_light_vis/traffic_light_vis.less

本节介绍的示例,出自 logz.io 官方博客和对应的 github 开源项目。logz.io 是基于 Kibana4.1 写的插件。我这里修正成了基于最新 Kibana4.3 的实现。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文