实用的数据统计分析工具——数据透视插件

cnDevNet发表于:2020年11月10日 10:07:06更新于:2021年04月01日 15:15:23

Index

概要

当今信息化时代,数据之庞大以至于管理和理解变得愈发困难。在工作中越来越需要对数据进行可视化,这对提高效率和公司决策都起到了至关重要的作用!
今天就向大家推荐一款具有多表联例及在线生成数据透视图的kintone插件。让你在工作中能事半功倍!

 

配置插件

STEP1:下载并导入插件

1.插件源码下载并打包

2.在kintone中导入插件。关于插件的导入方法,请参考kintone帮助文档 在kintone中安装插件

STEP2:在应用中添加插件

在应用中添加插件(pivotTable)。关于插件的添加方法,请参考kintone帮助文档 在应用中添加插件

STEP3:配置插件

Form设置

0015fa9f71e2bc27c43ab63fd459820

数据透视显示区域(空白栏)。

数据源应用ID填写区域(数值)。

配置数据保存区域(多行文本框)。只需通过插件配置页面设置,应用内不可修改。

插件设置

1.在应用管理页面中点击“插件”,然后点击pivotTalbe插件的齿轮图标。

2.各项设置。

3.点击“保存”。

4.点击“应用的设置”页面上的“更新应用”,插件的设置即可生效。

0015faa0e264fabe978a803449df8eb

 

使用插件

在使用此插件前先要准备一到两个用于可视化数据的应用。再要准备一个添加此插件的应用,用于对之前准备的应用进行数据可视化展示。

STEP1:创建记录

在添加了此插件的应用中创建一条记录,输入一到两个数据源应用ID(先期准备的应用的APPID),点击“保存”按钮后进入详情画面。

0015fa9f7b57d38a7501a102b9709cb

STEP2:设置数据关联

双数据透视设置(记录详情页面)

0015faa0972cfe23cfdadd8692c076b 


将需要联例字段的节点通过鼠标拖拽的方式连接起来(可拖拽节点使用三方组件jsPlumb.js实现),右侧映射结果列表中的字段名可修改,完成后点击显示图标按钮。

0015faa0d1e625f2a99c4ccfba0e208


联例完成后,点击“显示图表”,显示数据透视表图表界面。

0015faa09f8031fdc80daa0674a823f


该数据透视表主要使用三方组件PivotTable.js实现,里面的字段可随意拖动。

0015faa0d1f48dd94d91e5c2b7c650f


点击“状态保存”按钮可保存数据透视设置信息及透视表筛选状态。

0015faa0d213dea4b6d0a599f627132

 

单数据透视

也可以选择单数据源应用。

通过复选框选择需要进行透视的数据字段,下方数据塞选条件设定框中可以设置查询条件,在查询语句最末端输入"#"时,弹出字段名列表选中后自动写入.请严格遵从kintone 查询语句要求输入(空格间隔,关键字需添加双引号等)。注:除复选框外其余功能用法均与双数据源一致。0015fa9ffa100f6caba9218b02a7673


打包

下载源码后输入以下命令:

1.npm install

2.run build

3.run build_plugin

输入以上命令后会在./build/目录下生成pivotTable.zip

 

下面贴出部分代码,全部代码请点击插件源码

以下代码为条件查询输入框生成及字段自动补全功能数据添加

// init autoCompleteValues for query
        const autoCompleteValues = [];
        dragElements.elementsValue.forEach(element =>{
          if (element.isNeedBindPoint && !(element.isCustomElement)) {
            autoCompleteValues.push({label: element.tableAttribute.labelName, value: element.tableAttribute.code});
            dragElements.query.queryMap[element.tableAttribute.labelName] = element.tableAttribute.code;
          }
        });
        // add query element
        const queryElement = ElementUtils.generateaQueryElementView();
        queryElement.id = `query_${appElementInfo.value.appId}`;
        elementView.query_elements_area.appendChild(ElementUtils
          .generateTextField(`${dragElements.elements[`${dragElements.appId}`].tableAttribute.labelName}`));
        elementView.query_elements_area.appendChild(queryElement);
        dragElements.query.queryElementId = queryElement.id;
        bindAutocompleteValues(queryElement.id, autoCompleteValues);

 

以下为数据绑定具体实现

const bindAutocompleteValues = (elementId, autoCompleteValues)=> {
    $(`#${elementId}`)
      .autocomplete({
        minLength: 0,
        position: {
          my: 'left top',
          at: 'left top',
          collision: 'none'
        },
        focus: ()=> {
          return false;
        },
        source: function(request, response) {
          // delegate back to autocomplete, but extract the last term
          if ((request.term).indexOf('#') !== -1) {
            const extract = extractLast(request.term);
            if (extract === '') {
              $(`#${elementId}`).autocomplete({
                position: {my: 'left top', at: `left+${focusPosition.left} top+${focusPosition.top}`, collision: 'none'}
              });
            }
            response($.ui.autocomplete.filter(
              autoCompleteValues, extract));
          }
        },
        select: function(e, ui) {
          var temp = this.value;
          var result = temp.substring(0, temp.lastIndexOf('#'));
          this.value = result + ui.item.label;
          return false;
        }
      });
//设置下拉列表宽度
      $(`#${elementId}`).data( "ui-autocomplete" )._resizeMenu = function() {
        this.menu.element.css({"width":400})
    }
    function extractLast(term) {
      return term.split(/#\s*/).pop();
    }
  };

 

以下代码为pivotTable三方插件的属性配置及实现代码

  let properties = {};
      if (settingConfigInfo.pivotConfig !== undefined && Object.keys(settingConfigInfo.pivotConfig).length > 0) {
        properties = settingConfigInfo.pivotConfig;
      } else if (analyzeData[0].length > 0) {
        properties.rows = [analyzeData[0][0]];
        properties.cols = [analyzeData[0][1]];
        properties.rendererName = 'Bar Chart';
      }
      properties.onRefresh = (pivotProperties)=> {
        const pivotConfig = JSON.parse(JSON.stringify(pivotProperties));
        // delete some values which are functions
        delete pivotConfig['aggregators'];
        delete pivotConfig['renderers'];
        // delete some bulky default values
        delete pivotConfig['rendererOptions'];
        delete pivotConfig['localeStrings'];
        settingConfigInfo.pivotConfig = pivotConfig;
      };
      //$.extend 为其引用的三方lib pivotTble 还提供了其他的lib 具体请参考(https://github.com/nicolaskruchten/pivottable)
      properties.renderers = $.extend(
        $.pivotUtilities.renderers,
        $.pivotUtilities.plotly_renderers,
        $.pivotUtilities.export_renderers,
      );
      $('#graph_container').pivotUI(
        analyzeData, properties, false, lang
      );

 以下为jsPlumb配置及绑定代码,适配多列表生成多个锚点

   bindPoint(anchorsSite) {
    jsPlumb.ready(() => {
      const common = (anchor) =>{
        return {
          endpoint: ['Dot', {
            radius: 10,
            fill: '#48A8E8'
          }], // 端点的形状
          connectorStyle: {
            strokeWidth: 2,
            stroke: '#48A8E8',
            // strokeStyle: '#61B7CF',
            joinstyle: 'round',
            outlineStroke: '',
            outlineWidth: 2
          }, // 连接线的颜色,大小样式
          connectorHoverStyle: {
            lineWidth: 2,
            stroke: 'red',
            outlineWidth: 2,
            outlineColor: ''
          },
          paintStyle: {
            strokeStyle: '#1e8151',
            stroke: 'green',
            fill: '#48A8E8',
            fillStyle: '#1e8151',
            radius: 6,
            lineWidth: 2
          },
          ReattachConnections: false,
          hoverPaintStyle: {stroke: 'lightblue'},
          isSource: anchor === Constant.ANCHORS_SITE_RIGHT, // 是否可以拖动(作为连线起点)
          connector: ['Flowchart'], // 连接线的样式种类有[Bezier],[Flowchart],[StateMachine ],[Straight ]
          isTarget: anchor === Constant.ANCHORS_SITE_LEFT, // 是否可以放置(连线终点)
          connectorOverlays: [
            ['Arrow', {
              width: 10,
              length: 10,
              location: 1
            }],
            ['Arrow', {
              width: 10,
              length: 10,
              location: 0.2
            }],
            ['Arrow', {
              width: 10,
              length: 10,
              location: 0.7
            }],
            ['Label', {
              label: '',
              cssClass: '',
              labelStyle: {
                color: 'red'
              },
              events: {
                click: function(labelOverlay, originalEvent) {
                }
              }
            }]
          ]
        };
      };
      this.elementsValue.forEach(point =>{
        const id = point.elementView.id;
        const uuid = `uuid_${id}`;
        if (point.isNeedBindPoint) {
          if (anchorsSite === Constant.ANCHORS_SITE_BOTH) {
            jsPlumb.addEndpoint(id, {
              anchor: Constant.ANCHORS_SITE_LEFT,
              uuid: `${uuid}_${Constant.ANCHORS_SITE_LEFT}`
            }, common(Constant.ANCHORS_SITE_LEFT));
            jsPlumb.addEndpoint(id, {
              anchor: Constant.ANCHORS_SITE_RIGHT,
              uuid: `${uuid}_${Constant.ANCHORS_SITE_RIGHT}`
            }, common(Constant.ANCHORS_SITE_RIGHT));
          } else {
            jsPlumb.addEndpoint(id, {
              anchor: anchorsSite,
              uuid: `${uuid}_${anchorsSite}`
            }, common(anchorsSite));
          }
        }
      });
    });
  }

 

注意事项

直接使用此处提供的程序范例的情况,才望子不予以保证程序的正常运行。

才望子不提供对程序范例的技术支持。