diff --git a/Gruntfile.js b/Gruntfile.js index f1291a7..0bc2c8b 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,42 +1,69 @@ module.exports = function(grunt) { - grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), - makeDemos: { - demos: { - options: { - mainTemplate: 'index.ejs', - out: 'demos' - } - }, - gh_pages: { - options: { - mainTemplate: 'index.ghpages.ejs', - out: './' - } - } - }, - uglify: { - src: { - options: { - banner: '/*! <%= pkg.name %> - v<%= pkg.version %>*/\n\n' - }, - files: { - 'dist/angular-fusioncharts.min.js': ['src/angular-fusioncharts.js'] - } - } + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + makeDemos: { + demos: { + options: { + mainTemplate: 'index.ejs', + out: 'demos' + } + }, + gh_pages: { + options: { + mainTemplate: 'index.ghpages.ejs', + out: './' + } + } + }, + uglify: { + src: { + options: { + banner: '/*! <%= pkg.name %> - v<%= pkg.version %>*/\n\n' }, - copy: { - core: { - files: [ - {src:'dist/angular-fusioncharts.min.js', dest: 'demos/js/angular-fusioncharts.min.js'}, - {src:'src/angular-fusioncharts.js', dest: 'dist/angular-fusioncharts.js'} - ] - } + files: { + 'dist/angular-fusioncharts.min.js': ['src/angular-fusioncharts.js'] + } + } + }, + copy: { + core: { + files: [ + { + src: 'dist/angular-fusioncharts.min.js', + dest: 'demos/js/angular-fusioncharts.min.js' + }, + { + src: 'src/angular-fusioncharts.js', + dest: 'dist/angular-fusioncharts.js' + } + ] + } + }, + watch: { + options: { + livereload: true + }, + taskName: { + files: ['src/*.js', 'example/*.html'], + tasks: ['default'] + } + }, + connect: { + server: { + options: { + port: 8080, + base: './', + livereload: true } - }); - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-contrib-copy'); - grunt.loadTasks('./grunt-tasks'); - //grunt.registerTask('default', ['makeDemos:demos', 'uglify', 'copy']); // For gh-pages branch only - grunt.registerTask('default', ['uglify', 'copy']); // For other branches + } + } + }); + grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadTasks('./grunt-tasks'); + grunt.loadNpmTasks('grunt-contrib-watch'); + //grunt.registerTask('default', ['makeDemos:demos', 'uglify', 'copy']); // For gh-pages branch only + grunt.registerTask('default', ['uglify', 'copy']); // For other branches + grunt.registerTask('watch-server', ['connect', 'watch']); }; diff --git a/dist/angular-fusioncharts.js b/dist/angular-fusioncharts.js index 65450ec..3e98898 100644 --- a/dist/angular-fusioncharts.js +++ b/dist/angular-fusioncharts.js @@ -20,467 +20,721 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. (function() { - var fc = angular.module('ng-fusioncharts', []), + var fc = angular.module('ng-fusioncharts', []), scope = { - width: '@', - height: '@', - data: '@', - dataset: '@', - categories: '@', - chart: '@', - linkeddata: '@', - trendlines: '@', - vtrendlines: '@', - annotations: '@', - colorrange: '@', - lineset: '@', - axis: '@', - connectors: '@', - pointers: '@', - value: '@', - processes: '@', - tasks: '@', - rows: '@', - columns: '@', - map: '@', - markers: '@', - initialized:'&' + width: '@', + height: '@', + data: '@', + dataset: '@', + categories: '@', + chart: '@', + linkeddata: '@', + trendlines: '@', + vtrendlines: '@', + annotations: '@', + colorrange: '@', + lineset: '@', + axis: '@', + connectors: '@', + pointers: '@', + value: '@', + processes: '@', + tasks: '@', + rows: '@', + columns: '@', + map: '@', + markers: '@', + initialized: '&' }, - fcEvents = ['beforelinkeditemopen','linkeditemopened','beforelinkeditemclose','linkeditemclosed','printreadystatechange','dataloadrequestcompleted','dataloaderror','dataloadcancelled','dataloadrequestcancelled','dataupdated','dataupdatecancelled','dataloadrequested','beforedataupdate','realtimeupdatecomplete','chartcleared','slicingend','slicingstart','entityrollout','entityrollover','entityclick','connectorrollover','connectorrollout','connectorclick','markerrollover','markerrollout','markerclick','pagenavigated','rotationend','rotationstart','centerlabelrollover','centerlabelrollout','centerlabelclick','centerlabelchanged','chartclick','chartmousemove','chartrollover','chartrollout','backgroundloaded','backgroundloaderror','legenditemclicked','legenditemrollover','legenditemrollout','logorollover','logorollout','logoclick','logoloaded','logoloaderror','beforeexport','exported','exportcancelled','beforeprint','printcomplete','printcancelled','datalabelclick','datalabelrollover','datalabelrollout','scrollstart','scrollend','onscroll','zoomreset','zoomedout','zoomedin','zoomed','zoommodechanged','pinned','datarestored','beforedatasubmit','datasubmiterror','datasubmitted','datasubmitcancelled','chartupdated','nodeadded','nodeupdated','nodedeleted','connectoradded','connectorupdated','connectordeleted','labeladded','labeldeleted','selectionremoved','selectionstart','selectionend','labelclick','labelrollover','labelrollout','labeldragstart','labeldragend','dataplotdragstart','dataplotdragend','processclick','processrollover','processrollout','categoryclick','categoryrollover','categoryrollout','milestoneclick','milestonerollover','milestonerollout','charttypechanged','overlaybuttonclick','loaded','rendered','drawcomplete','rendercomplete','datainvalid','dataxmlinvalid','dataloaded','nodatatodisplay','legendpointerdragstart','legendpointerdragstop','legendrangeupdated','alertcomplete','realtimeupdateerror','dataplotrollover','dataplotrollout','dataplotclick','linkclicked','beforerender','rendercancelled','beforeresize','resized','resizecancelled','beforedispose','disposed','disposecancelled','linkedchartinvoked','beforedrilldown','drilldown','beforedrillup','drillup','drilldowncancelled','drillupcancelled'], + fcEvents = [ + 'beforelinkeditemopen', + 'linkeditemopened', + 'beforelinkeditemclose', + 'linkeditemclosed', + 'printreadystatechange', + 'dataloadrequestcompleted', + 'dataloaderror', + 'dataloadcancelled', + 'dataloadrequestcancelled', + 'dataupdated', + 'dataupdatecancelled', + 'dataloadrequested', + 'beforedataupdate', + 'realtimeupdatecomplete', + 'chartcleared', + 'slicingend', + 'slicingstart', + 'entityrollout', + 'entityrollover', + 'entityclick', + 'connectorrollover', + 'connectorrollout', + 'connectorclick', + 'markerrollover', + 'markerrollout', + 'markerclick', + 'pagenavigated', + 'rotationend', + 'rotationstart', + 'centerlabelrollover', + 'centerlabelrollout', + 'centerlabelclick', + 'centerlabelchanged', + 'chartclick', + 'chartmousemove', + 'chartrollover', + 'chartrollout', + 'backgroundloaded', + 'backgroundloaderror', + 'legenditemclicked', + 'legenditemrollover', + 'legenditemrollout', + 'logorollover', + 'logorollout', + 'logoclick', + 'logoloaded', + 'logoloaderror', + 'beforeexport', + 'exported', + 'exportcancelled', + 'beforeprint', + 'printcomplete', + 'printcancelled', + 'datalabelclick', + 'datalabelrollover', + 'datalabelrollout', + 'scrollstart', + 'scrollend', + 'onscroll', + 'zoomreset', + 'zoomedout', + 'zoomedin', + 'zoomed', + 'zoommodechanged', + 'pinned', + 'datarestored', + 'beforedatasubmit', + 'datasubmiterror', + 'datasubmitted', + 'datasubmitcancelled', + 'chartupdated', + 'nodeadded', + 'nodeupdated', + 'nodedeleted', + 'connectoradded', + 'connectorupdated', + 'connectordeleted', + 'labeladded', + 'labeldeleted', + 'selectionremoved', + 'selectionstart', + 'selectionend', + 'labelclick', + 'labelrollover', + 'labelrollout', + 'labeldragstart', + 'labeldragend', + 'dataplotdragstart', + 'dataplotdragend', + 'processclick', + 'processrollover', + 'processrollout', + 'categoryclick', + 'categoryrollover', + 'categoryrollout', + 'milestoneclick', + 'milestonerollover', + 'milestonerollout', + 'charttypechanged', + 'overlaybuttonclick', + 'loaded', + 'rendered', + 'drawcomplete', + 'rendercomplete', + 'datainvalid', + 'dataxmlinvalid', + 'dataloaded', + 'nodatatodisplay', + 'legendpointerdragstart', + 'legendpointerdragstop', + 'legendrangeupdated', + 'alertcomplete', + 'realtimeupdateerror', + 'dataplotrollover', + 'dataplotrollout', + 'dataplotclick', + 'linkclicked', + 'beforerender', + 'rendercancelled', + 'beforeresize', + 'resized', + 'resizecancelled', + 'beforedispose', + 'disposed', + 'disposecancelled', + 'linkedchartinvoked', + 'beforedrilldown', + 'drilldown', + 'beforedrillup', + 'drillup', + 'drilldowncancelled', + 'drillupcancelled' + ], currIndex, eventName, eventsLen = fcEvents.length; - for (currIndex = 0; currIndex < eventsLen; currIndex++){ - eventName = 'fcevent' + fcEvents[currIndex][0].toUpperCase() + fcEvents[currIndex].slice(1); - scope[eventName] = '&'; - } - - - fc.directive('fusioncharts', ['$http', function($http) { - return { - scope: scope, - link: function(scope, element, attrs) { - var observeConf = { - // non-data componenet observers - NDCObserver: { - 'width': { - ifExist: false, - observer: function(newVal) { - if (newVal && chartConfigObject.width != newVal) { - chartConfigObject.width = newVal; - chart.resizeTo(scope.width, scope.height); - } - } - }, - 'height': { - ifExist: false, - observer: function(newVal) { - if (newVal && chartConfigObject.height != newVal) { - chartConfigObject.height = newVal; - chart.resizeTo(scope.width, scope.height); - } - } - }, - - 'datasource': { - ifExist: true, - observer: function(newVal) { - if (dataStringStore.dataSource != newVal) { - dataStringStore.dataSource = newVal; - if (chartConfigObject.dataFormat === 'json') { - chartConfigObject.dataSource = JSON.parse(newVal); - setChartData(); - } else { - chartConfigObject.dataSource = newVal; - if (chartConfigObject.dataFormat === 'xml') { - chart.setXMLData(newVal); - } else if (chartConfigObject.dataFormat === 'jsonurl') { - chart.setJSONUrl(newVal); - } else if (chartConfigObject.dataFormat === 'xmlurl') { - chart.setXMLUrl(newVal); - } - } - } - } - }, - 'type': { - ifExist: false, - observer: function(newVal) { - if (newVal && chartConfigObject.type != newVal) { - chartConfigObject.type = newVal; - // createFCChart(); - chart.chartType(newVal); - } - } - }, - 'config': { - ifExist: false, - observer: function(newVal) { - var configObj, - attr, - doReRender = false; - if (newVal) { - configObj = JSON.parse(newVal); - for (attr in configObj) { - // detect the value change - if (chartConfigObject[attr] != configObj[attr]) { - doReRender = true; - chartConfigObject[attr] = configObj[attr]; - } - } - if (doReRender) { - createFCChart(); - } - } - } - } - }, - // data componenet observers - DCObserver: { - 'chart': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.chart != newVal) { - dataStringStore.chart = newVal; - chartConfigObject.dataSource.chart = JSON.parse(newVal); - setChartData(); - } - } - }, - 'data': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.data != newVal) { - dataStringStore.data = newVal; - chartConfigObject.dataSource.data = JSON.parse(newVal); - setChartData(); - } - } - }, - 'categories': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.categories != newVal) { - dataStringStore.categories = newVal; - chartConfigObject.dataSource.categories = JSON.parse(newVal); - setChartData(); - } - } - }, - 'dataset': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.dataset != newVal) { - dataStringStore.dataset = newVal; - chartConfigObject.dataSource.dataset = JSON.parse(newVal); - setChartData(); - } - } - }, - 'linkeddata': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.linkeddata != newVal) { - dataStringStore.linkeddata = newVal; - chartConfigObject.dataSource.linkeddata = JSON.parse(newVal); - setChartData(); - } - } - }, - 'trendlines': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.trendlines != newVal) { - dataStringStore.trendlines = newVal; - chartConfigObject.dataSource.trendlines = JSON.parse(newVal); - setChartData(); - } - } - }, - 'vtrendlines': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.vtrendlines != newVal) { - dataStringStore.vtrendlines = newVal; - chartConfigObject.dataSource.vtrendlines = JSON.parse(newVal); - setChartData(); - } - } - }, - 'annotations': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.annotations != newVal) { - dataStringStore.annotations = newVal; - chartConfigObject.dataSource.annotations = JSON.parse(newVal); - setChartData(); - } - } - }, - 'colorrange': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.colorrange != newVal) { - dataStringStore.colorrange = newVal; - chartConfigObject.dataSource.colorrange = JSON.parse(newVal); - setChartData(); - } - } - }, - 'lineset': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.lineset != newVal) { - dataStringStore.lineset = newVal; - chartConfigObject.dataSource.lineset = JSON.parse(newVal); - setChartData(); - } - } - }, - 'axis': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.axis != newVal) { - dataStringStore.axis = newVal; - chartConfigObject.dataSource.axis = JSON.parse(newVal); - setChartData(); - } - } - }, - 'connectors': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.connectors != newVal) { - dataStringStore.connectors = newVal; - chartConfigObject.dataSource.connectors = JSON.parse(newVal); - setChartData(); - } - } - }, - 'pointers': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.pointers != newVal) { - dataStringStore.pointers = newVal; - chartConfigObject.dataSource.pointers = JSON.parse(newVal); - setChartData(); - } - } - }, - 'value': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.value != newVal) { - dataStringStore.value = newVal; - chartConfigObject.dataSource.value = JSON.parse(newVal); - setChartData(); - } - } - }, - 'processes': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.processes != newVal) { - dataStringStore.processes = newVal; - chartConfigObject.dataSource.processes = JSON.parse(newVal); - setChartData(); - } - } - }, - 'tasks': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.tasks != newVal) { - dataStringStore.tasks = newVal; - chartConfigObject.dataSource.tasks = JSON.parse(newVal); - setChartData(); - } - } - }, - 'rows': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.rows != newVal) { - dataStringStore.rows = newVal; - chartConfigObject.dataSource.rows = JSON.parse(newVal); - setChartData(); - } - } - }, - 'columns': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.columns != newVal) { - dataStringStore.columns = newVal; - chartConfigObject.dataSource.columns = JSON.parse(newVal); - setChartData(); - } - } - }, - 'map': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.map != newVal) { - dataStringStore.map = newVal; - chartConfigObject.dataSource.map = JSON.parse(newVal); - setChartData(); - } - }, - }, - 'markers': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.markers != newVal) { - dataStringStore.markers = newVal; - chartConfigObject.dataSource.markers = JSON.parse(newVal); - setChartData(); - } - } - }, - } - }, - eventsObj = {}, - attribs = Object.keys(attrs), - chart = null, - events = { - '*': function(ev, props) { - if (eventsObj.hasOwnProperty(ev.eventType)) { - eventsObj[ev.eventType](ev, props); - } - } - }, - setDataTimer, - setChartData = function() { - // clear previous dataUpdate timer - if (setDataTimer) { - clearTimeout(setDataTimer); - } - // Update the data with setTimeout - // This will solve the issue of consiquitive data update within very small interval - setDataTimer = setTimeout(function() { - if (chart && chart.setJSONData) { - chart.setJSONData(chartConfigObject.dataSource); - } - }, 0); + for (currIndex = 0; currIndex < eventsLen; currIndex++) { + eventName = + 'fcevent' + + fcEvents[currIndex][0].toUpperCase() + + fcEvents[currIndex].slice(1); + scope[eventName] = '&'; + } - // chart.setJSONData(chartConfigObject.dataSource); - }, - createFCChart = function() { - // dispose if previous chart exists - if (chart && chart.dispose) { - chart.dispose(); - } - chart = new FusionCharts(chartConfigObject); - scope.initialized && scope.initialized({ chart: chart }); - for(currIndex = 0; currIndex < eventsLen ; currIndex++){ - eventName = 'fcevent' + fcEvents[currIndex][0].toUpperCase() + fcEvents[currIndex].slice(1); - // assign all events on chart instance - (function(eventName){ - chart.addEventListener(fcEvents[currIndex], function(event, args){ - scope[eventName] && scope[eventName]({ event:event, args: args }); - }); - })(eventName); + fc.directive('fusioncharts', [ + '$http', + function($http) { + return { + scope: scope, + link: function(scope, element, attrs) { + var observeConf = { + // non-data componenet observers + NDCObserver: { + width: { + ifExist: false, + observer: function(newVal) { + if (newVal && chartConfigObject.width != newVal) { + chartConfigObject.width = newVal; + chart.resizeTo(scope.width, scope.height); + } + } + }, + height: { + ifExist: false, + observer: function(newVal) { + if (newVal && chartConfigObject.height != newVal) { + chartConfigObject.height = newVal; + chart.resizeTo(scope.width, scope.height); + } + } + }, + datasource: { + ifExist: true, + observer: function(newVal) { + console.log('datasource'); + if (dataStringStore.dataSource != newVal) { + dataStringStore.dataSource = newVal; + if (chartConfigObject.dataFormat === 'json') { + chartConfigObject.dataSource = JSON.parse(newVal); + setChartData(); + } else { + chartConfigObject.dataSource = newVal; + if (chartConfigObject.dataFormat === 'xml') { + chart.setXMLData(newVal); + } else if (chartConfigObject.dataFormat === 'jsonurl') { + chart.setJSONUrl(newVal); + } else if (chartConfigObject.dataFormat === 'xmlurl') { + chart.setXMLUrl(newVal); } - /* @todo validate the ready function whether it can be replaced in a better way */ - angular.element(document).ready(function(){ - element.ready(function(){ - // Render the chart only when angular is done compiling the element and DOM. - chart = chart.render(); - scope[attrs.chartobject] = chart; - }); - }); - }, - dataStringStore = {}, - i, - attr, - _eobj, - key, - observableAttr, - chartConfigObject, - configObj, - dataComponent, - eventScopeArr, - l; - - if (attrs.events) { - eventScopeArr = attrs.events.split("."); - l = eventScopeArr.length; - _eobj = scope.$parent; - for (i = 0; i < l; i += 1){ - _eobj = _eobj && _eobj[eventScopeArr[i]]; + } + } + } + }, + type: { + ifExist: false, + observer: function(newVal) { + if (newVal && chartConfigObject.type != newVal) { + chartConfigObject.type = newVal; + // createFCChart(); + chart.chartType(newVal); } - if (_eobj) { - for (key in _eobj) { - if (_eobj.hasOwnProperty(key)) { - eventsObj[key.toLowerCase()] = _eobj[key]; - } + } + }, + config: { + ifExist: false, + observer: function(newVal) { + var configObj, + attr, + doReRender = false; + if (newVal) { + configObj = JSON.parse(newVal); + for (attr in configObj) { + // detect the value change + if (chartConfigObject[attr] != configObj[attr]) { + doReRender = true; + chartConfigObject[attr] = configObj[attr]; } + } + if (doReRender) { + createFCChart(); + } } + } } - for (i = 0; i < attribs.length; i++) { - attr = attribs[i]; - if (attr.match(/^on/i)) { - key = attr.slice(2).toLowerCase(); - eventsObj[key] = scope.$parent[attrs[attr]]; + }, + // data componenet observers + DCObserver: { + chart: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.chart != newVal + ) { + dataStringStore.chart = newVal; + chartConfigObject.dataSource.chart = JSON.parse(newVal); + setChartData(); + } + } + }, + data: { + ifExist: true, + observer: function(newVal) { + console.log('data'); + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.data != newVal + ) { + dataStringStore.data = newVal; + chartConfigObject.dataSource.data = JSON.parse(newVal); + setChartData(); + } + } + }, + categories: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.categories != newVal + ) { + dataStringStore.categories = newVal; + chartConfigObject.dataSource.categories = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + dataset: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.dataset != newVal + ) { + dataStringStore.dataset = newVal; + chartConfigObject.dataSource.dataset = JSON.parse(newVal); + setChartData(); + } + } + }, + linkeddata: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.linkeddata != newVal + ) { + dataStringStore.linkeddata = newVal; + chartConfigObject.dataSource.linkeddata = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + trendlines: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.trendlines != newVal + ) { + dataStringStore.trendlines = newVal; + chartConfigObject.dataSource.trendlines = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + vtrendlines: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.vtrendlines != newVal + ) { + dataStringStore.vtrendlines = newVal; + chartConfigObject.dataSource.vtrendlines = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + annotations: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.annotations != newVal + ) { + dataStringStore.annotations = newVal; + chartConfigObject.dataSource.annotations = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + colorrange: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.colorrange != newVal + ) { + dataStringStore.colorrange = newVal; + chartConfigObject.dataSource.colorrange = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + lineset: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.lineset != newVal + ) { + dataStringStore.lineset = newVal; + chartConfigObject.dataSource.lineset = JSON.parse(newVal); + setChartData(); + } + } + }, + axis: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.axis != newVal + ) { + dataStringStore.axis = newVal; + chartConfigObject.dataSource.axis = JSON.parse(newVal); + setChartData(); + } + } + }, + connectors: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.connectors != newVal + ) { + dataStringStore.connectors = newVal; + chartConfigObject.dataSource.connectors = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + pointers: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.pointers != newVal + ) { + dataStringStore.pointers = newVal; + chartConfigObject.dataSource.pointers = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + value: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.value != newVal + ) { + dataStringStore.value = newVal; + chartConfigObject.dataSource.value = JSON.parse(newVal); + setChartData(); + } + } + }, + processes: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.processes != newVal + ) { + dataStringStore.processes = newVal; + chartConfigObject.dataSource.processes = JSON.parse( + newVal + ); + setChartData(); } + } + }, + tasks: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.tasks != newVal + ) { + dataStringStore.tasks = newVal; + chartConfigObject.dataSource.tasks = JSON.parse(newVal); + setChartData(); + } + } + }, + rows: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.rows != newVal + ) { + dataStringStore.rows = newVal; + chartConfigObject.dataSource.rows = JSON.parse(newVal); + setChartData(); + } + } + }, + columns: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.columns != newVal + ) { + dataStringStore.columns = newVal; + chartConfigObject.dataSource.columns = JSON.parse(newVal); + setChartData(); + } + } + }, + map: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.map != newVal + ) { + dataStringStore.map = newVal; + chartConfigObject.dataSource.map = JSON.parse(newVal); + setChartData(); + } + } + }, + markers: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.markers != newVal + ) { + dataStringStore.markers = newVal; + chartConfigObject.dataSource.markers = JSON.parse(newVal); + setChartData(); + } + } + } + } + }, + eventsObj = {}, + attribs = Object.keys(attrs), + chart = null, + events = { + '*': function(ev, props) { + if (eventsObj.hasOwnProperty(ev.eventType)) { + eventsObj[ev.eventType](ev, props); + } + } + }, + setDataTimer, + setChartData = function() { + console.log('setChartData'); + // clear previous dataUpdate timer + if (setDataTimer) { + clearTimeout(setDataTimer); + } + // Update the data with setTimeout + // This will solve the issue of consiquitive data update within very small interval + setDataTimer = setTimeout(function() { + if (chart && chart.setJSONData) { + chart.setJSONData(chartConfigObject.dataSource); } + }, 0); + // chart.setJSONData(chartConfigObject.dataSource); + }, + createFCChart = function() { + console.log('createFCChart'); + // dispose if previous chart exists + if (chart && chart.dispose) { + chart.dispose(); + } + chart = new FusionCharts(chartConfigObject); + scope.initialized && scope.initialized({ chart: chart }); + for (currIndex = 0; currIndex < eventsLen; currIndex++) { + eventName = + 'fcevent' + + fcEvents[currIndex][0].toUpperCase() + + fcEvents[currIndex].slice(1); + // assign all events on chart instance + (function(eventName) { + chart.addEventListener(fcEvents[currIndex], function( + event, + args + ) { + scope[eventName] && + scope[eventName]({ event: event, args: args }); + }); + })(eventName); + } + /* @todo validate the ready function whether it can be replaced in a better way */ + angular.element(document).ready(function() { + element.ready(function() { + // Render the chart only when angular is done compiling the element and DOM. + chart = chart.render(); + scope[attrs.chartobject] = chart; + }); + }); + }, + dataStringStore = {}, + i, + attr, + _eobj, + key, + observableAttr, + chartConfigObject, + configObj, + dataComponent, + eventScopeArr, + l; - chartConfigObject = { - type: attrs.type, - width: attrs.width, - height: attrs.height, - renderAt: element[0], - id: attrs.chartid, - dataFormat: attrs.dataformat || 'json', - dataSource: {}, - events: events - }; + if (attrs.events) { + eventScopeArr = attrs.events.split('.'); + l = eventScopeArr.length; + _eobj = scope.$parent; + for (i = 0; i < l; i += 1) { + _eobj = _eobj && _eobj[eventScopeArr[i]]; + } + if (_eobj) { + for (key in _eobj) { + if (_eobj.hasOwnProperty(key)) { + eventsObj[key.toLowerCase()] = _eobj[key]; + } + } + } + } + for (i = 0; i < attribs.length; i++) { + attr = attribs[i]; + if (attr.match(/^on/i)) { + key = attr.slice(2).toLowerCase(); + eventsObj[key] = scope.$parent[attrs[attr]]; + } + } + chartConfigObject = { + type: attrs.type, + width: attrs.width, + height: attrs.height, + renderAt: element[0], + id: attrs.chartid, + dataFormat: attrs.dataformat || 'json', + dataSource: {}, + events: events + }; - for (observableAttr in observeConf.NDCObserver) { - attrConfig = observeConf.NDCObserver[observableAttr]; - if (attrConfig.ifExist === false || attrs[observableAttr]) { - attrs.$observe(observableAttr, attrConfig.observer); - } - } + for (observableAttr in observeConf.NDCObserver) { + attrConfig = observeConf.NDCObserver[observableAttr]; + if (attrConfig.ifExist === false || attrs[observableAttr]) { + attrs.$observe(observableAttr, attrConfig.observer); + } + } - if (attrs.datasource) { - chartConfigObject.dataSource = (chartConfigObject.dataFormat === 'json') ? JSON.parse(attrs.datasource) : attrs.datasource; - dataStringStore.dataSource = attrs.datasource; - } + console.log(attrs.datasource); - for (observableAttr in observeConf.DCObserver) { - attrConfig = observeConf.DCObserver[observableAttr]; - dataComponent = attrs[observableAttr]; - if (dataComponent) { - attrs.$observe(observableAttr, attrConfig.observer); - dataStringStore[observableAttr] = dataComponent; - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource === "object") { - chartConfigObject.dataSource[observableAttr] = JSON.parse(dataComponent); - } - } else if (attrConfig.ifExist === false) { - attrs.$observe(observableAttr, attrConfig.observer); - } - } + if (attrs.datasource) { + chartConfigObject.dataSource = + chartConfigObject.dataFormat === 'json' + ? JSON.parse(attrs.datasource) + : attrs.datasource; + dataStringStore.dataSource = attrs.datasource; + } - // add configurations from config - if (attrs.config) { - configObj = JSON.parse(attrs.config); - for (attr in configObj) { - chartConfigObject[attr] = configObj[attr]; - } - } + for (observableAttr in observeConf.DCObserver) { + attrConfig = observeConf.DCObserver[observableAttr]; + dataComponent = attrs[observableAttr]; + if (dataComponent) { + attrs.$observe(observableAttr, attrConfig.observer); + dataStringStore[observableAttr] = dataComponent; + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource === 'object' + ) { + chartConfigObject.dataSource[observableAttr] = JSON.parse( + dataComponent + ); + } + } else if (attrConfig.ifExist === false) { + attrs.$observe(observableAttr, attrConfig.observer); + } + } + + // add configurations from config + if (attrs.config) { + configObj = JSON.parse(attrs.config); + for (attr in configObj) { + chartConfigObject[attr] = configObj[attr]; + } + } - createFCChart(); + createFCChart(); - scope.$on('$destroy', function () { - // on destroy free used resources to avoid memory leaks - if (chart && chart.dispose) { - chart.dispose(); - } - }); + scope.$on('$destroy', function() { + // on destroy free used resources to avoid memory leaks + if (chart && chart.dispose) { + chart.dispose(); } - }; - }]); -}()); + }); + } + }; + } + ]); +})(); diff --git a/dist/angular-fusioncharts.min.js b/dist/angular-fusioncharts.min.js index fd16208..6848346 100644 --- a/dist/angular-fusioncharts.min.js +++ b/dist/angular-fusioncharts.min.js @@ -1,3 +1,3 @@ -/*! angularjs-fusioncharts - v4.0.2*/ +/*! angularjs-fusioncharts - v4.0.3*/ -!function(){var a,b,c=angular.module("ng-fusioncharts",[]),d={width:"@",height:"@",data:"@",dataset:"@",categories:"@",chart:"@",linkeddata:"@",trendlines:"@",vtrendlines:"@",annotations:"@",colorrange:"@",lineset:"@",axis:"@",connectors:"@",pointers:"@",value:"@",processes:"@",tasks:"@",rows:"@",columns:"@",map:"@",markers:"@",initialized:"&"},e=["beforelinkeditemopen","linkeditemopened","beforelinkeditemclose","linkeditemclosed","printreadystatechange","dataloadrequestcompleted","dataloaderror","dataloadcancelled","dataloadrequestcancelled","dataupdated","dataupdatecancelled","dataloadrequested","beforedataupdate","realtimeupdatecomplete","chartcleared","slicingend","slicingstart","entityrollout","entityrollover","entityclick","connectorrollover","connectorrollout","connectorclick","markerrollover","markerrollout","markerclick","pagenavigated","rotationend","rotationstart","centerlabelrollover","centerlabelrollout","centerlabelclick","centerlabelchanged","chartclick","chartmousemove","chartrollover","chartrollout","backgroundloaded","backgroundloaderror","legenditemclicked","legenditemrollover","legenditemrollout","logorollover","logorollout","logoclick","logoloaded","logoloaderror","beforeexport","exported","exportcancelled","beforeprint","printcomplete","printcancelled","datalabelclick","datalabelrollover","datalabelrollout","scrollstart","scrollend","onscroll","zoomreset","zoomedout","zoomedin","zoomed","zoommodechanged","pinned","datarestored","beforedatasubmit","datasubmiterror","datasubmitted","datasubmitcancelled","chartupdated","nodeadded","nodeupdated","nodedeleted","connectoradded","connectorupdated","connectordeleted","labeladded","labeldeleted","selectionremoved","selectionstart","selectionend","labelclick","labelrollover","labelrollout","labeldragstart","labeldragend","dataplotdragstart","dataplotdragend","processclick","processrollover","processrollout","categoryclick","categoryrollover","categoryrollout","milestoneclick","milestonerollover","milestonerollout","charttypechanged","overlaybuttonclick","loaded","rendered","drawcomplete","rendercomplete","datainvalid","dataxmlinvalid","dataloaded","nodatatodisplay","legendpointerdragstart","legendpointerdragstop","legendrangeupdated","alertcomplete","realtimeupdateerror","dataplotrollover","dataplotrollout","dataplotclick","linkclicked","beforerender","rendercancelled","beforeresize","resized","resizecancelled","beforedispose","disposed","disposecancelled","linkedchartinvoked","beforedrilldown","drilldown","beforedrillup","drillup","drilldowncancelled","drillupcancelled"],f=e.length;for(a=0;a + + + + + + Document + + + + + + + + +
+ +
+ +
+ + diff --git a/package.json b/package.json index 7d52775..6c9822b 100644 --- a/package.json +++ b/package.json @@ -12,12 +12,20 @@ "bugs": { "url": "https://github.com/fusioncharts/angularjs-fusioncharts/issues" }, + "scripts": { + "dev": "npx grunt watch-server", + "build": "npx grunt" + }, "homepage": "https://www.fusioncharts.com/angularjs-charts/", "dependencies": {}, "devDependencies": { + "angular": "^1.7.2", "ejs": "^1.0.0", + "fusioncharts": "^3.13.3-sr.1", "grunt": "^0.4.5", + "grunt-contrib-connect": "^2.0.0", "grunt-contrib-copy": "^0.7.0", - "grunt-contrib-uglify": "^0.6.0" + "grunt-contrib-uglify": "^0.6.0", + "grunt-contrib-watch": "^1.1.0" } } diff --git a/src/angular-fusioncharts.js b/src/angular-fusioncharts.js index 65450ec..3e98898 100644 --- a/src/angular-fusioncharts.js +++ b/src/angular-fusioncharts.js @@ -20,467 +20,721 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. (function() { - var fc = angular.module('ng-fusioncharts', []), + var fc = angular.module('ng-fusioncharts', []), scope = { - width: '@', - height: '@', - data: '@', - dataset: '@', - categories: '@', - chart: '@', - linkeddata: '@', - trendlines: '@', - vtrendlines: '@', - annotations: '@', - colorrange: '@', - lineset: '@', - axis: '@', - connectors: '@', - pointers: '@', - value: '@', - processes: '@', - tasks: '@', - rows: '@', - columns: '@', - map: '@', - markers: '@', - initialized:'&' + width: '@', + height: '@', + data: '@', + dataset: '@', + categories: '@', + chart: '@', + linkeddata: '@', + trendlines: '@', + vtrendlines: '@', + annotations: '@', + colorrange: '@', + lineset: '@', + axis: '@', + connectors: '@', + pointers: '@', + value: '@', + processes: '@', + tasks: '@', + rows: '@', + columns: '@', + map: '@', + markers: '@', + initialized: '&' }, - fcEvents = ['beforelinkeditemopen','linkeditemopened','beforelinkeditemclose','linkeditemclosed','printreadystatechange','dataloadrequestcompleted','dataloaderror','dataloadcancelled','dataloadrequestcancelled','dataupdated','dataupdatecancelled','dataloadrequested','beforedataupdate','realtimeupdatecomplete','chartcleared','slicingend','slicingstart','entityrollout','entityrollover','entityclick','connectorrollover','connectorrollout','connectorclick','markerrollover','markerrollout','markerclick','pagenavigated','rotationend','rotationstart','centerlabelrollover','centerlabelrollout','centerlabelclick','centerlabelchanged','chartclick','chartmousemove','chartrollover','chartrollout','backgroundloaded','backgroundloaderror','legenditemclicked','legenditemrollover','legenditemrollout','logorollover','logorollout','logoclick','logoloaded','logoloaderror','beforeexport','exported','exportcancelled','beforeprint','printcomplete','printcancelled','datalabelclick','datalabelrollover','datalabelrollout','scrollstart','scrollend','onscroll','zoomreset','zoomedout','zoomedin','zoomed','zoommodechanged','pinned','datarestored','beforedatasubmit','datasubmiterror','datasubmitted','datasubmitcancelled','chartupdated','nodeadded','nodeupdated','nodedeleted','connectoradded','connectorupdated','connectordeleted','labeladded','labeldeleted','selectionremoved','selectionstart','selectionend','labelclick','labelrollover','labelrollout','labeldragstart','labeldragend','dataplotdragstart','dataplotdragend','processclick','processrollover','processrollout','categoryclick','categoryrollover','categoryrollout','milestoneclick','milestonerollover','milestonerollout','charttypechanged','overlaybuttonclick','loaded','rendered','drawcomplete','rendercomplete','datainvalid','dataxmlinvalid','dataloaded','nodatatodisplay','legendpointerdragstart','legendpointerdragstop','legendrangeupdated','alertcomplete','realtimeupdateerror','dataplotrollover','dataplotrollout','dataplotclick','linkclicked','beforerender','rendercancelled','beforeresize','resized','resizecancelled','beforedispose','disposed','disposecancelled','linkedchartinvoked','beforedrilldown','drilldown','beforedrillup','drillup','drilldowncancelled','drillupcancelled'], + fcEvents = [ + 'beforelinkeditemopen', + 'linkeditemopened', + 'beforelinkeditemclose', + 'linkeditemclosed', + 'printreadystatechange', + 'dataloadrequestcompleted', + 'dataloaderror', + 'dataloadcancelled', + 'dataloadrequestcancelled', + 'dataupdated', + 'dataupdatecancelled', + 'dataloadrequested', + 'beforedataupdate', + 'realtimeupdatecomplete', + 'chartcleared', + 'slicingend', + 'slicingstart', + 'entityrollout', + 'entityrollover', + 'entityclick', + 'connectorrollover', + 'connectorrollout', + 'connectorclick', + 'markerrollover', + 'markerrollout', + 'markerclick', + 'pagenavigated', + 'rotationend', + 'rotationstart', + 'centerlabelrollover', + 'centerlabelrollout', + 'centerlabelclick', + 'centerlabelchanged', + 'chartclick', + 'chartmousemove', + 'chartrollover', + 'chartrollout', + 'backgroundloaded', + 'backgroundloaderror', + 'legenditemclicked', + 'legenditemrollover', + 'legenditemrollout', + 'logorollover', + 'logorollout', + 'logoclick', + 'logoloaded', + 'logoloaderror', + 'beforeexport', + 'exported', + 'exportcancelled', + 'beforeprint', + 'printcomplete', + 'printcancelled', + 'datalabelclick', + 'datalabelrollover', + 'datalabelrollout', + 'scrollstart', + 'scrollend', + 'onscroll', + 'zoomreset', + 'zoomedout', + 'zoomedin', + 'zoomed', + 'zoommodechanged', + 'pinned', + 'datarestored', + 'beforedatasubmit', + 'datasubmiterror', + 'datasubmitted', + 'datasubmitcancelled', + 'chartupdated', + 'nodeadded', + 'nodeupdated', + 'nodedeleted', + 'connectoradded', + 'connectorupdated', + 'connectordeleted', + 'labeladded', + 'labeldeleted', + 'selectionremoved', + 'selectionstart', + 'selectionend', + 'labelclick', + 'labelrollover', + 'labelrollout', + 'labeldragstart', + 'labeldragend', + 'dataplotdragstart', + 'dataplotdragend', + 'processclick', + 'processrollover', + 'processrollout', + 'categoryclick', + 'categoryrollover', + 'categoryrollout', + 'milestoneclick', + 'milestonerollover', + 'milestonerollout', + 'charttypechanged', + 'overlaybuttonclick', + 'loaded', + 'rendered', + 'drawcomplete', + 'rendercomplete', + 'datainvalid', + 'dataxmlinvalid', + 'dataloaded', + 'nodatatodisplay', + 'legendpointerdragstart', + 'legendpointerdragstop', + 'legendrangeupdated', + 'alertcomplete', + 'realtimeupdateerror', + 'dataplotrollover', + 'dataplotrollout', + 'dataplotclick', + 'linkclicked', + 'beforerender', + 'rendercancelled', + 'beforeresize', + 'resized', + 'resizecancelled', + 'beforedispose', + 'disposed', + 'disposecancelled', + 'linkedchartinvoked', + 'beforedrilldown', + 'drilldown', + 'beforedrillup', + 'drillup', + 'drilldowncancelled', + 'drillupcancelled' + ], currIndex, eventName, eventsLen = fcEvents.length; - for (currIndex = 0; currIndex < eventsLen; currIndex++){ - eventName = 'fcevent' + fcEvents[currIndex][0].toUpperCase() + fcEvents[currIndex].slice(1); - scope[eventName] = '&'; - } - - - fc.directive('fusioncharts', ['$http', function($http) { - return { - scope: scope, - link: function(scope, element, attrs) { - var observeConf = { - // non-data componenet observers - NDCObserver: { - 'width': { - ifExist: false, - observer: function(newVal) { - if (newVal && chartConfigObject.width != newVal) { - chartConfigObject.width = newVal; - chart.resizeTo(scope.width, scope.height); - } - } - }, - 'height': { - ifExist: false, - observer: function(newVal) { - if (newVal && chartConfigObject.height != newVal) { - chartConfigObject.height = newVal; - chart.resizeTo(scope.width, scope.height); - } - } - }, - - 'datasource': { - ifExist: true, - observer: function(newVal) { - if (dataStringStore.dataSource != newVal) { - dataStringStore.dataSource = newVal; - if (chartConfigObject.dataFormat === 'json') { - chartConfigObject.dataSource = JSON.parse(newVal); - setChartData(); - } else { - chartConfigObject.dataSource = newVal; - if (chartConfigObject.dataFormat === 'xml') { - chart.setXMLData(newVal); - } else if (chartConfigObject.dataFormat === 'jsonurl') { - chart.setJSONUrl(newVal); - } else if (chartConfigObject.dataFormat === 'xmlurl') { - chart.setXMLUrl(newVal); - } - } - } - } - }, - 'type': { - ifExist: false, - observer: function(newVal) { - if (newVal && chartConfigObject.type != newVal) { - chartConfigObject.type = newVal; - // createFCChart(); - chart.chartType(newVal); - } - } - }, - 'config': { - ifExist: false, - observer: function(newVal) { - var configObj, - attr, - doReRender = false; - if (newVal) { - configObj = JSON.parse(newVal); - for (attr in configObj) { - // detect the value change - if (chartConfigObject[attr] != configObj[attr]) { - doReRender = true; - chartConfigObject[attr] = configObj[attr]; - } - } - if (doReRender) { - createFCChart(); - } - } - } - } - }, - // data componenet observers - DCObserver: { - 'chart': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.chart != newVal) { - dataStringStore.chart = newVal; - chartConfigObject.dataSource.chart = JSON.parse(newVal); - setChartData(); - } - } - }, - 'data': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.data != newVal) { - dataStringStore.data = newVal; - chartConfigObject.dataSource.data = JSON.parse(newVal); - setChartData(); - } - } - }, - 'categories': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.categories != newVal) { - dataStringStore.categories = newVal; - chartConfigObject.dataSource.categories = JSON.parse(newVal); - setChartData(); - } - } - }, - 'dataset': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.dataset != newVal) { - dataStringStore.dataset = newVal; - chartConfigObject.dataSource.dataset = JSON.parse(newVal); - setChartData(); - } - } - }, - 'linkeddata': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.linkeddata != newVal) { - dataStringStore.linkeddata = newVal; - chartConfigObject.dataSource.linkeddata = JSON.parse(newVal); - setChartData(); - } - } - }, - 'trendlines': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.trendlines != newVal) { - dataStringStore.trendlines = newVal; - chartConfigObject.dataSource.trendlines = JSON.parse(newVal); - setChartData(); - } - } - }, - 'vtrendlines': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.vtrendlines != newVal) { - dataStringStore.vtrendlines = newVal; - chartConfigObject.dataSource.vtrendlines = JSON.parse(newVal); - setChartData(); - } - } - }, - 'annotations': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.annotations != newVal) { - dataStringStore.annotations = newVal; - chartConfigObject.dataSource.annotations = JSON.parse(newVal); - setChartData(); - } - } - }, - 'colorrange': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.colorrange != newVal) { - dataStringStore.colorrange = newVal; - chartConfigObject.dataSource.colorrange = JSON.parse(newVal); - setChartData(); - } - } - }, - 'lineset': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.lineset != newVal) { - dataStringStore.lineset = newVal; - chartConfigObject.dataSource.lineset = JSON.parse(newVal); - setChartData(); - } - } - }, - 'axis': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.axis != newVal) { - dataStringStore.axis = newVal; - chartConfigObject.dataSource.axis = JSON.parse(newVal); - setChartData(); - } - } - }, - 'connectors': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.connectors != newVal) { - dataStringStore.connectors = newVal; - chartConfigObject.dataSource.connectors = JSON.parse(newVal); - setChartData(); - } - } - }, - 'pointers': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.pointers != newVal) { - dataStringStore.pointers = newVal; - chartConfigObject.dataSource.pointers = JSON.parse(newVal); - setChartData(); - } - } - }, - 'value': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.value != newVal) { - dataStringStore.value = newVal; - chartConfigObject.dataSource.value = JSON.parse(newVal); - setChartData(); - } - } - }, - 'processes': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.processes != newVal) { - dataStringStore.processes = newVal; - chartConfigObject.dataSource.processes = JSON.parse(newVal); - setChartData(); - } - } - }, - 'tasks': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.tasks != newVal) { - dataStringStore.tasks = newVal; - chartConfigObject.dataSource.tasks = JSON.parse(newVal); - setChartData(); - } - } - }, - 'rows': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.rows != newVal) { - dataStringStore.rows = newVal; - chartConfigObject.dataSource.rows = JSON.parse(newVal); - setChartData(); - } - } - }, - 'columns': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.columns != newVal) { - dataStringStore.columns = newVal; - chartConfigObject.dataSource.columns = JSON.parse(newVal); - setChartData(); - } - } - }, - 'map': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.map != newVal) { - dataStringStore.map = newVal; - chartConfigObject.dataSource.map = JSON.parse(newVal); - setChartData(); - } - }, - }, - 'markers': { - ifExist: true, - observer: function(newVal) { - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource == "object" && dataStringStore.markers != newVal) { - dataStringStore.markers = newVal; - chartConfigObject.dataSource.markers = JSON.parse(newVal); - setChartData(); - } - } - }, - } - }, - eventsObj = {}, - attribs = Object.keys(attrs), - chart = null, - events = { - '*': function(ev, props) { - if (eventsObj.hasOwnProperty(ev.eventType)) { - eventsObj[ev.eventType](ev, props); - } - } - }, - setDataTimer, - setChartData = function() { - // clear previous dataUpdate timer - if (setDataTimer) { - clearTimeout(setDataTimer); - } - // Update the data with setTimeout - // This will solve the issue of consiquitive data update within very small interval - setDataTimer = setTimeout(function() { - if (chart && chart.setJSONData) { - chart.setJSONData(chartConfigObject.dataSource); - } - }, 0); + for (currIndex = 0; currIndex < eventsLen; currIndex++) { + eventName = + 'fcevent' + + fcEvents[currIndex][0].toUpperCase() + + fcEvents[currIndex].slice(1); + scope[eventName] = '&'; + } - // chart.setJSONData(chartConfigObject.dataSource); - }, - createFCChart = function() { - // dispose if previous chart exists - if (chart && chart.dispose) { - chart.dispose(); - } - chart = new FusionCharts(chartConfigObject); - scope.initialized && scope.initialized({ chart: chart }); - for(currIndex = 0; currIndex < eventsLen ; currIndex++){ - eventName = 'fcevent' + fcEvents[currIndex][0].toUpperCase() + fcEvents[currIndex].slice(1); - // assign all events on chart instance - (function(eventName){ - chart.addEventListener(fcEvents[currIndex], function(event, args){ - scope[eventName] && scope[eventName]({ event:event, args: args }); - }); - })(eventName); + fc.directive('fusioncharts', [ + '$http', + function($http) { + return { + scope: scope, + link: function(scope, element, attrs) { + var observeConf = { + // non-data componenet observers + NDCObserver: { + width: { + ifExist: false, + observer: function(newVal) { + if (newVal && chartConfigObject.width != newVal) { + chartConfigObject.width = newVal; + chart.resizeTo(scope.width, scope.height); + } + } + }, + height: { + ifExist: false, + observer: function(newVal) { + if (newVal && chartConfigObject.height != newVal) { + chartConfigObject.height = newVal; + chart.resizeTo(scope.width, scope.height); + } + } + }, + datasource: { + ifExist: true, + observer: function(newVal) { + console.log('datasource'); + if (dataStringStore.dataSource != newVal) { + dataStringStore.dataSource = newVal; + if (chartConfigObject.dataFormat === 'json') { + chartConfigObject.dataSource = JSON.parse(newVal); + setChartData(); + } else { + chartConfigObject.dataSource = newVal; + if (chartConfigObject.dataFormat === 'xml') { + chart.setXMLData(newVal); + } else if (chartConfigObject.dataFormat === 'jsonurl') { + chart.setJSONUrl(newVal); + } else if (chartConfigObject.dataFormat === 'xmlurl') { + chart.setXMLUrl(newVal); } - /* @todo validate the ready function whether it can be replaced in a better way */ - angular.element(document).ready(function(){ - element.ready(function(){ - // Render the chart only when angular is done compiling the element and DOM. - chart = chart.render(); - scope[attrs.chartobject] = chart; - }); - }); - }, - dataStringStore = {}, - i, - attr, - _eobj, - key, - observableAttr, - chartConfigObject, - configObj, - dataComponent, - eventScopeArr, - l; - - if (attrs.events) { - eventScopeArr = attrs.events.split("."); - l = eventScopeArr.length; - _eobj = scope.$parent; - for (i = 0; i < l; i += 1){ - _eobj = _eobj && _eobj[eventScopeArr[i]]; + } + } + } + }, + type: { + ifExist: false, + observer: function(newVal) { + if (newVal && chartConfigObject.type != newVal) { + chartConfigObject.type = newVal; + // createFCChart(); + chart.chartType(newVal); } - if (_eobj) { - for (key in _eobj) { - if (_eobj.hasOwnProperty(key)) { - eventsObj[key.toLowerCase()] = _eobj[key]; - } + } + }, + config: { + ifExist: false, + observer: function(newVal) { + var configObj, + attr, + doReRender = false; + if (newVal) { + configObj = JSON.parse(newVal); + for (attr in configObj) { + // detect the value change + if (chartConfigObject[attr] != configObj[attr]) { + doReRender = true; + chartConfigObject[attr] = configObj[attr]; } + } + if (doReRender) { + createFCChart(); + } } + } } - for (i = 0; i < attribs.length; i++) { - attr = attribs[i]; - if (attr.match(/^on/i)) { - key = attr.slice(2).toLowerCase(); - eventsObj[key] = scope.$parent[attrs[attr]]; + }, + // data componenet observers + DCObserver: { + chart: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.chart != newVal + ) { + dataStringStore.chart = newVal; + chartConfigObject.dataSource.chart = JSON.parse(newVal); + setChartData(); + } + } + }, + data: { + ifExist: true, + observer: function(newVal) { + console.log('data'); + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.data != newVal + ) { + dataStringStore.data = newVal; + chartConfigObject.dataSource.data = JSON.parse(newVal); + setChartData(); + } + } + }, + categories: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.categories != newVal + ) { + dataStringStore.categories = newVal; + chartConfigObject.dataSource.categories = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + dataset: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.dataset != newVal + ) { + dataStringStore.dataset = newVal; + chartConfigObject.dataSource.dataset = JSON.parse(newVal); + setChartData(); + } + } + }, + linkeddata: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.linkeddata != newVal + ) { + dataStringStore.linkeddata = newVal; + chartConfigObject.dataSource.linkeddata = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + trendlines: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.trendlines != newVal + ) { + dataStringStore.trendlines = newVal; + chartConfigObject.dataSource.trendlines = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + vtrendlines: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.vtrendlines != newVal + ) { + dataStringStore.vtrendlines = newVal; + chartConfigObject.dataSource.vtrendlines = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + annotations: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.annotations != newVal + ) { + dataStringStore.annotations = newVal; + chartConfigObject.dataSource.annotations = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + colorrange: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.colorrange != newVal + ) { + dataStringStore.colorrange = newVal; + chartConfigObject.dataSource.colorrange = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + lineset: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.lineset != newVal + ) { + dataStringStore.lineset = newVal; + chartConfigObject.dataSource.lineset = JSON.parse(newVal); + setChartData(); + } + } + }, + axis: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.axis != newVal + ) { + dataStringStore.axis = newVal; + chartConfigObject.dataSource.axis = JSON.parse(newVal); + setChartData(); + } + } + }, + connectors: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.connectors != newVal + ) { + dataStringStore.connectors = newVal; + chartConfigObject.dataSource.connectors = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + pointers: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.pointers != newVal + ) { + dataStringStore.pointers = newVal; + chartConfigObject.dataSource.pointers = JSON.parse( + newVal + ); + setChartData(); + } + } + }, + value: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.value != newVal + ) { + dataStringStore.value = newVal; + chartConfigObject.dataSource.value = JSON.parse(newVal); + setChartData(); + } + } + }, + processes: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.processes != newVal + ) { + dataStringStore.processes = newVal; + chartConfigObject.dataSource.processes = JSON.parse( + newVal + ); + setChartData(); } + } + }, + tasks: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.tasks != newVal + ) { + dataStringStore.tasks = newVal; + chartConfigObject.dataSource.tasks = JSON.parse(newVal); + setChartData(); + } + } + }, + rows: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.rows != newVal + ) { + dataStringStore.rows = newVal; + chartConfigObject.dataSource.rows = JSON.parse(newVal); + setChartData(); + } + } + }, + columns: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.columns != newVal + ) { + dataStringStore.columns = newVal; + chartConfigObject.dataSource.columns = JSON.parse(newVal); + setChartData(); + } + } + }, + map: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.map != newVal + ) { + dataStringStore.map = newVal; + chartConfigObject.dataSource.map = JSON.parse(newVal); + setChartData(); + } + } + }, + markers: { + ifExist: true, + observer: function(newVal) { + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource == 'object' && + dataStringStore.markers != newVal + ) { + dataStringStore.markers = newVal; + chartConfigObject.dataSource.markers = JSON.parse(newVal); + setChartData(); + } + } + } + } + }, + eventsObj = {}, + attribs = Object.keys(attrs), + chart = null, + events = { + '*': function(ev, props) { + if (eventsObj.hasOwnProperty(ev.eventType)) { + eventsObj[ev.eventType](ev, props); + } + } + }, + setDataTimer, + setChartData = function() { + console.log('setChartData'); + // clear previous dataUpdate timer + if (setDataTimer) { + clearTimeout(setDataTimer); + } + // Update the data with setTimeout + // This will solve the issue of consiquitive data update within very small interval + setDataTimer = setTimeout(function() { + if (chart && chart.setJSONData) { + chart.setJSONData(chartConfigObject.dataSource); } + }, 0); + // chart.setJSONData(chartConfigObject.dataSource); + }, + createFCChart = function() { + console.log('createFCChart'); + // dispose if previous chart exists + if (chart && chart.dispose) { + chart.dispose(); + } + chart = new FusionCharts(chartConfigObject); + scope.initialized && scope.initialized({ chart: chart }); + for (currIndex = 0; currIndex < eventsLen; currIndex++) { + eventName = + 'fcevent' + + fcEvents[currIndex][0].toUpperCase() + + fcEvents[currIndex].slice(1); + // assign all events on chart instance + (function(eventName) { + chart.addEventListener(fcEvents[currIndex], function( + event, + args + ) { + scope[eventName] && + scope[eventName]({ event: event, args: args }); + }); + })(eventName); + } + /* @todo validate the ready function whether it can be replaced in a better way */ + angular.element(document).ready(function() { + element.ready(function() { + // Render the chart only when angular is done compiling the element and DOM. + chart = chart.render(); + scope[attrs.chartobject] = chart; + }); + }); + }, + dataStringStore = {}, + i, + attr, + _eobj, + key, + observableAttr, + chartConfigObject, + configObj, + dataComponent, + eventScopeArr, + l; - chartConfigObject = { - type: attrs.type, - width: attrs.width, - height: attrs.height, - renderAt: element[0], - id: attrs.chartid, - dataFormat: attrs.dataformat || 'json', - dataSource: {}, - events: events - }; + if (attrs.events) { + eventScopeArr = attrs.events.split('.'); + l = eventScopeArr.length; + _eobj = scope.$parent; + for (i = 0; i < l; i += 1) { + _eobj = _eobj && _eobj[eventScopeArr[i]]; + } + if (_eobj) { + for (key in _eobj) { + if (_eobj.hasOwnProperty(key)) { + eventsObj[key.toLowerCase()] = _eobj[key]; + } + } + } + } + for (i = 0; i < attribs.length; i++) { + attr = attribs[i]; + if (attr.match(/^on/i)) { + key = attr.slice(2).toLowerCase(); + eventsObj[key] = scope.$parent[attrs[attr]]; + } + } + chartConfigObject = { + type: attrs.type, + width: attrs.width, + height: attrs.height, + renderAt: element[0], + id: attrs.chartid, + dataFormat: attrs.dataformat || 'json', + dataSource: {}, + events: events + }; - for (observableAttr in observeConf.NDCObserver) { - attrConfig = observeConf.NDCObserver[observableAttr]; - if (attrConfig.ifExist === false || attrs[observableAttr]) { - attrs.$observe(observableAttr, attrConfig.observer); - } - } + for (observableAttr in observeConf.NDCObserver) { + attrConfig = observeConf.NDCObserver[observableAttr]; + if (attrConfig.ifExist === false || attrs[observableAttr]) { + attrs.$observe(observableAttr, attrConfig.observer); + } + } - if (attrs.datasource) { - chartConfigObject.dataSource = (chartConfigObject.dataFormat === 'json') ? JSON.parse(attrs.datasource) : attrs.datasource; - dataStringStore.dataSource = attrs.datasource; - } + console.log(attrs.datasource); - for (observableAttr in observeConf.DCObserver) { - attrConfig = observeConf.DCObserver[observableAttr]; - dataComponent = attrs[observableAttr]; - if (dataComponent) { - attrs.$observe(observableAttr, attrConfig.observer); - dataStringStore[observableAttr] = dataComponent; - if (chartConfigObject.dataFormat === 'json' && typeof chartConfigObject.dataSource === "object") { - chartConfigObject.dataSource[observableAttr] = JSON.parse(dataComponent); - } - } else if (attrConfig.ifExist === false) { - attrs.$observe(observableAttr, attrConfig.observer); - } - } + if (attrs.datasource) { + chartConfigObject.dataSource = + chartConfigObject.dataFormat === 'json' + ? JSON.parse(attrs.datasource) + : attrs.datasource; + dataStringStore.dataSource = attrs.datasource; + } - // add configurations from config - if (attrs.config) { - configObj = JSON.parse(attrs.config); - for (attr in configObj) { - chartConfigObject[attr] = configObj[attr]; - } - } + for (observableAttr in observeConf.DCObserver) { + attrConfig = observeConf.DCObserver[observableAttr]; + dataComponent = attrs[observableAttr]; + if (dataComponent) { + attrs.$observe(observableAttr, attrConfig.observer); + dataStringStore[observableAttr] = dataComponent; + if ( + chartConfigObject.dataFormat === 'json' && + typeof chartConfigObject.dataSource === 'object' + ) { + chartConfigObject.dataSource[observableAttr] = JSON.parse( + dataComponent + ); + } + } else if (attrConfig.ifExist === false) { + attrs.$observe(observableAttr, attrConfig.observer); + } + } + + // add configurations from config + if (attrs.config) { + configObj = JSON.parse(attrs.config); + for (attr in configObj) { + chartConfigObject[attr] = configObj[attr]; + } + } - createFCChart(); + createFCChart(); - scope.$on('$destroy', function () { - // on destroy free used resources to avoid memory leaks - if (chart && chart.dispose) { - chart.dispose(); - } - }); + scope.$on('$destroy', function() { + // on destroy free used resources to avoid memory leaks + if (chart && chart.dispose) { + chart.dispose(); } - }; - }]); -}()); + }); + } + }; + } + ]); +})();