Jump to: navigation, search

Configure and customize chart properties


Chart properties are used to provide historical values to a UBIK® client for display in a chart. This article covers how to configure and customize them on the server side. There is another article addressing the client-side UI customization of Charts.


[edit]

Basic configuration

  • Open the Custom.Main.Base.CUSTOMMETAPROPERTY MetaClass in a Bulk Editor.
  • Create a new instance
  • Fill in at least the Name (NAME) and set the Item type (TYPE) to "Chart".
  • Assign the new MetaProperty to a MetaClass of your choice using the Class Details Browser or the Relation Editor.
  • For display on the client, make sure there is a MetaClassScope for that MetaClass also relating to the new MetaProperty.

Assigning and reading values

Chart values can only be set programmatically; there is no UI for entering "ChartData" values (when this article was written). The recommended ways to provide values for Chart properties are:

  • Import: Use an InterfaceExecutor defined in plugin code or custom code to set chart values imported from a 3rd party system via the Enterprise Service (using UBIK® Proxies).
  • On-demand calculation: Use custom code to assemble chart data on demand, when the property value is requested.
  • Manual assignment: Use the Debugger ("Who-Bert") to execute a script assembling and assigning chart data to one or more instances, e.g., with hard-coded values or parsing from a file.

Assembling ChartData

ChartData is a C# type used to encode chart values. Here's how it looks like (omitting irrelevant code):

namespace UBIK.Service.DTO.V262
{
    public class ChartData
    {
        public string Header { get; set; }
        public ChartAxis PrimaryAxis { get; set; }
        public ChartAxis SecondaryAxis { get; set; }
        public ChartValueSeries[] Series { get; set; }
        public ChartThreshold[] Thresholds { get; set; }
    }

    public class ChartAxis
    {
        public string Header { get; set; }
        public double Interval { get; set; }
        public int DateTimeIntervalType { get; set; }
        public string LabelFormat { get; set; }
        public object Minimum { get; set; }
        public object Maximum { get; set; }
    }

    public class ChartValueSeries
    {
        public string Name { get; set; }
        public int Color { get; set; }
        public ChartItem[] Items { get; set; }
    }

    public class ChartItem
    {
        public object XValue { get; set; }
        public object YValue { get; set; }
    }

    public class ChartThreshold
    {
        public object Value { get; set; }
        public int Color { get; set; }
    }
}

You can assemble chart data by instantiating the ChartData type and assigning the property values respectively. The resulting object can be assigned to UBIK® Chart properties.

The Charts article explains the effect of the ChartData members on the chart.

Another question is where to get the values from. This is covered in a dedicated article.

Custom code example

As explained above, you can either import chart values or you can customize the property to assemble chart data on demand. Here's example code for the latter option, assuming you already read some historical data from Aveva/Osi PI.

MetaProperty custom code

//CHART Property:
//In this case it's called PLOTDATA

public override UBIK.Service.DTO.V262.ChartData PLOTDATA
{
    get
    {
            plotdata = null;
            object plot = this.GetPlotValues(); // values read from Aveva/Osi PI system

            if (plot as UBIK.Interface.Module.OSIPI.PiWebApiDataModel.ValuesFloat32 != null)
            {
                //UBIKKernel.LogDebugOutput(System.Reflection.MethodBase.GetCurrentMethod(), -5005, ((UBIK.Interface.Module.OSIPI.PiWebApiDataModel.ValuesFloat32)plot).Items.Length.ToString(), this);
                this.CreateChartData32((UBIK.Interface.Module.OSIPI.PiWebApiDataModel.ValuesFloat32)plot, this.Name);
            }
            if (plot as UBIK.Interface.Module.OSIPI.PiWebApiDataModel.ValuesFloat64 != null)
            {
                //UBIKKernel.LogDebugOutput(System.Reflection.MethodBase.GetCurrentMethod(), -5006, ((UBIK.Interface.Module.OSIPI.PiWebApiDataModel.ValuesFloat64)plot).Items.Length.ToString(), this);
                this.CreateChartData64((UBIK.Interface.Module.OSIPI.PiWebApiDataModel.ValuesFloat64)plot, this.Name);
            }
            return plotdata;
    }
    set
    {
        // do nothing, value is calculated on demand
    }
}

Custom object code

private UBIK.Service.DTO.V262.ChartData plotdata = null;
private string valueseries = null;

public void CreateChartData32(UBIK.Interface.Module.OSIPI.PiWebApiDataModel.ValuesFloat32 plotValue, string dataPointName)
{
    UBIK.Service.DTO.V262.ChartData chart = new UBIK.Service.DTO.V262.ChartData();
    chart.Header = "Trend " + dataPointName;
    chart.PrimaryAxis = new UBIK.Service.DTO.V262.ChartAxis
    {
        Header = "Timestamp",
        Interval = 1,
        LabelFormat = "hh:mm"
    };
    chart.SecondaryAxis = new UBIK.Service.DTO.V262.ChartAxis
    {
        Header = "Value " + this.EngineeringUnits,
        Interval = 0.5,
        LabelFormat = "0.##"
    };

    System.Collections.Generic.List<UBIK.Service.DTO.V262.ChartItem> values = new System.Collections.Generic.List<UBIK.Service.DTO.V262.ChartItem>();
    System.Text.StringBuilder stringbuilder = new System.Text.StringBuilder();

    foreach (UBIK.Interface.Module.OSIPI.PiWebApiDataModel.ValueFloat32 item in plotValue.Items)
    {
        if (item != null)
        {
            UBIK.Service.DTO.V262.ChartItem val = new UBIK.Service.DTO.V262.ChartItem();
            val.XValue = item.Timestamp.Add(TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow));
            val.YValue = item.Value;
            values.Add(val);
            stringbuilder.Append(val.XValue);
            stringbuilder.Append(";");
            stringbuilder.Append(item.Value.ToString(System.Globalization.CultureInfo.InvariantCulture));
            stringbuilder.Append(";");
        }
    }
    valueseries = stringbuilder.ToString();
    UBIK.Service.DTO.V262.ChartValueSeries serie = new UBIK.Service.DTO.V262.ChartValueSeries();
    serie.Name = "Values";
    serie.Color = -6356949;
    serie.Items = values.ToArray();
    chart.Series = new UBIK.Service.DTO.V262.ChartValueSeries[] { serie };

    plotdata = chart;
}

public void CreateChartData64(UBIK.Interface.Module.OSIPI.PiWebApiDataModel.ValuesFloat64 plotValue, string dataPointName)
{
    UBIK.Service.DTO.V262.ChartData chart = new UBIK.Service.DTO.V262.ChartData();
    chart.Header = "Trend " + dataPointName;
    chart.PrimaryAxis = new UBIK.Service.DTO.V262.ChartAxis
    {
        Header = "Timestamp",
        Interval = 1,
        LabelFormat = "hh:mm",
        //DateTimeIntervalType = 0
        //Maximum = maxYear.AddMonths(3),
        //Minimum = minYear.AddMonths(-3)
    };
    chart.SecondaryAxis = new UBIK.Service.DTO.V262.ChartAxis
    {
        Header = "Value " + this.EngineeringUnits,
        Interval = 0.5,
        LabelFormat = "0.##"
        //Maximum = maxWallThickness * 1.1,
        //Minimum = minWallThickness
    };

    System.Collections.Generic.List<UBIK.Service.DTO.V262.ChartItem> values = new System.Collections.Generic.List<UBIK.Service.DTO.V262.ChartItem>();
    System.Text.StringBuilder stringbuilder = new System.Text.StringBuilder();

    foreach (UBIK.Interface.Module.OSIPI.PiWebApiDataModel.ValueFloat64 item in plotValue.Items)
    {
        if (item != null)
        {
            UBIK.Service.DTO.V262.ChartItem val = new UBIK.Service.DTO.V262.ChartItem();
            val.XValue = item.Timestamp.Add(TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow));
            val.YValue = item.Value;
            values.Add(val);
            stringbuilder.Append(val.XValue);
            stringbuilder.Append(";");
            stringbuilder.Append(item.Value.ToString(System.Globalization.CultureInfo.InvariantCulture));
            stringbuilder.Append(";");
        }
    }
    valueseries = stringbuilder.ToString();
    UBIK.Service.DTO.V262.ChartValueSeries serie = new UBIK.Service.DTO.V262.ChartValueSeries();
    serie.Name = "Values";
    serie.Color = -6356949;
    serie.Items = values.ToArray();
    chart.Series = new UBIK.Service.DTO.V262.ChartValueSeries[] { serie };
    plotdata = chart;
}

See also