hzhao

PI Coresight 2016 添加自定义图案(custom symbol)

Blog Post created by hzhao Employee on Aug 17, 2016

PI Coresight 2016相比于之前版本有非常大的变化,其中一项重要的改进是允许用户自己添加自定义的图案。pisquare中已经有非常多相关的post,如添加谷歌地图,添加RSS种子添加时间轴等等,并且不断有新的post更新。相关的配置文档可以在此处找到,此外在github上有关于custom symbol比较详细的介绍,下面结合其中一个案例(单个值的图形),简单介绍一下创建custom symbol的基本方法,和一些配置参数。

在PI Coresight的安装文件夹下INSTALLATION_FOLDER\Scripts\app\editor\symbols\ext创建名为sym-simplevalue.js的文件。如果ext文件夹不存在,您需要手动创建此文件夹。

将如下代码添加到刚创建的js文件中,这会初始化用于创建custom symbol的结构。这个代码创建了一个IIFE(immediately invoked functional expression,立即执行函数),此函数将会取到将会被用来注册symbol的PI Coresight对象

(function (CS) {
})(window.Coresight);

创建一个定义对象,并注册。这里symbol catalog是一个我们用来注册和管理所有Coresight symbols。我们这样会创建一个空的对象,并将其传递到注册函数中。因为这是一个立即执行函数,一旦浏览器执行它,它将会运行这个注册的代码

(function (CS) {
    var definition = {};
    CS.symbolCatalog.register(definition);
})(window.Coresight);

接下来我们,开始添加一个新的图案中必须的部分:

typeName是PI Coresight注册时使用的一个内部名字。这个名字在所有Coresight的图案中必须是唯一的。

datasourceBehavior用来指定有多少搜索结果(None用来表示静态值,Single表示单个值,Multiple表示多个值。此处我们使用单个值,如果需要画自定义的trend,那就需要多个值,即multiple)可以被用来创建这个图案。

(function (CS) {
    var definition = {
        typeName: 'simplevalue',
        datasourceBehavior: CS.DatasourceBehaviors.Single
    };
    CS.symbolCatalog.register(definition);
})(window.Coresight);

接下来,我们将添加一些具体使用的信息:这里我们会添加getDefaultConfig属性。这个函数是用来指定一系列symbol形态的参数的。如这里我们指定datashape为Value,那我们会显示一个value的图案

(function (CS) {
   var definition = {
  typeName: 'simplevalue',
  datasourceBehavior: CS.DatasourceBehaviors.Single,
   getDefaultConfig: function() {
   return {
  DataShape: 'Value'
  };
  }
  };
   CS.symbolCatalog.register(definition);
})(window.Coresight);

在继续完善之前的代码之前,我们现在与之前js文件相同的文件夹下创建一个名为sym-simplevalue-template.html的函数,这里命名的规则是:sym-<图案类型名>-template.html。这是一个symbol框架会默认去寻找的名字,如果template路径没有在symbol中被指定的话(可以通过templateUrl来指定)。加入以下内容到HTML文件。这里现在只是一个占位符。

<div style="background: red">
    <div>Simple Value</div>
</div>

这里,为了让这个心得图案被PI Coresight 网页服务器接收到,需要运行IIS reset

接下来,打开Coresight的页面,搜索一个PI点或者AF属性,将该属性拖动到画布中。您会发现当您放下这个item之后,您还无法选择它。这是因为这个图案没有包括一个init函数。

为了修复这个问题,我们需要更新getDefaultConfig函数,让它返回高(Height)和宽(Width)。此外我们需要添加初始化(initialization)函数到definition对象中。init函数是在图案被添加到画布的时候被调用的。

(function (CS) {
    var definition = {
        typeName: 'simplevalue',
        datasourceBehavior: CS.DatasourceBehaviors.Single,
        getDefaultConfig: function() {
            return {
                DataShape: 'Value',
                Height: 150,
                Width: 150
            };
        },
        init: init
    };


    function init() {
    }


    CS.symbolCatalog.register(definition);
})(window.Coresight);

再在Coresight中添加新的图案。图案现在可以被选择、移动,并且可以使用Coresight中的撤销功能了。这样基础架构已经搭好了,为了给图案添加新的功能,我们需要扩展init函数。我们会添加一个新的参数到这个函数中scope。Scope是一个从AngularJS中借用的,是一个让页面和后台JS更方便互动的框架。init函数会有一个函数来处理当图案获得一个新的数据时。最终我们会添加一个返回函数到init函数中,让PI Coresight知道如何和图案交互。

function init(scope) {
    function onUpdate(data) {
    }
    return { dataUpdate: onUpdate };
}

上面这段代码告诉PI Coresight每当数据更新时去调用onUpdate函数。现在我们需要对onUpdate函数做一些扩展

用下面这段函数来添加一些变量到scope中:value,timelabel。这样可以让这些变量在HTML展示画面中使用。为了完整性,我们会检查data和Label这两个变量在被onUpdate函数使用时是否已经被定义了。

function init(scope) {
    function onUpdate(data) {
        if(data) {
            scope.value = data.Value;
            scope.time = data.Time;
            if(data.Label) {
                scope.label = data.Label;
            }
        }
    }
    return { dataUpdate: onUpdate };
}

现在我们可以更新HTML文件来显示这些值了。我们使用AngularJS的样式来标记{{}}。此外我们还在div中添加了一些背景颜色的style。

<div style="background: orange; color: black">
    <div>{{label}}</div>
    <div>{{value}}</div>
    <div>{{time}}</div>
</div>

重新尝试在Coresight中添加这个新的图案。

接下来我们介绍如何修改这个图案的颜色。首先我们需要添加一个内容菜单的选项到图案中,这是通过添加configOptions属性来实现的。configOptions是一个图案可用属性的一个函数,它会返回一个控制配置的数组。在这个案例中,我们返回了名为‘Format Symbol’的对象。在这里使用的‘mode’是用来指定配置类型的。这样当我们右键点击图案,选择配置图案时,我们将会打开右侧PI Coresight 配置画面。

var definition = {
    typeName: 'simplevalue',
    datasourceBehavior: CS.DatasourceBehaviors.Single,
    getDefaultConfig: function() {
        return {
            DataShape: 'Value',
            Height: 150,
            Width: 150
        };
    },
    configOptions: function () {
        return [{
            title: 'Format Symbol',
            mode: 'format'
        }];
    },
    init: init
};

接下来我们需要创建一个configurationHTML的画面。在相同文件夹下创建sym-simplevalue-config.html文件。命名规则是sym-<图案名>-config.html。同理,如果不按照这个规则命名,需要在configTemplateUrl参数中指定。下面这个例子中包含了两种配置:文字颜色和背景颜色。我们这里使用了format-color-picker,这是一个AngularJS的服务让Coresight可以给图案挑选颜色。format-color-picker有两个属性:property和config。property对应config对象中传递进来的属性,config是图案中的config对象。

<div class="c-side-pane t-toolbar">
    <span style="color:#fff; margin-left:15px">Text Color</span>
</div>
<format-color-picker id="textColor" property="TextColor" config="config"></format-color-picker>
<div class="c-side-pane t-toolbar">
    <span style="color:#fff; margin-left:15px">Background Color</span>
</div>
<format-color-picker id="backgroundColor" property="BackgroundColor" config="config"></format-color-picker>

我们也需要对原来的展示页面做一些修改,使得我们配置页面的属性也可以关联进来。这里我们需要用到一个AngularJS的辅助工具,ng-style

<div ng-style="{background: config.BackgroundColor, color: config.TextColor}">
    <div>{{label}}</div>
    <div>{{value}}</div>
    <div>{{time}}</div>
</div>

最后,我们还可以配置我们的图案,使之可以显示或隐藏一部分属性。要做到这点,我们需要更新getDefaultConfig函数,使之包含可以显示或者隐藏标题和时间的boolean形变。如下面的代码所示,默认我们是会显示标题,但不显示时间戳

getDefaultConfig: function() {
    return {
        DataShape: 'Value',
        Height: 150,
        Width: 150,
        BackgroundColor: 'rgb(255,0,0)',
        TextColor: 'rgb(0,255,0)',
        ShowLabel: true,
        ShowTime: false
    };
},

同时,展示的html画面也需要做一些修改,我们通过ng-show的辅助工具(同样也是angularJS的功能)可以控制是否显示相应的属性。当绑定的值为true是,将会显示这个元素,反之则隐藏这个元素。

<div ng-style="{background: config.BackgroundColor, color: config.TextColor}">
    <div ng-show="config.ShowLabel">{{label}}</div>
    <div>{{value}}</div>
    <div ng-show="config.ShowTime">{{time}}</div>
</div>

最后,我们对配置页面也需要做一些修改,使之可以选择是否显示时间或者标题。

<div class="c-side-pane t-toolbar">
    <span style="color:#fff; margin-left:15px">Text Color</span>
</div>
<format-color-picker id="textColor" property="TextColor" config="config"></format-color-picker>
<div class="c-side-pane t-toolbar">
    <span style="color:#fff; margin-left:15px">Background Color</span>
</div>
<format-color-picker id="backgroundColor" property="BackgroundColor" config="config"></format-color-picker>


<div class="c-side-pane t-toolbar">
    <span style="color:#fff; margin-left:15px">Show Options</span>
</div>
<div class="c-config-content">Show Label:
    <input type="checkbox" ng-model="config.ShowLabel">
</div>
<div class="c-config-content">Show Time:
    <input type="checkbox" ng-model="config.ShowTime">
</div>

这样基本的功能就完成了,下面我们修改一下配置信息使之可以显示multistate。要做到这一点,我们必须添加StateVariables到图案的definition对象。

var definition = {
    typeName: 'simplevalue',
    datasourceBehavior: CS.DatasourceBehaviors.Single,
    getDefaultConfig: function() {
        return {
            DataShape: 'Value',
            Height: 150,
            Width: 150,
            BackgroundColor: 'rgb(255,0,0)',
            TextColor: 'rgb(0,255,0)'
        };
    },
    StateVariables: [ 'MultistateColor' ],
    configOptions: function () {
        return [{
            title: 'Format Symbol',
            mode: 'format'
        }];
    },
    init: init
};

此外还需要对展示页面做一些修改,使得页面颜色可以使用multistate中定义的颜色。这里,如果multistate被定义了,那颜色就会用multistate的定义,如果没有定义,就用默认的颜色。

<div ng-style="{background: config.BackgroundColor, color: MultistateColor || config.TextColor}">
    <div ng-show="config.ShowLabel">{{label}}</div>
    <div>{{value}}</div>
    <div ng-show="config.ShowTime">{{time}}</div>
</div>

Outcomes