• MattFox

    I think I may have confused you a bit...

    When you use the dashboard designer, one of the options for the maSerialChart is time-format.
    so:

    <ma-serial-chart points="chartPoints" values="chartPointValues" time-format="DD mm"></ma-serial-chart>
    

    I trust that is more along the lines of what you are trying to accomplish. Refer to the moment.js website for their docs if you are looking to format the time value in a specific manner.

    posted in Mango Automation general Discussion read more
  • MattFox

    My pleasure @Jared-Wiltshire you guys are awesome. It's the least I could do.

    posted in Dashboard Designer & Custom AngularJS Pages read more
  • MattFox

    @phildunlap thanks Phil, I'll be sure to keep that in mind. Thank you both for your help

    posted in Mango Automation general Discussion read more
  • MattFox

    /ui/docs/ng-mango/ma-serial-chart
    

    Read the docs under API Docs -> components -> maSerialChart

    there's an attribute you can set to alter the format:

    time-format
    (optional)
    string	
    The moment.js time format to be used in displaying timestamps on the X axis.
    

    Put your moment.js format in there and that will let you set the format to 'DD mm' etc

    posted in Mango Automation general Discussion read more
  • MattFox

    @phillip-weeks there is something in the API that allows you to do it:
    /v1/data-points/enable-disable/{xid}
    Would not be impossible to make a component to do it using a $http.put request. Unless of course you'd rather not have to code something, but if it's there in the API it can't be far off...

    posted in Dashboard Designer & Custom AngularJS Pages read more
  • MattFox

    OK! Here is what the code would be like:
    You need to have a directory structure like this to make it work with my code:
    Use winscp to connect with SSH to your mango install.
    -/opt/mango/overrides/web/modules/mangoUI/web/userModule
    |->/opt/mango/overrides/web/modules/mangoUI/web/userModule/userModule.js
    |->->/opt/mango/overrides/web/modules/mangoUI/web/userModule/directives/gaugeChart.js

    Once configured, make sure you add userModule.js to the administration->UI Settings page under user module url.
    enter this:

    /modules/mangoUI/web/userModule/userModule.js
    

    in the userModule.js file paste this code:

    define(['angular', 'require','./directives/gaugeChart.js'], function(angular, require,gaugeChart) {
    var userModule = angular.module('userModule', ['maUiApp']);
    try
    {
    userModule.directive('gaugeChart', gaugeChart);
     return userModule;
    }catch(e){console.log(e);}
    });
    

    In the directives file, use the code in the post above.

    Now, to use this in your dashboard, simply do the same as above, except the tag would just be 'gauge-chart'

     <gauge-chart id="44cf2d0c-c777-41e0-b20d-ea11a3f9f0cb" style="position: absolute; width: 200px; height: 200px; left: 145px; top: 8px;" point-xid="DP_866585" start="180" end="260" 
      options="{
    	axes: [ {
        axisThickness: 1,
        axisAlpha: 0.2,
        tickAlpha: 0.2,
        valueInterval: 5,
        bands: [ {
          color: '#cc4748',
          endValue: 191,
          startValue: 180
        }, {
          color: '#fdd400',
          endValue: 202,
          startValue: 191
        }, {
          color: '#84b761',
          endValue: 232,
          innerRadius: '95%',
          startValue: 202
        }, {
          color: '#fdd400',
          endValue: 232,
          startValue: 234
        }, {
          color: '#cc4748',
          endValue: 260,
          startValue: 234
        }],
        bottomText: '[[value]] km/h',
        bottomTextYOffset: 0,
        startValue:180,
        endValue: 260
      } ]
    }
    "></gauge-chart>
    

    posted in Dashboard Designer & Custom AngularJS Pages read more
  • MattFox

    @leoboeng Yep, I now have a gauge with multiple colours on it.
    If you want to be able to use this code in a separate angular tag, you will need to create and upload the userModule.js file as provided by examples in the forum that Jared has put together, or look at the help.inifiniteautomation.com docs. Sorry not near a PC at the moment, can't give you a complete example.

    posted in Dashboard Designer & Custom AngularJS Pages read more
  • MattFox

    I Lied, here's a working directive fix from Jared's version 3.3.1 code. Feel free to add it or Jared may be able to utilise this in his latest revision. Bands value kept getting reset in directive after checking options. A mistake even I make with arrays.
    Thanks! Fox

    /**
     * @copyright 2016 {@link http://infiniteautomation.com|Infinite Automation Systems, Inc.} All rights reserved.
     * @author Jared Wiltshire
     */
    
    define(['amcharts/gauge', 'require', 'angular', './PointValueController'], function(AmCharts, require, angular, PointValueController) {
    'use strict';
    
    /**
     * @ngdoc directive
     * @name ngMango.directive:maGaugeChart
     * @restrict E
     * @description
     * `<ma-gauge-chart point="myPoint" style="width:100%; height:200px"></ma-gauge-chart>`
     * - This directive will display a gauge that can be tied to a data point's live value.
     * - You must use `<ma-get-point-value>` to provide a point value to `<ma-gauge-chart>`
     * - Note, you will need to set a width and height on the element.
     * - Options have been exposed via attributes, allowing you to set colors and ranges of multiple bands.
     * - <a ui-sref="ui.examples.singleValueDisplays.gauges">View Demo</a>
     *
    
     * @param {object} point The point object with the live value provided by `<ma-get-point-value>`.
     * @param {number=} value Allows you to set the gauge to a value that is not provided by the `point` attribute. Only use without the `point` attribute.
     * @param {number=} start Sets the starting value for the gauge.
     * @param {number=} end Sets the ending value for the gauge.
     * @param {boolean=} auto-start Set to `true` to enable auto selecting a `start` value for the gauge based on minimum value
     * from past week.
     * @param {boolean=} auto-end Set to `true` to enable auto selecting an `end` value for the gauge based on maximum value
     * from past week.
     * @param {number=} band-1-end Sets the ending value for the first band.
     * @param {string=} band-1-color Sets the color for the first band.
     * @param {number=} band-2-end Sets the ending value for the second band.
     * @param {string=} band-2-color Sets the color for the second band.
     * @param {number=} band-3-end Sets the ending value for the third band.
     * @param {string=} band-3-color Sets the color for the third band.
     * @param {number=} radius Sets the radius of the axis circled around the gauge. (default: 95%)
     * @param {number=} value-offset Sets the vertical offset of the value text. Negative moves the value up. (default: -20)
     * @param {number=} value-font-size Sets the fontsize of the value text. (default: 12)
     * @param {number=} axis-label-font-size Sets the fontsize of the labels around the axis.
     * @param {number=} axis-thickness Sets the thickness of the axis circle. (default: 1)
     * @param {number=} interval Sets the interval for each numbered tick on the gauge. (default: 6 evenly distributed numbered ticks)
     * @param {number=} tick-interval Sets the interval for the minor ticks. Divide this number into the numbered tick interval to
     *     get the number of minor ticks per numbered interval. (default: 5 evenly distributed minor ticks per numbered interval)
     * @param {number=} arrow-inner-radius Radius of the ring the arrow is attached to. (default: 8)
     * @param {number=} arrow-alpha Opacity of the arrow and the arrow ring. Ranges 0-1 as a decimal. (default: 1)
     * @param {number=} axis-alpha Opacity of the circular axis. Ranges 0-1 as a decimal. (default: 0.5)
     * @param {object=} options Extend [amCharts](https://www.amcharts.com/demos/angular-gauge/) configuration object for customizing design of the gauge.
     
     *
     * @usage
     * 
    <md-input-container flex>
        <label>Choose a point</label>
        <ma-point-list limit="200" ng-model="myPoint"></ma-point-list>
    </md-input-container>
    
    <ma-get-point-value point="myPoint"></ma-get-point-value>
    
    <p>Basic (defaults to 0-100)</p>
    <ma-gauge-chart point="myPoint" style="width:100%; height:200px"></ma-gauge-chart>
    
    <p>Set axis interval and start and end value</p>
    <ma-gauge-chart point="myPoint" interval="10" start="-20" end="120"
    style="width:100%; height:200px"></ma-gauge-chart>
    
    <p>Set color bands</p>
    <ma-gauge-chart point="myPoint" start="-20" interval="20" band-1-end="20"
    band-2-end="80" band-2-color="yellow" band-3-end="100" style="width:100%; height:200px">
    </ma-gauge-chart>
    
     *
     */
    function gaugeChart() {
        return {
            restrict: 'E',
            template: '<div ng-class="classes" class="amchart"></div>' +
            '<ma-point-statistics point="$ctrl.point" point-xid="{{$ctrl.pointXid}}"' +
            ' from="from" to="to" statistics="$ctrl.pointStats" rendered="false"></ma-point-statistics>' +
            '<ma-date-range-picker from="from" to="to" preset="LAST_1_MONTHS" update-interval="1 minutes"' +
            ' style="display: none;"></ma-date-range-picker>',
            scope: {},
            controller: GaugeChartController,
            controllerAs: '$ctrl',
            bindToController: {
              point: '<?',
              pointXid: '@?',
              start: '<?',
              end: '<?',
              autoStart: '<?',
              autoEnd: '<?',
              interval: '<?',
              band1End: '<?',
              band1Color: '@',
              band2End: '<?',
              band2Color: '@',
              band3End: '<?',
              band3Color: '@',
              radius: '@',
              valueOffset: '<?',
              valueFontSize: '<?',
              axisLabelFontSize: '<?',
              axisThickness: '<?',
              tickInterval: '<?',
              arrowInnerRadius: '<?',
              arrowAlpha: '<?',
              axisAlpha: '<?',
              options: '<?',
              value: '<?',
              renderValue: '&?'
            },
            designerInfo: {
                translation: 'ui.components.gaugeChart',
                icon: 'donut_large',
                category: 'pointValue',
                size: {
                    width: '200px',
                    height: '200px'
                },
                attributes: {
                    point: {nameTr: 'ui.app.dataPoint', type: 'datapoint'},
                    pointXid: {nameTr: 'ui.components.dataPointXid', type: 'datapoint-xid'},
                    band1Color: {type: 'color'},
                    band2Color: {type: 'color'},
                    band3Color: {type: 'color'},
                    autoStart: {type: 'boolean'},
                    autoEnd: {type: 'boolean'}
                }
            }
        };
    }
    
    GaugeChartController.$inject = PointValueController.$inject;
    
    function GaugeChartController() {
        PointValueController.apply(this, arguments);
        
        this.chartOptions = defaultOptions();
    }
    
    GaugeChartController.prototype = Object.create(PointValueController.prototype);
    GaugeChartController.prototype.constructor = GaugeChartController;
    
    GaugeChartController.prototype.$onInit = function() {
        this.updateChart();
        this.chart = AmCharts.makeChart(this.$element.find('.amchart')[0], this.chartOptions);
        this.updateChartValue();
    
    
    
        if(this.autoStart || this.autoEnd) {
            this.$scope.$watch('$ctrl.pointStats', function(newValue, oldValue) {
                if (newValue === undefined) return;
    
                if (this.autoStart) {
                    this.start = Math.floor(newValue.minimum.value / 10) * 10;
                }
                if (this.autoEnd) {
                    this.end =  Math.ceil(newValue.maximum.value / 10) * 10;
                }
                this.updateChart();
            }.bind(this));
        }
    };
    
    GaugeChartController.prototype.$onChanges = function(changes) {
        PointValueController.prototype.$onChanges.apply(this, arguments);
        
        var optionsChanged = false;
        for (var key in changes) {
            if (key !== 'point' && key !== 'pointXid' && key !== 'value' && !changes[key].isFirstChange()) {
                optionsChanged = true;
                break;
            }
        }
        
        if (optionsChanged) {
            this.updateChart();
        }
    };
    
    GaugeChartController.prototype.valueChangeHandler = function() {
        PointValueController.prototype.valueChangeHandler.apply(this, arguments);
        this.updateChartValue();
    };
    
    GaugeChartController.prototype.updateChartValue = function() {
        if (!this.chart) return;
        
        var value = this.getValue();
        var textValue = this.getTextValue();
        
        this.chart.arrows[0].setValue(value || 0);
        this.chart.axes[0].setBottomText(textValue);
    };
    
    //Matt Fox Change 18/5/18
    GaugeChartController.prototype.checkGaugeBands = function(bands)
    {
    var hasColour,hasStart,hasEnd;
    	for( var i=0;i<bands.length; i++)
    	{
    		hasColour = (bands[ i ].hasOwnProperty('color') && /^#(?:[0-9a-fA-F]{3}){1,2}$/.test( bands[ i ] ) )? true : false;
    		hasEnd = (bands[ i ].hasOwnProperty('endValue') && Number.isFinite( parseFloat( bands[ i ]['endValue']) ) )?true:false;
    		hasStart = (bands[ i ].hasOwnProperty('startValue') && Number.isFinite( parseFloat( bands[ i ]['startValue']) ) )?true:false;
    		
    		if( ! (hasColour&&hasEnd&&hasStart) )
    		{
    			console.log("Error: bands not configured correctly, cannot parse values");
    			return [];
    		}
    	}
    	return bands;
    };
    
    GaugeChartController.prototype.updateChart = function() {
        var options = angular.merge(this.chartOptions, this.options);
        var axis = options.axes[0];
        var arrow = options.arrows[0];
        
        //axis.bands = []; //<-- KEEPS RESETTING MY OPTIONS!!!!
    	if( axis.bands!==undefined && axis.bands.length > 0 )
    	{
    		axis.bands = this.checkGaugeBands(axis.bands);
    	}
    	else
    	{
    		axis.bands = [];
    	}
        axis.startValue = asNumber(this.start);
        axis.endValue = asNumber(this.end, 100);
    	
    	if(axis.bands.length==0)
    	{
    		if (this.band1End != null) {
    			var stop1 = asNumber(this.band1End);
    			axis.bands.push({
    				id: 'band1',
    				color: this.band1Color || '#84b761',
    				startValue: axis.startValue,
    				endValue: stop1
    			});
    			if (!this.end)
    				axis.endValue = stop1;
    		}
    		if (this.band1End != null && this.band2End != null) {
    			var stop2 = asNumber(this.band2End);
    			axis.bands.push({
    				id: 'band2',
    				color: this.band2Color || '#fdd400',
    				startValue: axis.bands[0].endValue,
    				endValue: stop2
    			});
    			if (!this.end)
    				axis.endValue = stop2;
    		}
    		if (this.band1End != null && this.band2End != null && this.band3End != null) {
    			var stop3 = asNumber(this.band3End);
    			axis.bands.push({
    				id: 'band3',
    				color: this.band3Color || '#cc4748',
    				startValue: axis.bands[1].endValue,
    				endValue: stop3
    			});
    			if (!this.end)
    				axis.endValue = stop3;
    		}
    	}
        axis.valueInterval = asNumber(this.interval, (axis.endValue - axis.startValue) / 5);
        
        axis.radius = this.radius || '100%';
        axis.bottomTextYOffset =  asNumber(this.valueOffset, -20);
        axis.bottomTextFontSize =  asNumber(this.valueFontSize, 12);
        axis.axisThickness =  asNumber(this.axisThickness, 1);
        axis.axisAlpha =  asNumber(this.axisAlpha, 0.5);
        axis.tickAlpha =  asNumber(this.axisAlpha, 0.5);
        
        if (this.axisLabelFontSize != null) {
            axis.fontSize = asNumber(this.axisLabelFontSize);
        }
        if (this.tickInterval != null) {
            axis.minorTickInterval = asNumber(this.tickInterval);
        }
        
        arrow.nailRadius = asNumber(this.arrowInnerRadius, 8);
        arrow.innerRadius = arrow.nailRadius + 3;
        arrow.alpha = asNumber(this.arrowAlpha, 1);
        arrow.nailBorderAlpha = arrow.alpha;
    
        if (this.chart) {
            this.chart.validateNow();
        }
    };
    
    function asNumber(value, defaultValue) {
        if (typeof value === 'number' && isFinite(value)) {
            return value;
        } else if (typeof value === 'string') {
            try {
                return parseFloat(value);
            } catch (e) {}
        }
        return defaultValue || 0;
    }
    
    function defaultOptions() {
        return {
            type: 'gauge',
            theme: 'light',
            addClassNames: true,
            axes: [{
                startValue: 0,
                endValue: 100,
                bands: [],
                bottomText: ''
            }],
            arrows: [{
                nailAlpha: 0,
                borderAlpha: 0,
                nailBorderThickness: 6
            }]
        };
    }
    
    return gaugeChart;
    
    }); // define
    

    posted in Dashboard Designer & Custom AngularJS Pages read more
  • MattFox

    Agreed, I examined Jared's code to see how it parses the options and how I've got it should work flawlessly.
    If I had more time I'd debug and try and help with a solution.

    posted in Dashboard Designer & Custom AngularJS Pages read more
  • MattFox

    @leoboeng said in Gauges Function AmCharts:

    >   "type": "gauge",
    >   "theme": "light",
    >   "axes": [ {
    >     "axisThickness": 1,
    >     "axisAlpha": 0.2,
    >     "tickAlpha": 0.2,
    >     "valueInterval": 5,
    >     "bands": [ {
    >       "color": "#cc4748",
    >       "endValue": 191,
    >       "startValue": 180
    >     }, {
    >       "color": "#fdd400",
    >       "endValue": 202,
    >       "startValue": 191
    >     }, {
    >       "color": "#84b761",
    >       "endValue": 232,
    >       "innerRadius": "95%",
    >       "startValue": 202
    >     }, {
    >       "color": "#fdd400",
    >       "endValue": 232,
    >       "startValue": 234
    >     }, {
    >       "color": "#cc4748",
    >       "endValue": 260,
    >       "startValue": 234
    >     }],
    >     "bottomText": "0 km/h",
    >     "bottomTextYOffset": 0,
    >     "startValue":180,
    >     "endValue": 260
    >   } ],
    >   "arrows": [ {} ],
    >   "export": {
    >     "enabled": true
    >   }
    > } )
    
      <ma-gauge-chart id="44cf2d0c-c777-41e0-b20d-ea11a3f9f0cb" style="position: absolute; width: 200px; height: 200px; left: 145px; top: 8px;" point-xid="DP_866585" start="180" end="260" 
      options="{
    	axes: [ {
        axisThickness: 1,
        axisAlpha: 0.2,
        tickAlpha: 0.2,
        valueInterval: 5,
        bands: [ {
          color: '#cc4748',
          endValue: 191,
          startValue: 180
        }, {
          color: '#fdd400',
          endValue: 202,
          startValue: 191
        }, {
          color: '#84b761',
          endValue: 232,
          innerRadius: '95%',
          startValue: 202
        }, {
          color: '#fdd400',
          endValue: 232,
          startValue: 234
        }, {
          color: '#cc4748',
          endValue: 260,
          startValue: 234
        }],
        bottomText: '[[value]] km/h',
        bottomTextYOffset: 0,
        startValue:180,
        endValue: 260
      } ]
    }
    "></ma-gauge-chart>
    

    Funnily enough, it's not working for me either,,, (gauge shows, but no colours. I changed the datapoint from one of mine back to leoboeng's after testing)
    NBB: tested in 3.3.0 also, doesn't work with the ma-gauge-chart in that version either. Sorry Jared, think the ball's in your court with this one.

    posted in Dashboard Designer & Custom AngularJS Pages read more