cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Did you get an answer that solved your problem? Please mark it as an Accepted Solution so others with the same problem can find the answer easily. X

Customizing Progress Gauge

kahmeng96
12-Amethyst

Customizing Progress Gauge

I am using the progress gauge extension on Thingworx and right now it can only take in one value. I have studied the javascript code of the progress gauge and I have roughly understood it. However, I am still unsure on how to start in terms of writing code in progressgauge.ide.js and progressgauge.runtime.js so that the gauge can take in multiple values and show multiple colors based on those values. I have attached the javascript codes for reference as well. Any help will be greatly appreciated! An example of what I want at the end is shown below.

TW.IDE.Widgets.progressgauge = function () {
    this.widgetIconUrl = function() {
        return  "../Common/extensions/ProgressGauge_ExtensionPackage/ui/progressgauge/progressgauge.ide.png";
    };
    this.widgetProperties = function () {
        return {
            'name': 'Progress Gauge',
            'description': 'A rotary progress gauge',
            'category': ['Data', 'Charts'],
            'iconImage': 'progressgauge.ide.png',
            'defaultBindingTargetProperty': 'Data',
            'properties': {
                'Data': {
                    'description': 'Data source',
                    'isBindingTarget': true,
                    'baseType': 'NUMBER',
                    'warnIfNotBoundAsTarget': true
                },
                'MinValue': {
                    'description': 'Minimum value for the gauge',
                    'isBindingTarget': true,
                    'baseType': 'NUMBER',
                    'defaultValue': 0
                },
                'MaxValue': {
                    'description': 'Maximum value for the gauge',
                    'isBindingTarget': true,
                    'baseType': 'NUMBER',
                    'defaultValue': 100
                },
                'ProgressFormatter': {
                    'description': 'Styling rules for the progress display',
                    'baseType': 'STATEFORMATTING',
                    'baseTypeInfotableProperty': 'Data'
                },
                'ValueFormatter': {
                    'description': 'Styling rules for the value display',
                    'baseType': 'STATEFORMATTING',
                    'baseTypeInfotableProperty': 'Data'
                },
                'GaugeStyle': {
                    'description': 'Style for gauge background',
                    'baseType': 'STYLEDEFINITION',
                    'defaultValue': 'DefaultProgressGaugeStyle'
                },
                'GaugeFaceStyle': {
                    'description': 'Style for gauge face',
                    'baseType': 'STYLEDEFINITION',
                    'defaultValue': 'DefaultProgressGaugeFaceStyle'
                },
                'ProgressStyle': {
                    'description': 'Style for progress bar',
                    'baseType': 'STYLEDEFINITION',
                    'defaultValue': 'DefaultProgressGaugeIndicatorStyle'
                },
                'ValueStyle': {
                    'description': 'Style for value display',
                    'baseType': 'STYLEDEFINITION',
                    'defaultValue': 'DefaultProgressGaugeIndicatorStyle'
                },
                'ValueDigits': {
                    'description': 'Number of digits for value display',
                    'baseType': 'NUMBER',
                    'defaultValue': 3
                },
                'ValueDecimals': {
                    'description': 'Number of decimals for value display',
                    'baseType': 'NUMBER',
                    'defaultValue': 0
                },
                'ReferenceAngle': {
                    'description': 'Angle that controls the gauge orientation (degrees)',
                    'baseType': 'NUMBER',
                    'defaultValue': 0
                },
                'Aperture': {
                    'description': 'Angle that controls the gauge size (degrees)',
                    'baseType': 'NUMBER',
                    'defaultValue': 360
                },
                'GaugeBorder': {
                    'description': 'Width of the outside gauge border (pixels)',
                    'baseType': 'NUMBER',
                    'defaultValue': 20
                },
                'RingWidth': {
                    'description': 'Width/thickness of the progress indicator ring (pixels)',
                    'baseType': 'NUMBER',
                    'defaultValue': 10
                },
                'Width': {
                    'description': 'Widget width',
                    'defaultValue': 200
                },
                'Height': {
                    'description': 'Widget height',
                    'defaultValue': 200
                }
            }
        };
    };
    this.renderHtml = function () {
        var html = '';
        html += '<div class="widget-content widget-progressgauge"><table height="100%" width="100%"><tr><td valign="middle" align="center"><span>Progress Gauge</span></td></tr></table></div>';
        return html;
    };
	this.afterRender = function() {
		var domElementId = this.jqElementId;
		var widgetElement = this.jqElement;
		var formatResult = TW.getStyleFromStyleDefinition(this.getProperty('GaugeStyle'));
		var cssGaugeBorder = TW.getStyleCssBorderFromStyle(formatResult);
		var resource = TW.IDE.getMashupResource();
		var widgetStyles = '#' + domElementId + ' table {'+ cssGaugeBorder +'}';
		resource.styles.append(widgetStyles);
	}
    this.afterAddBindingSource = function (bindingInfo) {
        if (bindingInfo['targetProperty'] === 'Data') {
            this.resetPropertyToDefaultValue('ValueFormatter');
        }
    };
    this.beforeSetProperty = function (name, value) {
        if (name === 'MinValue') {
            if (value >= this.getProperty('MaxValue')) {
                return 'MinValue must be less than MaxValue';
            }
        }
        if (name === 'Aperture') {
            if (value < 45 || value > 360) {
                return 'Aperture must be between 45 and 360';
            }
        }
        if (name === 'ReferenceAngle') {
            if (value < 0 || value > 360) {
                return 'Reference Angle must be between 0 and 360';
            }
        }
        if (name === 'MaxValue') {
            if (value <= this.getProperty('MinValue')) {
                return 'MinValue must be less than MaxValue';
            }
        }
    };

};

Image result for progress gauge multiple values

PS: I will post the runtime code once someone replies as this message is too long.

 

2 REPLIES 2

Attached is the code for the runtime as the previous post was too long.

TW.Runtime.Widgets.progressgauge = function () {
	
	var gaugeElementId;
	var borderWidth = 0;
	
    this.runtimeProperties = function () {
        return {
            'needsError': true
        };
    };

    this.renderHtml = function () {
    	this.haveData = false;
    	
        var html = '<div class="widget-content widget-progressgauge"></div>';
        return html;
    };

    this.beforeDestroy = function () {
    	this.cleanupGauge();
    	
        if(this.paper !== undefined) {
            try {
            	this.paper.clear();
            	this.paper.remove();
            	
    			try {
    				TW.purgeJqElement(this,false);
    			}
    			catch(err) {
    				TW.log.error('purge error: ' + err);
    			}

            	this.paper = null;
            	delete this.paper;
            }
            catch (destroyErr) {
            }
        }

    };


    this.afterRender = function () {

		var domElementId = this.jqElementId;
		var widgetElement = this.jqElement;
		gaugeElementId = domElementId + '-widget-progressgauge-container';
		widgetElement.append('<div id="'+ gaugeElementId +'"></div>');

		var formatResult = TW.getStyleFromStyleDefinition(this.getProperty('GaugeStyle'));
		var cssGaugeBorder = TW.getStyleCssBorderFromStyle(formatResult);

		var styleBlock = 
			'<style>' +
				'#' + gaugeElementId + ' {'+ cssGaugeBorder +'}' +				
			'</style>';

		$(styleBlock).prependTo(widgetElement);

		if(formatResult.lineThickness !== undefined && formatResult.lineThickness !== '') {
			borderWidth = parseInt(formatResult.lineThickness);
		} else {
			borderWidth = 0;
		}

	
    	this.drawGauge();
    };

    this.cleanupGauge = function() {
    	if(this.chartBackgroundRectangle !== undefined && this.chartBackgroundRectangle !== null) {
    		this.chartBackgroundRectangle.remove();
    		this.chartBackgroundRectangle = null;
    		delete this.chartBackgroundRectangle;
    	}

    	if(this.gaugeCircle !== undefined && this.gaugeCircle !== null) {
    		this.gaugeCircle.remove();
    		this.gaugeCircle = null;
    		delete this.gaugeCircle;
    	}

    	if(this.gaugeFaceCircle !== undefined && this.gaugeFaceCircle !== null) {
    		this.gaugeFaceCircle.remove();
    		this.gaugeFaceCircle = null;
    		delete this.gaugeFaceCircle;
    	}

    	if(this.valueText !== undefined && this.valueText !== null) {
    		this.valueText.remove();
    		this.valueText = null;
    		delete this.valueText;
    	}

    	if(this.valueTextBackground !== undefined && this.valueTextBackground !== null) {
    		this.valueTextBackground.remove();
    		this.valueTextBackground = null;
    		delete this.valueTextBackground;
    	}

    	this.cleanupMask();
    };
    
    this.cleanupMask = function() {
    	if(this.maskElement !== undefined && this.maskElement !== null) {
    		this.maskElement.remove();
    		this.maskElement = null;
    		delete this.maskElement;
    	}
    	
    };
    
    this.updateGauge = function(value,data) {
    	this.cleanupMask();
    	
    	if(value == undefined) {
    		if(this.valueText !== undefined)
    			this.valueText.hide();

    		return;
    	}
    	
		if(this.valueText !== undefined) {
			this.valueText.hide();
	    	
			var formattedValue = value.format(this.valueformatString);
			
			this.valueText.attr('text',formattedValue);
	        this.valueText.show();
    	}
    
    	var widgetProperties = this.properties;
    	
    	var hasTextFormatting = widgetProperties['ValueFormatter'] !== undefined;

        if (hasTextFormatting) {
        	var valueStyle;
        	
        	if(widgetProperties['ValueFormatter'] !== undefined)  {
        		valueStyle = TW.getStyleFromStateFormatting({ DataRow: data, StateFormatting: widgetProperties['ValueFormatter'] });
        		
	            if (valueStyle.styleDefinitionName !== undefined) {
	            	
	        		if(this.valueText !== undefined) {
	        			this.valueText.attr('fill',valueStyle.foregroundColor);
	        		}
	            }
        	}
        	
        }

        var minRange = widgetProperties["MinValue"];
        if(minRange == undefined)
        	minRange = 0;
        
        var maxRange = widgetProperties["MaxValue"];
        if(maxRange == undefined)
        	maxRange = 100;

        var aperture = widgetProperties['Aperture'];
        if(aperture == undefined)
        	aperture = 270;
        
        var referenceAngle = widgetProperties['ReferenceAngle'];
        if(referenceAngle == undefined)
        	referenceAngle = 225;
        
        var rotationAngle = referenceAngle + aperture * (value - minRange) / (maxRange - minRange);

        if(value != undefined) {
        	// Draw ring
            
            if(this.ringWidth > 0) {
                var r2 = (this.faceDiameter / 2.0);
                var r1 = r2 - this.ringWidth;

                var previousValue = minRange;
                
                // Don't draw zero degree wedges
                
                if(value !== previousValue) {
                    var endAngle = -referenceAngle - aperture * (minRange- minRange) / (maxRange - minRange) + 90;
                    var startAngle = -referenceAngle - aperture * (value - minRange) / (maxRange - minRange) + 90;

                    var progressBackground = "#ffffff";
                    
                    var progressStyleDefinition = TW.getStyleFromStyleDefinition(widgetProperties['ProgressStyle']);

                    if (progressStyleDefinition !== undefined && progressStyleDefinition.styleDefinitionName !== undefined) {
                        progressBackground = progressStyleDefinition.backgroundColor;
                    }

                	var hasProgressFormatting = widgetProperties['ProgressFormatter'] !== undefined;

                    if (hasProgressFormatting) {
                    	if(widgetProperties['ProgressFormatter'] !== undefined)  {
                    		var progressStyle = TW.getStyleFromStateFormatting({ DataRow: data, StateFormatting: widgetProperties['ProgressFormatter'] });
                    		
                            if (progressStyle.styleDefinitionName !== undefined) {
                                progressBackground = progressStyle.backgroundColor;
                            }
                    	}
                    	
                    }

                    if(value <= maxRange) {
                    	this.maskElement = TW.ChartLibrary.drawSector(this.paper, this.centerX, this.centerY, r1, r2, startAngle, endAngle);
                        this.setShapeStyle(this.maskElement, progressBackground, progressBackground, 'none', 'none', undefined, 1);
                    }
                    else {
                    	var middleRadius = (r1 + r2) / 2;
                    	this.maskElement = TW.ChartLibrary.drawCircle(this.paper, this.centerX, this.centerY, middleRadius, middleRadius, this.ringWidth, progressBackground); 
                    }
    	        }
            }
        };
        
        this.previousRotationAngle = rotationAngle;
    };
    
    this.setShapeStyle = function(element,fill,secondaryFill,fillType,fillOrientation,stroke,strokeWidth) {
		TW.ChartLibrary.setElementStyle(element, fill, secondaryFill, fillType, fillOrientation, stroke, strokeWidth, TW.ChartLibrary.STROKE_SOLID);
    };

    this.drawGauge = function() {

        var widgetProperties = this.properties;

        var width = widgetProperties['Width'] - (borderWidth * 2);
        var height = widgetProperties['Height'] - (borderWidth * 2);
        
        if(widgetProperties['GaugeStyle'] === undefined) {
        	widgetProperties['GaugeStyle'] = 'DefaultProgressGaugeStyle';
        }
        
        if(widgetProperties['GaugeFaceStyle'] === undefined) {
        	widgetProperties['GaugeFaceStyle'] = 'DefaultProgressGaugeFaceStyle';
        }
        
        if(widgetProperties['ValueStyle'] === undefined) {
        	widgetProperties['ValueStyle'] = 'DefaultProgressGaugeIndicatorStyle';
        }
        
        if(widgetProperties['ProgressStyle'] === undefined) {
        	widgetProperties['ProgressStyle'] = 'DefaultProgressGaugeIndicatorStyle';
        }
        
        var chartStyleDefinition = TW.getStyleFromStyleDefinition(widgetProperties['GaugeStyle']);

        var chartBackground = "#ffffff";
        var chartSecondaryBackground = undefined;
        var chartBorder = undefined;
        var chartBorderWidth = 0;
        
        if (chartStyleDefinition !== undefined) {
            chartBackground = chartStyleDefinition.backgroundColor;

            if (chartStyleDefinition.secondaryBackgroundColor !== undefined && chartStyleDefinition.secondaryBackgroundColor != chartStyleDefinition.backgroundColor && chartStyleDefinition.secondaryBackgroundColor !== '')
                chartSecondaryBackground = chartStyleDefinition.secondaryBackgroundColor;
        }

        var gaugeFaceBackground = "#ffffff";
        var gaugeFaceSecondaryBackground = undefined;
        var gaugeFaceBorder = "#000000";
        var gaugeFaceBorderWidth = 1;
        
        var gaugeFaceStyleDefinition = TW.getStyleFromStyleDefinition(widgetProperties['GaugeFaceStyle']);

        if (gaugeFaceStyleDefinition !== undefined && gaugeFaceStyleDefinition.styleDefinitionName !== undefined) {
            gaugeFaceBackground = gaugeFaceStyleDefinition.backgroundColor;

            if (gaugeFaceStyleDefinition.secondaryBackgroundColor !== undefined && gaugeFaceStyleDefinition.secondaryBackgroundColor != gaugeFaceStyleDefinition.backgroundColor && gaugeFaceStyleDefinition.secondaryBackgroundColor !== '')
                gaugeFaceSecondaryBackground = gaugeFaceStyleDefinition.secondaryBackgroundColor;

            gaugeFaceBorder = gaugeFaceStyleDefinition.lineColor;
            gaugeFaceBorderWidth = parseInt(gaugeFaceStyleDefinition.lineThickness);
        }

    	var absolutePadding = 6;

        var gaugeBorderSize = widgetProperties['GaugeBorder'];

        if(gaugeBorderSize == undefined)
        	gaugeBorderSize = 16;
        
        var effectiveHeight = height - 2 * absolutePadding;
        var effectiveWidth = width - 2 * absolutePadding;
        
        var gaugeDiameter = effectiveWidth;

        if (effectiveHeight < effectiveWidth)
            gaugeDiameter = effectiveHeight;

        this.ringWidth = widgetProperties['RingWidth'];

        if(this.ringWidth == undefined)
        	this.ringWidth = 16;
        
        this.faceDiameter = gaugeDiameter - gaugeBorderSize;

    	var paperWidth = width;
    	var paperHeight = height;
    	
		var centerX = width/2;
		var centerY = height/2;

		this.centerX = centerX;
		this.centerY = centerY;
		
		if(this.paper === undefined) {
			this.paper = Raphael(gaugeElementId, paperWidth, paperHeight);
		}
		else {
			this.cleanupGauge();
		}
		
		this.chartBackgroundRectangle = this.paper.rect(0, 0, width, height);
		this.setShapeStyle(this.chartBackgroundRectangle, chartBackground, chartSecondaryBackground, TW.ChartLibrary.FILL_LINEAR, TW.ChartLibrary.ORIENTATION_VERTICAL, chartBorder, chartBorderWidth);
		
		this.gaugeFaceCircle = this.paper.circle(centerX, centerY, (gaugeDiameter / 2.0));
		this.setShapeStyle(this.gaugeFaceCircle, gaugeFaceBackground, gaugeFaceSecondaryBackground, TW.ChartLibrary.FILL_LINEAR, TW.ChartLibrary.ORIENTATION_VERTICAL, gaugeFaceBorder, gaugeFaceBorderWidth);
		
        var minRange = this.getProperty("MinValue");
        if(minRange == undefined)
        	minRange = 0;
        
        var maxRange = this.getProperty("MaxValue");
        if(maxRange == undefined)
        	maxRange = 100;

        var aperture = widgetProperties['Aperture'];
        if(aperture == undefined)
        	aperture = 360;
        
        var referenceAngle = widgetProperties['ReferenceAngle'];
        if(referenceAngle == undefined)
        	referenceAngle = 0;
        
        var valuedecimals = widgetProperties['ValueDecimals'];

        if (valuedecimals == undefined) {
            valuedecimals = widgetProperties['Decimals'];

            if (valuedecimals == undefined)
            	valuedecimals = 0;
        }

        var valuedigits = widgetProperties['ValueDigits'];

        if (valuedigits == undefined)
        	valuedigits = 3;

        var valueformatString = "0";
        
        if(valuedecimals > 0)
        	valueformatString = valueformatString + ".";
        
        for(var i=0;i<valuedecimals;i++) {
       		valueformatString = valueformatString + "0";
        }

        this.valueformatString = valueformatString;
        
        var valueFontColor = "#000080";
        var valueFontBold = false;
        var valueFontSizeName = "normal";
        
        var valueStyleDefinition = TW.getStyleFromStyleDefinition(widgetProperties['ValueStyle']);


        if (valueStyleDefinition !== undefined && valueStyleDefinition.styleDefinitionName !== undefined) {
            valueFontColor = valueStyleDefinition.foregroundColor;
            valueFontBold = valueStyleDefinition.fontEmphasisBold;
            valueFontSizeName = valueStyleDefinition.textSize;
        }

    	var valueFontSize = TW.ChartLibrary.getFontSize(valueFontSizeName);
    	
        var xpos = centerX;
        var ypos = centerY;
            
        var value = 0.0;
        var valueText = value.format(valueformatString);
        
        this.valueText = this.paper.text(xpos,ypos,valueText).attr({ "font-size": valueFontSize, "font-family": "Segoe UI, Arial, Sans Serif", "fill" : valueFontColor, "font-weight" : valueFontBold ? "bold" : "normal"  });
        this.valueText.hide();
    };
    
    this.updateProperty = function (updatePropertyInfo) {
        if (updatePropertyInfo.TargetProperty === "ValueFormatter") {
        	this.drawGauge();
        	
        	if(this.lastValue !== undefined) {
        		this.updateGauge(this.lastValue,this.lastDataRow);
        	}
        }
        
        if (updatePropertyInfo.TargetProperty === "MinValue" || updatePropertyInfo.TargetProperty === "MaxValue" || updatePropertyInfo.TargetProperty === "ReferenceAngle" || updatePropertyInfo.TargetProperty === "Aperture") {
        	this.setProperty(updatePropertyInfo.TargetProperty,updatePropertyInfo.RawSinglePropertyValue);
        	this.drawGauge();
        	
        	if(this.lastValue !== undefined) {
        		this.updateGauge(this.lastValue,this.lastDataRow);
        	}
        	
            return;
        }

        if (updatePropertyInfo.TargetProperty === "Data") {
        	var value = updatePropertyInfo.RawSinglePropertyValue;
        	var datarow = updatePropertyInfo.ActualDataRows[0];
        	
        	this.lastValue = value;
        	this.lastDataRow = datarow;
        	
        	this.updateGauge(value,datarow);
        }
    };

};

TW.Runtime.Widgets.progressgauge = function () {
	
	var gaugeElementId;
	var borderWidth = 0;
	
    this.runtimeProperties = function () {
        return {
            'needsError': true
        };
    };

    this.renderHtml = function () {
    	this.haveData = false;
    	
        var html = '<div class="widget-content widget-progressgauge"></div>';
        return html;
    };

    this.beforeDestroy = function () {
    	this.cleanupGauge();
    	
        if(this.paper !== undefined) {
            try {
            	this.paper.clear();
            	this.paper.remove();
            	
    			try {
    				TW.purgeJqElement(this,false);
    			}
    			catch(err) {
    				TW.log.error('purge error: ' + err);
    			}

            	this.paper = null;
            	delete this.paper;
            }
            catch (destroyErr) {
            }
        }

    };


    this.afterRender = function () {

		var domElementId = this.jqElementId;
		var widgetElement = this.jqElement;
		gaugeElementId = domElementId + '-widget-progressgauge-container';
		widgetElement.append('<div id="'+ gaugeElementId +'"></div>');

		var formatResult = TW.getStyleFromStyleDefinition(this.getProperty('GaugeStyle'));
		var cssGaugeBorder = TW.getStyleCssBorderFromStyle(formatResult);

		var styleBlock = 
			'<style>' +
				'#' + gaugeElementId + ' {'+ cssGaugeBorder +'}' +				
			'</style>';

		$(styleBlock).prependTo(widgetElement);

		if(formatResult.lineThickness !== undefined && formatResult.lineThickness !== '') {
			borderWidth = parseInt(formatResult.lineThickness);
		} else {
			borderWidth = 0;
		}

	
    	this.drawGauge();
    };

    this.cleanupGauge = function() {
    	if(this.chartBackgroundRectangle !== undefined && this.chartBackgroundRectangle !== null) {
    		this.chartBackgroundRectangle.remove();
    		this.chartBackgroundRectangle = null;
    		delete this.chartBackgroundRectangle;
    	}

    	if(this.gaugeCircle !== undefined && this.gaugeCircle !== null) {
    		this.gaugeCircle.remove();
    		this.gaugeCircle = null;
    		delete this.gaugeCircle;
    	}

    	if(this.gaugeFaceCircle !== undefined && this.gaugeFaceCircle !== null) {
    		this.gaugeFaceCircle.remove();
    		this.gaugeFaceCircle = null;
    		delete this.gaugeFaceCircle;
    	}

    	if(this.valueText !== undefined && this.valueText !== null) {
    		this.valueText.remove();
    		this.valueText = null;
    		delete this.valueText;
    	}

    	if(this.valueTextBackground !== undefined && this.valueTextBackground !== null) {
    		this.valueTextBackground.remove();
    		this.valueTextBackground = null;
    		delete this.valueTextBackground;
    	}

    	this.cleanupMask();
    };
    
    this.cleanupMask = function() {
    	if(this.maskElement !== undefined && this.maskElement !== null) {
    		this.maskElement.remove();
    		this.maskElement = null;
    		delete this.maskElement;
    	}
    	
    };
    
    this.updateGauge = function(value,data) {
    	this.cleanupMask();
    	
    	if(value == undefined) {
    		if(this.valueText !== undefined)
    			this.valueText.hide();

    		return;
    	}
    	
		if(this.valueText !== undefined) {
			this.valueText.hide();
	    	
			var formattedValue = value.format(this.valueformatString);
			
			this.valueText.attr('text',formattedValue);
	        this.valueText.show();
    	}
    
    	var widgetProperties = this.properties;
    	
    	var hasTextFormatting = widgetProperties['ValueFormatter'] !== undefined;

        if (hasTextFormatting) {
        	var valueStyle;
        	
        	if(widgetProperties['ValueFormatter'] !== undefined)  {
        		valueStyle = TW.getStyleFromStateFormatting({ DataRow: data, StateFormatting: widgetProperties['ValueFormatter'] });
        		
	            if (valueStyle.styleDefinitionName !== undefined) {
	            	
	        		if(this.valueText !== undefined) {
	        			this.valueText.attr('fill',valueStyle.foregroundColor);
	        		}
	            }
        	}
        	
        }

        var minRange = widgetProperties["MinValue"];
        if(minRange == undefined)
        	minRange = 0;
        
        var maxRange = widgetProperties["MaxValue"];
        if(maxRange == undefined)
        	maxRange = 100;

        var aperture = widgetProperties['Aperture'];
        if(aperture == undefined)
        	aperture = 270;
        
        var referenceAngle = widgetProperties['ReferenceAngle'];
        if(referenceAngle == undefined)
        	referenceAngle = 225;
        
        var rotationAngle = referenceAngle + aperture * (value - minRange) / (maxRange - minRange);

        if(value != undefined) {
        	// Draw ring
            
            if(this.ringWidth > 0) {
                var r2 = (this.faceDiameter / 2.0);
                var r1 = r2 - this.ringWidth;

                var previousValue = minRange;
                
                // Don't draw zero degree wedges
                
                if(value !== previousValue) {
                    var endAngle = -referenceAngle - aperture * (minRange- minRange) / (maxRange - minRange) + 90;
                    var startAngle = -referenceAngle - aperture * (value - minRange) / (maxRange - minRange) + 90;

                    var progressBackground = "#ffffff";
                    
                    var progressStyleDefinition = TW.getStyleFromStyleDefinition(widgetProperties['ProgressStyle']);

                    if (progressStyleDefinition !== undefined && progressStyleDefinition.styleDefinitionName !== undefined) {
                        progressBackground = progressStyleDefinition.backgroundColor;
                    }

                	var hasProgressFormatting = widgetProperties['ProgressFormatter'] !== undefined;

                    if (hasProgressFormatting) {
                    	if(widgetProperties['ProgressFormatter'] !== undefined)  {
                    		var progressStyle = TW.getStyleFromStateFormatting({ DataRow: data, StateFormatting: widgetProperties['ProgressFormatter'] });
                    		
                            if (progressStyle.styleDefinitionName !== undefined) {
                                progressBackground = progressStyle.backgroundColor;
                            }
                    	}
                    	
                    }

                    if(value <= maxRange) {
                    	this.maskElement = TW.ChartLibrary.drawSector(this.paper, this.centerX, this.centerY, r1, r2, startAngle, endAngle);
                        this.setShapeStyle(this.maskElement, progressBackground, progressBackground, 'none', 'none', undefined, 1);
                    }
                    else {
                    	var middleRadius = (r1 + r2) / 2;
                    	this.maskElement = TW.ChartLibrary.drawCircle(this.paper, this.centerX, this.centerY, middleRadius, middleRadius, this.ringWidth, progressBackground); 
                    }
    	        }
            }
        };
        
        this.previousRotationAngle = rotationAngle;
    };
    
    this.setShapeStyle = function(element,fill,secondaryFill,fillType,fillOrientation,stroke,strokeWidth) {
		TW.ChartLibrary.setElementStyle(element, fill, secondaryFill, fillType, fillOrientation, stroke, strokeWidth, TW.ChartLibrary.STROKE_SOLID);
    };

    this.drawGauge = function() {

        var widgetProperties = this.properties;

        var width = widgetProperties['Width'] - (borderWidth * 2);
        var height = widgetProperties['Height'] - (borderWidth * 2);
        
        if(widgetProperties['GaugeStyle'] === undefined) {
        	widgetProperties['GaugeStyle'] = 'DefaultProgressGaugeStyle';
        }
        
        if(widgetProperties['GaugeFaceStyle'] === undefined) {
        	widgetProperties['GaugeFaceStyle'] = 'DefaultProgressGaugeFaceStyle';
        }
        
        if(widgetProperties['ValueStyle'] === undefined) {
        	widgetProperties['ValueStyle'] = 'DefaultProgressGaugeIndicatorStyle';
        }
        
        if(widgetProperties['ProgressStyle'] === undefined) {
        	widgetProperties['ProgressStyle'] = 'DefaultProgressGaugeIndicatorStyle';
        }
        
        var chartStyleDefinition = TW.getStyleFromStyleDefinition(widgetProperties['GaugeStyle']);

        var chartBackground = "#ffffff";
        var chartSecondaryBackground = undefined;
        var chartBorder = undefined;
        var chartBorderWidth = 0;
        
        if (chartStyleDefinition !== undefined) {
            chartBackground = chartStyleDefinition.backgroundColor;

            if (chartStyleDefinition.secondaryBackgroundColor !== undefined && chartStyleDefinition.secondaryBackgroundColor != chartStyleDefinition.backgroundColor && chartStyleDefinition.secondaryBackgroundColor !== '')
                chartSecondaryBackground = chartStyleDefinition.secondaryBackgroundColor;
        }

        var gaugeFaceBackground = "#ffffff";
        var gaugeFaceSecondaryBackground = undefined;
        var gaugeFaceBorder = "#000000";
        var gaugeFaceBorderWidth = 1;
        
        var gaugeFaceStyleDefinition = TW.getStyleFromStyleDefinition(widgetProperties['GaugeFaceStyle']);

        if (gaugeFaceStyleDefinition !== undefined && gaugeFaceStyleDefinition.styleDefinitionName !== undefined) {
            gaugeFaceBackground = gaugeFaceStyleDefinition.backgroundColor;

            if (gaugeFaceStyleDefinition.secondaryBackgroundColor !== undefined && gaugeFaceStyleDefinition.secondaryBackgroundColor != gaugeFaceStyleDefinition.backgroundColor && gaugeFaceStyleDefinition.secondaryBackgroundColor !== '')
                gaugeFaceSecondaryBackground = gaugeFaceStyleDefinition.secondaryBackgroundColor;

            gaugeFaceBorder = gaugeFaceStyleDefinition.lineColor;
            gaugeFaceBorderWidth = parseInt(gaugeFaceStyleDefinition.lineThickness);
        }

    	var absolutePadding = 6;

        var gaugeBorderSize = widgetProperties['GaugeBorder'];

        if(gaugeBorderSize == undefined)
        	gaugeBorderSize = 16;
        
        var effectiveHeight = height - 2 * absolutePadding;
        var effectiveWidth = width - 2 * absolutePadding;
        
        var gaugeDiameter = effectiveWidth;

        if (effectiveHeight < effectiveWidth)
            gaugeDiameter = effectiveHeight;

        this.ringWidth = widgetProperties['RingWidth'];

        if(this.ringWidth == undefined)
        	this.ringWidth = 16;
        
        this.faceDiameter = gaugeDiameter - gaugeBorderSize;

    	var paperWidth = width;
    	var paperHeight = height;
    	
		var centerX = width/2;
		var centerY = height/2;

		this.centerX = centerX;
		this.centerY = centerY;
		
		if(this.paper === undefined) {
			this.paper = Raphael(gaugeElementId, paperWidth, paperHeight);
		}
		else {
			this.cleanupGauge();
		}
		
		this.chartBackgroundRectangle = this.paper.rect(0, 0, width, height);
		this.setShapeStyle(this.chartBackgroundRectangle, chartBackground, chartSecondaryBackground, TW.ChartLibrary.FILL_LINEAR, TW.ChartLibrary.ORIENTATION_VERTICAL, chartBorder, chartBorderWidth);
		
		this.gaugeFaceCircle = this.paper.circle(centerX, centerY, (gaugeDiameter / 2.0));
		this.setShapeStyle(this.gaugeFaceCircle, gaugeFaceBackground, gaugeFaceSecondaryBackground, TW.ChartLibrary.FILL_LINEAR, TW.ChartLibrary.ORIENTATION_VERTICAL, gaugeFaceBorder, gaugeFaceBorderWidth);
		
        var minRange = this.getProperty("MinValue");
        if(minRange == undefined)
        	minRange = 0;
        
        var maxRange = this.getProperty("MaxValue");
        if(maxRange == undefined)
        	maxRange = 100;

        var aperture = widgetProperties['Aperture'];
        if(aperture == undefined)
        	aperture = 360;
        
        var referenceAngle = widgetProperties['ReferenceAngle'];
        if(referenceAngle == undefined)
        	referenceAngle = 0;
        
        var valuedecimals = widgetProperties['ValueDecimals'];

        if (valuedecimals == undefined) {
            valuedecimals = widgetProperties['Decimals'];

            if (valuedecimals == undefined)
            	valuedecimals = 0;
        }

        var valuedigits = widgetProperties['ValueDigits'];

        if (valuedigits == undefined)
        	valuedigits = 3;

        var valueformatString = "0";
        
        if(valuedecimals > 0)
        	valueformatString = valueformatString + ".";
        
        for(var i=0;i<valuedecimals;i++) {
       		valueformatString = valueformatString + "0";
        }

        this.valueformatString = valueformatString;
        
        var valueFontColor = "#000080";
        var valueFontBold = false;
        var valueFontSizeName = "normal";
        
        var valueStyleDefinition = TW.getStyleFromStyleDefinition(widgetProperties['ValueStyle']);


        if (valueStyleDefinition !== undefined && valueStyleDefinition.styleDefinitionName !== undefined) {
            valueFontColor = valueStyleDefinition.foregroundColor;
            valueFontBold = valueStyleDefinition.fontEmphasisBold;
            valueFontSizeName = valueStyleDefinition.textSize;
        }

    	var valueFontSize = TW.ChartLibrary.getFontSize(valueFontSizeName);
    	
        var xpos = centerX;
        var ypos = centerY;
            
        var value = 0.0;
        var valueText = value.format(valueformatString);
        
        this.valueText = this.paper.text(xpos,ypos,valueText).attr({ "font-size": valueFontSize, "font-family": "Segoe UI, Arial, Sans Serif", "fill" : valueFontColor, "font-weight" : valueFontBold ? "bold" : "normal"  });
        this.valueText.hide();
    };
    
    this.updateProperty = function (updatePropertyInfo) {
        if (updatePropertyInfo.TargetProperty === "ValueFormatter") {
        	this.drawGauge();
        	
        	if(this.lastValue !== undefined) {
        		this.updateGauge(this.lastValue,this.lastDataRow);
        	}
        }
        
        if (updatePropertyInfo.TargetProperty === "MinValue" || updatePropertyInfo.TargetProperty === "MaxValue" || updatePropertyInfo.TargetProperty === "ReferenceAngle" || updatePropertyInfo.TargetProperty === "Aperture") {
        	this.setProperty(updatePropertyInfo.TargetProperty,updatePropertyInfo.RawSinglePropertyValue);
        	this.drawGauge();
        	
        	if(this.lastValue !== undefined) {
        		this.updateGauge(this.lastValue,this.lastDataRow);
        	}
        	
            return;
        }

        if (updatePropertyInfo.TargetProperty === "Data") {
        	var value = updatePropertyInfo.RawSinglePropertyValue;
        	var datarow = updatePropertyInfo.ActualDataRows[0];
        	
        	this.lastValue = value;
        	this.lastDataRow = datarow;
        	
        	this.updateGauge(value,datarow);
        }
    };

};

Top Tags