From 5d7e45ae7ffb2fac416114059d6b5ce2c5b1e19f Mon Sep 17 00:00:00 2001 From: Frank Thelen Date: Sun, 5 Apr 2015 16:51:27 +0200 Subject: [PATCH] preject restructured / bower support --- .gitignore | 7 + README.md | 39 +- .../src/bower.json => bower.json | 20 +- demo/index.html | 57 +++ ngRadialGauge/ngRadialGauge/src/index.html | 16 - .../controllers/ng-radial-gauge-ctrl.js | 34 -- .../scripts/directives/ng-radial-gauge-dir.js | 336 ------------------ ...dialGaugeDemo.png => ngRadialGaugeDemo.png | Bin .../src/scripts/services => src}/d3-serv.js | 4 +- src/ng-radial-gauge-dir.js | 335 +++++++++++++++++ 10 files changed, 438 insertions(+), 410 deletions(-) create mode 100644 .gitignore rename ngRadialGauge/ngRadialGauge/src/bower.json => bower.json (51%) create mode 100644 demo/index.html delete mode 100644 ngRadialGauge/ngRadialGauge/src/index.html delete mode 100644 ngRadialGauge/ngRadialGauge/src/scripts/controllers/ng-radial-gauge-ctrl.js delete mode 100644 ngRadialGauge/ngRadialGauge/src/scripts/directives/ng-radial-gauge-dir.js rename ngRadialGauge/ngRadialGaugeDemo.png => ngRadialGaugeDemo.png (100%) rename {ngRadialGauge/ngRadialGauge/src/scripts/services => src}/d3-serv.js (87%) create mode 100644 src/ng-radial-gauge-dir.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b01b42b --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +bower_components +node_modules +dist +.tmp +.sass-cache +.project +.settings diff --git a/README.md b/README.md index d9b762b..880b5c2 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ -ngRadialGauge -============= +# ngRadialGauge -Angular.js Radial Gauge (with bower support) +Angular.js Radial Gauge -![alt tag](https://raw.github.com/stherrienaspnet/ngRadialGauge/master/ngRadialGauge/ngRadialGaugeDemo.png) +![alt tag](https://raw.github.com/stherrienaspnet/ngRadialGauge/master/ngRadialGaugeDemo.png) This radial gauge builded using D3.js JavaScript library is designed for Angular.js framework. @@ -35,19 +34,31 @@ List of directive attributes: **If the value provided by the controller is outside the limits defined, the needle won't be display but the value will be display.** -Html view sample code usage: -``` - -
-
-
- +## Installation + +You can install with Bower: + +`bower install ngRadialGauge` + +## Usage + +You need to include the module in your project: + +```JavaScript +// in your app +angular.module('myApp', ['ngRadialGauge']); ``` -Controller sample code usage: +Then create the content: +```HTML +
+
``` -app.controller('RadialGaugeCtrl', ['$scope', function ($scope) { + +The variables must be provided, e.g., in your controller: +```JavaScript +app.controller('MyCtrl', ['$scope', function ($scope) { $scope.value = 1.5; $scope.upperLimit = 6; $scope.lowerLimit = 0; diff --git a/ngRadialGauge/ngRadialGauge/src/bower.json b/bower.json similarity index 51% rename from ngRadialGauge/ngRadialGauge/src/bower.json rename to bower.json index 134d50d..7985eda 100644 --- a/ngRadialGauge/ngRadialGauge/src/bower.json +++ b/bower.json @@ -1,12 +1,13 @@ { "name": "ngRadialGauge", "version": "1.0.0", - "description": "Angular.js Radial Gauge", - "main": "index.html", + "description": "AngularJS Radial Gauge", + "main": "./src/ng-radial-gauge-dir.js", "keywords": [ - "Angular.Js", + "AngularJS", "Radial", - "Gauge" + "Gauge", + "d3" ], "authors": [ "Stephane Therrien" @@ -14,12 +15,15 @@ "license": "MIT", "homepage": "https://github.com/stherrienaspnet/ngRadialGauge", "ignore": [ - ".jshintrc", - "**/*.txt" + ".jshintrc", + "**/*.txt", + "node_modules", + "bower_components", + "test" ], "dependencies": { - "d3": "~3.4.4", - "angular": "~1.2.28", + "d3": "~3.4.0", + "angular": "~1.3.0", "jquery": "~2.1.0" } } diff --git a/demo/index.html b/demo/index.html new file mode 100644 index 0000000..8f3c79b --- /dev/null +++ b/demo/index.html @@ -0,0 +1,57 @@ + + + + ngRadialGauge Demo + + + + + + + +
+
+
+ + diff --git a/ngRadialGauge/ngRadialGauge/src/index.html b/ngRadialGauge/ngRadialGauge/src/index.html deleted file mode 100644 index 8881b36..0000000 --- a/ngRadialGauge/ngRadialGauge/src/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - ngRadialGauge Demo - - - - - - - -
-
-
- - diff --git a/ngRadialGauge/ngRadialGauge/src/scripts/controllers/ng-radial-gauge-ctrl.js b/ngRadialGauge/ngRadialGauge/src/scripts/controllers/ng-radial-gauge-ctrl.js deleted file mode 100644 index d63dfec..0000000 --- a/ngRadialGauge/ngRadialGauge/src/scripts/controllers/ng-radial-gauge-ctrl.js +++ /dev/null @@ -1,34 +0,0 @@ -app.controller('RadialGaugeCtrl', ['$scope', function ($scope) { - $scope.value = 1.5; - $scope.upperLimit = 6; - $scope.lowerLimit = 0; - $scope.unit = "kW"; - $scope.precision = 2; - $scope.ranges = [ - { - min: 0, - max: 1.5, - color: '#DEDEDE' - }, - { - min: 1.5, - max: 2.5, - color: '#8DCA2F' - }, - { - min: 2.5, - max: 3.5, - color: '#FDC702' - }, - { - min: 3.5, - max: 4.5, - color: '#FF7700' - }, - { - min: 4.5, - max: 6.0, - color: '#C50200' - } - ]; -}]); \ No newline at end of file diff --git a/ngRadialGauge/ngRadialGauge/src/scripts/directives/ng-radial-gauge-dir.js b/ngRadialGauge/ngRadialGauge/src/scripts/directives/ng-radial-gauge-dir.js deleted file mode 100644 index 7dd9d84..0000000 --- a/ngRadialGauge/ngRadialGauge/src/scripts/directives/ng-radial-gauge-dir.js +++ /dev/null @@ -1,336 +0,0 @@ -/* - ng-radial-gauge 1.0 - (c) 2010-2014 Stéphane Therrien, - https://github.com/stherrienaspnet/ngRadialGauge - License: MIT -*/ -app.directive('ngRadialGauge', ['$window', '$timeout', 'd3Service', - function ($window, $timeout, d3Service) { - return { - restrict: 'A', - scope: { - lowerLimit: '=', - upperLimit: '=', - ranges: '=', - value: '=', - valueUnit: '=', - precision: '=', - label: '@', - onClick: '&' - }, - link: function (scope, ele, attrs) { - "use strict"; - d3Service.d3().then(function (d3) { - var initialized = false; - var renderTimeout; - var width = parseInt(attrs.width) || 300; - var innerRadius = Math.round((width * 130) / 300); - var outterRadius = Math.round((width * 145) / 300); - var majorGraduations = parseInt(attrs.majorGraduations - 1) || 5; - var minorGraduations = parseInt(attrs.minorGraduations) || 10; - var majorGraduationLenght = Math.round((width * 16) / 300); - var minorGraduationLenght = Math.round((width * 10) / 300); - var majorGraduationMarginTop = Math.round((width * 7) / 300); - var majorGraduationColor = attrs.majorGraduationColor || "#B0B0B0"; - var minorGraduationColor = attrs.minorGraduationColor || "#D0D0D0"; - var majorGraduationTextColor = attrs.majorGraduationTextColor || "#6C6C6C"; - var needleColor = attrs.needleColor || "#416094"; - var valueVerticalOffset = Math.round((width * 30) / 300); - var unactiveColor = "#D7D7D7"; - var transitionMs = parseInt(attrs.transitionMs) || 750; - var majorGraduationTextSize = parseInt(attrs.majorGraduationTextSize); - var needleValueTextSize = parseInt(attrs.needleValueTextSize); - - var maxLimit = scope.upperLimit ? scope.upperLimit : 100; - var minLimit = scope.lowerLimit ? scope.lowerLimit : 0; - - var needle = undefined; - var scale = d3.scale.linear() - .range([0,1]) - .domain([minLimit, maxLimit]); - - var svg = d3.select(ele[0]) - .append('svg') - .attr('width', width) - .attr('height', width * 0.75); - var renderMajorGraduations = function (majorGraduationsAngles) { - var centerX = width / 2; - var centerY = width / 2; - //Render Major Graduations - $.each(majorGraduationsAngles, function (index, value) { - var cos1Adj = Math.round(Math.cos((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop - majorGraduationLenght)); - var sin1Adj = Math.round(Math.sin((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop - majorGraduationLenght)); - var cos2Adj = Math.round(Math.cos((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop)); - var sin2Adj = Math.round(Math.sin((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop)); - var x1 = centerX + cos1Adj; - var y1 = centerY + sin1Adj * -1; - var x2 = centerX + cos2Adj; - var y2 = centerY + sin2Adj * -1; - svg.append("svg:line") - .attr("x1", x1) - .attr("y1", y1) - .attr("x2", x2) - .attr("y2", y2) - .style("stroke", majorGraduationColor); - - renderMinorGraduations(majorGraduationsAngles, index); - }); - }; - var renderMinorGraduations = function (majorGraduationsAngles, indexMajor) { - var minorGraduationsAngles = []; - - if (indexMajor > 0) { - var minScale = majorGraduationsAngles[indexMajor - 1]; - var maxScale = majorGraduationsAngles[indexMajor]; - var scaleRange = maxScale - minScale; - - for (var i = 1; i < minorGraduations; i++) { - var scaleValue = minScale + i * scaleRange / minorGraduations; - minorGraduationsAngles.push(scaleValue); - } - - var centerX = width / 2; - var centerY = width / 2; - //Render Minor Graduations - $.each(minorGraduationsAngles, function (indexMinor, value) { - var cos1Adj = Math.round(Math.cos((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop - minorGraduationLenght)); - var sin1Adj = Math.round(Math.sin((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop - minorGraduationLenght)); - var cos2Adj = Math.round(Math.cos((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop)); - var sin2Adj = Math.round(Math.sin((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop)); - var x1 = centerX + cos1Adj; - var y1 = centerY + sin1Adj * -1; - var x2 = centerX + cos2Adj; - var y2 = centerY + sin2Adj * -1; - svg.append("svg:line") - .attr("x1", x1) - .attr("y1", y1) - .attr("x2", x2) - .attr("y2", y2) - .style("stroke", minorGraduationColor); - }); - } - }; - var getMajorGraduationValues = function (minLimit, maxLimit) { - var scaleRange = maxLimit - minLimit; - var majorGraduationValues = []; - for (var i = 0; i <= majorGraduations; i++) { - var scaleValue = minLimit + i * scaleRange / (majorGraduations); - majorGraduationValues.push(scaleValue.toFixed(scope.precision)); - } - - return majorGraduationValues; - }; - var getMajorGraduationAngles = function () { - var scaleRange = 240; - var minScale = -120; - var graduationsAngles = []; - for (var i = 0; i <= majorGraduations; i++) { - var scaleValue = minScale + i * scaleRange / (majorGraduations); - graduationsAngles.push(scaleValue); - } - - return graduationsAngles; - }; - var getNewAngle = function(value){ - var ratio = scale(value); - var range = 240; - var minScale = -120; - var newAngle = minScale + (ratio * range); - return newAngle; - }; - var renderMajorGraduationTexts = function (majorGraduationsAngles, majorGraduationValues) { - if (!scope.ranges) return; - - var centerX = width / 2; - var centerY = width / 2; - var textVerticalPadding = 5; - var textHorizontalPadding = 5; - - var lastGraduationValue = majorGraduationValues[majorGraduationValues.length - 1]; - var textSize = isNaN(majorGraduationTextSize) ? (width * 12) / 300 : majorGraduationTextSize; - var fontStyle = textSize + "px Courier"; - - var dummyText = svg.append("text") - .attr("x", centerX) - .attr("y", centerY) - .attr("fill", "transparent") - .attr("text-anchor", "middle") - .style("font", fontStyle) - .text(lastGraduationValue + scope.valueUnit); - - var textWidth = dummyText.node().getBBox().width; - - for (var i = 0; i < majorGraduationsAngles.length; i++) { - var angle = majorGraduationsAngles[i]; - var cos1Adj = Math.round(Math.cos((90 - angle) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop - majorGraduationLenght - textHorizontalPadding)); - var sin1Adj = Math.round(Math.sin((90 - angle) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop - majorGraduationLenght - textVerticalPadding)); - - var sin1Factor = 1; - if (sin1Adj < 0) sin1Factor = 1.1; - if (sin1Adj > 0) sin1Factor = 0.9; - if (cos1Adj > 0) { - if (angle > 0 && angle < 45) { - cos1Adj -= textWidth / 2; - } else { - cos1Adj -= textWidth; - } - } - if (cos1Adj < 0) { - if (angle < 0 && angle > -45) { - cos1Adj -= textWidth / 2; - } - } - if (cos1Adj == 0) { - cos1Adj -= angle == 0 ? textWidth / 4 : textWidth / 2; - } - - var x1 = centerX + cos1Adj; - var y1 = centerY + sin1Adj * sin1Factor * -1; - - svg.append("text") - .attr("class", "mtt-majorGraduationText") - .style("font", fontStyle) - .attr("text-align", "center") - .attr("x", x1) - .attr("dy", y1) - .attr("fill", majorGraduationTextColor) - .text(majorGraduationValues[i] + scope.valueUnit); - } - }; - var renderGraduationNeedle = function (minLimit, maxLimit) { - svg.selectAll('.mtt-graduation-needle').remove(); - svg.selectAll('.mtt-graduationValueText').remove(); - svg.selectAll('.mtt-graduation-needle-center').remove(); - - var centerX = width / 2; - var centerY = width / 2; - var centerColor; - - if (typeof scope.value === 'undefined') { - centerColor = unactiveColor; - } else { - centerColor = needleColor; - var needleAngle = getNewAngle(scope.value); - var needleLen = innerRadius - majorGraduationLenght - majorGraduationMarginTop; - var needleRadius = (width * 2.5) / 300; - var textSize = isNaN(needleValueTextSize) ? (width * 12) / 300 : needleValueTextSize; - var fontStyle = textSize + "px Courier"; - - if (scope.value >= minLimit && scope.value <= maxLimit) { - var lineData = [ - [needleRadius, 0], - [0, -needleLen], - [-needleRadius, 0], - [needleRadius, 0] - ]; - var pointerLine = d3.svg.line().interpolate('monotone'); - var pg = svg.append('g').data([lineData]) - .attr('class', 'mtt-graduation-needle') - .style("fill", needleColor) - .attr('transform', 'translate(' + centerX + ',' + centerY + ')'); - needle = pg.append('path') - .attr('d', pointerLine) - .attr('transform', 'rotate('+needleAngle+')'); - } - - svg.append("text") - .attr("x", centerX) - .attr("y", centerY + valueVerticalOffset) - .attr("class", "mtt-graduationValueText") - .attr("fill", needleColor) - .attr("text-anchor", "middle") - .attr("font-weight", "bold") - .style("font", fontStyle) - .text('[ ' + scope.value.toFixed(scope.precision) + scope.valueUnit + ' ]'); - } - - var circleRadius = (width * 6) / 300; - - svg.append("circle") - .attr("r", circleRadius) - .attr("cy", centerX) - .attr("cx", centerY) - .attr("fill", centerColor) - .attr("class", "mtt-graduation-needle-center"); - }; - $window.onresize = function () { - scope.$apply(); - }; - scope.$watch(function () { - return angular.element($window)[0].innerWidth; - }, function () { - scope.render(); - }); - scope.$watch('ranges', function () { - scope.render(); - }, true); - - - scope.render = function () { - svg.selectAll('*').remove(); - if (renderTimeout) clearTimeout(renderTimeout); - - renderTimeout = $timeout(function () { - var d3DataSource = []; - - if (typeof scope.ranges === 'undefined') { - d3DataSource.push([minLimit, maxLimit, unactiveColor]); - } else { - //Data Generation - $.each(scope.ranges, function (index, value) { - d3DataSource.push([value.min, value.max, value.color]); - }); - } - - //Render Gauge Color Area - var translate = "translate(" + width / 2 + "," + width / 2 + ")"; - var cScale = d3.scale.linear().domain([minLimit, maxLimit]).range([-120 * (Math.PI / 180), 120 * (Math.PI / 180)]); - var arc = d3.svg.arc() - .innerRadius(innerRadius) - .outerRadius(outterRadius) - .startAngle(function (d) { return cScale(d[0]); }) - .endAngle(function (d) { return cScale(d[1]); }); - svg.selectAll("path") - .data(d3DataSource) - .enter() - .append("path") - .attr("d", arc) - .style("fill", function (d) { return d[2]; }) - .attr("transform", translate); - - var majorGraduationsAngles = getMajorGraduationAngles(); - var majorGraduationValues = getMajorGraduationValues(minLimit, maxLimit); - renderMajorGraduations(majorGraduationsAngles); - renderMajorGraduationTexts(majorGraduationsAngles, majorGraduationValues); - renderGraduationNeedle(minLimit, maxLimit); - initialized = true; - }, 200); - - }; - var update = function(){ - if (typeof scope.value === 'undefined') { - centerColor = unactiveColor; - } else { - if (scope.value >= minLimit && scope.value <= maxLimit) { - var needleAngle = getNewAngle(scope.value); - needle.transition() - .duration(transitionMs) - .ease('elastic') - .attr('transform', 'rotate('+needleAngle+')'); - svg.selectAll('.mtt-graduationValueText') - .text('[ ' + scope.value.toFixed(scope.precision) + scope.valueUnit + ' ]') ; - } else { - svg.selectAll('.mtt-graduation-needle').remove(); - svg.selectAll('.mtt-graduationValueText').remove(); - svg.selectAll('.mtt-graduation-needle-center').attr("fill", unactiveColor); - } - } - }; - scope.$watch('value', function () { - if (!initialized) return; - update(); - }, true); - }); - } - }; - }]) diff --git a/ngRadialGauge/ngRadialGaugeDemo.png b/ngRadialGaugeDemo.png similarity index 100% rename from ngRadialGauge/ngRadialGaugeDemo.png rename to ngRadialGaugeDemo.png diff --git a/ngRadialGauge/ngRadialGauge/src/scripts/services/d3-serv.js b/src/d3-serv.js similarity index 87% rename from ngRadialGauge/ngRadialGauge/src/scripts/services/d3-serv.js rename to src/d3-serv.js index 4ade6a0..dcd8390 100644 --- a/ngRadialGauge/ngRadialGauge/src/scripts/services/d3-serv.js +++ b/src/d3-serv.js @@ -1,5 +1,5 @@ -app.factory('d3Service', ['$document', '$window', '$q', '$rootScope', -require="" +"use strict"; +angular.module("ngRadialGauge").factory('d3Service', ['$document', '$window', '$q', '$rootScope', function($document, $window, $q, $rootScope) { var d = $q.defer(), d3service = { diff --git a/src/ng-radial-gauge-dir.js b/src/ng-radial-gauge-dir.js new file mode 100644 index 0000000..475ce99 --- /dev/null +++ b/src/ng-radial-gauge-dir.js @@ -0,0 +1,335 @@ +/* global d3 */ +/* + ng-radial-gauge 1.0 + (c) 2010-2014 Stéphane Therrien, + https://github.com/stherrienaspnet/ngRadialGauge + License: MIT +*/ +"use strict"; +angular.module("ngRadialGauge",[]).directive('ngRadialGauge', ['$window', '$timeout', + function ($window, $timeout) { + return { + restrict: 'EAC', + scope: { + lowerLimit: '=', + upperLimit: '=', + ranges: '=', + value: '=', + valueUnit: '=', + precision: '=', + label: '@', + onClick: '&' + }, + link: function (scope, ele, attrs) { + var initialized = false; + var renderTimeout; + var width = parseInt(attrs.width) || 300; + var innerRadius = Math.round((width * 130) / 300); + var outterRadius = Math.round((width * 145) / 300); + var majorGraduations = parseInt(attrs.majorGraduations - 1) || 5; + var minorGraduations = parseInt(attrs.minorGraduations) || 10; + var majorGraduationLenght = Math.round((width * 16) / 300); + var minorGraduationLenght = Math.round((width * 10) / 300); + var majorGraduationMarginTop = Math.round((width * 7) / 300); + var majorGraduationColor = attrs.majorGraduationColor || "#B0B0B0"; + var minorGraduationColor = attrs.minorGraduationColor || "#D0D0D0"; + var majorGraduationTextColor = attrs.majorGraduationTextColor || "#6C6C6C"; + var needleColor = attrs.needleColor || "#416094"; + var valueVerticalOffset = Math.round((width * 30) / 300); + var unactiveColor = "#D7D7D7"; + var transitionMs = parseInt(attrs.transitionMs) || 750; + var majorGraduationTextSize = parseInt(attrs.majorGraduationTextSize); + var needleValueTextSize = parseInt(attrs.needleValueTextSize); + + var maxLimit = scope.upperLimit ? scope.upperLimit : 100; + var minLimit = scope.lowerLimit ? scope.lowerLimit : 0; + + var needle = undefined; + var scale = d3.scale.linear() + .range([0,1]) + .domain([minLimit, maxLimit]); + + var svg = d3.select(ele[0]) + .append('svg') + .attr('width', width) + .attr('height', width * 0.75); + var renderMajorGraduations = function (majorGraduationsAngles) { + var centerX = width / 2; + var centerY = width / 2; + //Render Major Graduations + $.each(majorGraduationsAngles, function (index, value) { + var cos1Adj = Math.round(Math.cos((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop - majorGraduationLenght)); + var sin1Adj = Math.round(Math.sin((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop - majorGraduationLenght)); + var cos2Adj = Math.round(Math.cos((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop)); + var sin2Adj = Math.round(Math.sin((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop)); + var x1 = centerX + cos1Adj; + var y1 = centerY + sin1Adj * -1; + var x2 = centerX + cos2Adj; + var y2 = centerY + sin2Adj * -1; + svg.append("svg:line") + .attr("x1", x1) + .attr("y1", y1) + .attr("x2", x2) + .attr("y2", y2) + .style("stroke", majorGraduationColor); + + renderMinorGraduations(majorGraduationsAngles, index); + }); + }; + var renderMinorGraduations = function (majorGraduationsAngles, indexMajor) { + var minorGraduationsAngles = []; + + if (indexMajor > 0) { + var minScale = majorGraduationsAngles[indexMajor - 1]; + var maxScale = majorGraduationsAngles[indexMajor]; + var scaleRange = maxScale - minScale; + + for (var i = 1; i < minorGraduations; i++) { + var scaleValue = minScale + i * scaleRange / minorGraduations; + minorGraduationsAngles.push(scaleValue); + } + + var centerX = width / 2; + var centerY = width / 2; + //Render Minor Graduations + $.each(minorGraduationsAngles, function (indexMinor, value) { + var cos1Adj = Math.round(Math.cos((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop - minorGraduationLenght)); + var sin1Adj = Math.round(Math.sin((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop - minorGraduationLenght)); + var cos2Adj = Math.round(Math.cos((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop)); + var sin2Adj = Math.round(Math.sin((90 - value) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop)); + var x1 = centerX + cos1Adj; + var y1 = centerY + sin1Adj * -1; + var x2 = centerX + cos2Adj; + var y2 = centerY + sin2Adj * -1; + svg.append("svg:line") + .attr("x1", x1) + .attr("y1", y1) + .attr("x2", x2) + .attr("y2", y2) + .style("stroke", minorGraduationColor); + }); + } + }; + var getMajorGraduationValues = function (minLimit, maxLimit) { + var scaleRange = maxLimit - minLimit; + var majorGraduationValues = []; + for (var i = 0; i <= majorGraduations; i++) { + var scaleValue = minLimit + i * scaleRange / (majorGraduations); + majorGraduationValues.push(scaleValue.toFixed(scope.precision)); + } + + return majorGraduationValues; + }; + var getMajorGraduationAngles = function () { + var scaleRange = 240; + var minScale = -120; + var graduationsAngles = []; + for (var i = 0; i <= majorGraduations; i++) { + var scaleValue = minScale + i * scaleRange / (majorGraduations); + graduationsAngles.push(scaleValue); + } + + return graduationsAngles; + }; + var getNewAngle = function(value){ + var ratio = scale(value); + var range = 240; + var minScale = -120; + var newAngle = minScale + (ratio * range); + return newAngle; + }; + var renderMajorGraduationTexts = function (majorGraduationsAngles, majorGraduationValues) { + if (!scope.ranges) return; + + var centerX = width / 2; + var centerY = width / 2; + var textVerticalPadding = 5; + var textHorizontalPadding = 5; + + var lastGraduationValue = majorGraduationValues[majorGraduationValues.length - 1]; + var textSize = isNaN(majorGraduationTextSize) ? (width * 12) / 300 : majorGraduationTextSize; + var fontStyle = textSize + "px Courier"; + + var dummyText = svg.append("text") + .attr("x", centerX) + .attr("y", centerY) + .attr("fill", "transparent") + .attr("text-anchor", "middle") + .style("font", fontStyle) + .text(lastGraduationValue + scope.valueUnit); + + var textWidth = dummyText.node().getBBox().width; + + for (var i = 0; i < majorGraduationsAngles.length; i++) { + var angle = majorGraduationsAngles[i]; + var cos1Adj = Math.round(Math.cos((90 - angle) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop - majorGraduationLenght - textHorizontalPadding)); + var sin1Adj = Math.round(Math.sin((90 - angle) * Math.PI / 180) * (innerRadius - majorGraduationMarginTop - majorGraduationLenght - textVerticalPadding)); + + var sin1Factor = 1; + if (sin1Adj < 0) sin1Factor = 1.1; + if (sin1Adj > 0) sin1Factor = 0.9; + if (cos1Adj > 0) { + if (angle > 0 && angle < 45) { + cos1Adj -= textWidth / 2; + } else { + cos1Adj -= textWidth; + } + } + if (cos1Adj < 0) { + if (angle < 0 && angle > -45) { + cos1Adj -= textWidth / 2; + } + } + if (cos1Adj == 0) { + cos1Adj -= angle == 0 ? textWidth / 4 : textWidth / 2; + } + + var x1 = centerX + cos1Adj; + var y1 = centerY + sin1Adj * sin1Factor * -1; + + svg.append("text") + .attr("class", "mtt-majorGraduationText") + .style("font", fontStyle) + .attr("text-align", "center") + .attr("x", x1) + .attr("dy", y1) + .attr("fill", majorGraduationTextColor) + .text(majorGraduationValues[i] + scope.valueUnit); + } + }; + var renderGraduationNeedle = function (minLimit, maxLimit) { + svg.selectAll('.mtt-graduation-needle').remove(); + svg.selectAll('.mtt-graduationValueText').remove(); + svg.selectAll('.mtt-graduation-needle-center').remove(); + + var centerX = width / 2; + var centerY = width / 2; + var centerColor; + + if (typeof scope.value === 'undefined') { + centerColor = unactiveColor; + } else { + centerColor = needleColor; + var needleAngle = getNewAngle(scope.value); + var needleLen = innerRadius - majorGraduationLenght - majorGraduationMarginTop; + var needleRadius = (width * 2.5) / 300; + var textSize = isNaN(needleValueTextSize) ? (width * 12) / 300 : needleValueTextSize; + var fontStyle = textSize + "px Courier"; + + if (scope.value >= minLimit && scope.value <= maxLimit) { + var lineData = [ + [needleRadius, 0], + [0, -needleLen], + [-needleRadius, 0], + [needleRadius, 0] + ]; + var pointerLine = d3.svg.line().interpolate('monotone'); + var pg = svg.append('g').data([lineData]) + .attr('class', 'mtt-graduation-needle') + .style("fill", needleColor) + .attr('transform', 'translate(' + centerX + ',' + centerY + ')'); + needle = pg.append('path') + .attr('d', pointerLine) + .attr('transform', 'rotate('+needleAngle+')'); + } + + svg.append("text") + .attr("x", centerX) + .attr("y", centerY + valueVerticalOffset) + .attr("class", "mtt-graduationValueText") + .attr("fill", needleColor) + .attr("text-anchor", "middle") + .attr("font-weight", "bold") + .style("font", fontStyle) + .text('[ ' + scope.value.toFixed(scope.precision) + scope.valueUnit + ' ]'); + } + + var circleRadius = (width * 6) / 300; + + svg.append("circle") + .attr("r", circleRadius) + .attr("cy", centerX) + .attr("cx", centerY) + .attr("fill", centerColor) + .attr("class", "mtt-graduation-needle-center"); + }; + $window.onresize = function () { + scope.$apply(); + }; + scope.$watch(function () { + return angular.element($window)[0].innerWidth; + }, function () { + scope.render(); + }); + scope.$watch('ranges', function () { + scope.render(); + }, true); + + + scope.render = function () { + svg.selectAll('*').remove(); + if (renderTimeout) clearTimeout(renderTimeout); + + renderTimeout = $timeout(function () { + var d3DataSource = []; + + if (typeof scope.ranges === 'undefined') { + d3DataSource.push([minLimit, maxLimit, unactiveColor]); + } else { + //Data Generation + $.each(scope.ranges, function (index, value) { + d3DataSource.push([value.min, value.max, value.color]); + }); + } + + //Render Gauge Color Area + var translate = "translate(" + width / 2 + "," + width / 2 + ")"; + var cScale = d3.scale.linear().domain([minLimit, maxLimit]).range([-120 * (Math.PI / 180), 120 * (Math.PI / 180)]); + var arc = d3.svg.arc() + .innerRadius(innerRadius) + .outerRadius(outterRadius) + .startAngle(function (d) { return cScale(d[0]); }) + .endAngle(function (d) { return cScale(d[1]); }); + svg.selectAll("path") + .data(d3DataSource) + .enter() + .append("path") + .attr("d", arc) + .style("fill", function (d) { return d[2]; }) + .attr("transform", translate); + + var majorGraduationsAngles = getMajorGraduationAngles(); + var majorGraduationValues = getMajorGraduationValues(minLimit, maxLimit); + renderMajorGraduations(majorGraduationsAngles); + renderMajorGraduationTexts(majorGraduationsAngles, majorGraduationValues); + renderGraduationNeedle(minLimit, maxLimit); + initialized = true; + }, 200); + + }; + var update = function(){ + if (typeof scope.value === 'undefined') { + centerColor = unactiveColor; + } else { + if (scope.value >= minLimit && scope.value <= maxLimit) { + var needleAngle = getNewAngle(scope.value); + needle.transition() + .duration(transitionMs) + .ease('elastic') + .attr('transform', 'rotate('+needleAngle+')'); + svg.selectAll('.mtt-graduationValueText') + .text('[ ' + scope.value.toFixed(scope.precision) + scope.valueUnit + ' ]') ; + } else { + svg.selectAll('.mtt-graduation-needle').remove(); + svg.selectAll('.mtt-graduationValueText').remove(); + svg.selectAll('.mtt-graduation-needle-center').attr("fill", unactiveColor); + } + } + }; + scope.$watch('value', function () { + if (!initialized) return; + update(); + }, true); + } + }; + }]);