diff --git a/angular-chart.js b/angular-chart.js index 9a3f267a..eee1f141 100644 --- a/angular-chart.js +++ b/angular-chart.js @@ -109,7 +109,9 @@ chartColors: '=?', chartClick: '=?', chartHover: '=?', - chartDatasetOverride: '=?' + chartDatasetOverride: '=?', + chartForceUpdate: '=?', + chartDisplayWhenNoData: '=?' }, link: function (scope, elem/*, attrs */) { if (useExcanvas) window.G_vmlCanvasManager.initElement(elem[0]); @@ -118,7 +120,7 @@ scope.$watch('chartData', watchData, true); scope.$watch('chartSeries', watchOther, true); scope.$watch('chartLabels', watchOther, true); - scope.$watch('chartOptions', watchOther, true); + scope.$watch('chartOptions', watchOptions, true); scope.$watch('chartColors', watchOther, true); scope.$watch('chartDatasetOverride', watchOther, true); scope.$watch('chartType', watchType, false); @@ -132,14 +134,14 @@ }); function watchData (newVal, oldVal) { - if (! newVal || ! newVal.length || (Array.isArray(newVal[0]) && ! newVal[0].length)) { + if (!scope.chartDisplayWhenNoData && (! newVal || ! newVal.length || (Array.isArray(newVal[0]) && ! newVal[0].length))) { destroyChart(scope); return; } var chartType = type || scope.chartType; if (! chartType) return; - if (scope.chart && canUpdateChart(newVal, oldVal)) + if (scope.chart && (canUpdateChart(newVal, oldVal) || scope.chartForceUpdate)) return updateChart(newVal, scope); createChart(chartType, scope, elem); @@ -156,6 +158,12 @@ createChart(chartType, scope, elem); } + function watchOptions (newVal, oldVal) { + if (isEmpty(newVal)) return; + if (angular.equals(newVal, oldVal)) return; + updateChartOption(newVal, scope) + } + function watchType (newVal, oldVal) { if (isEmpty(newVal)) return; if (angular.equals(newVal, oldVal)) return; @@ -167,7 +175,7 @@ function createChart (type, scope, elem) { var options = getChartOptions(type, scope); - if (! hasData(scope) || ! canDisplay(type, scope, elem, options)) return; + if (!scope.chartDisplayWhenNoData && (! hasData(scope) || ! canDisplay(type, scope, elem, options))) return; var cvs = elem[0]; var ctx = cvs.getContext('2d'); @@ -352,6 +360,18 @@ cvs.onmousemove = scope.chartHover ? getEventHandler(scope, 'chartHover', true) : angular.noop; } + function updateChartOption(values,scope) { + if (values) { + Object.keys(values).forEach((key) => { + if (scope.chart.options[key]) { + scope.chart.options[key] = values[key] + } + }) + scope.chart.update('quiet'); + scope.$emit('chart-update', scope.chart); + } + } + function updateChart (values, scope) { if (Array.isArray(scope.chartData[0])) { scope.chart.data.datasets.forEach(function (dataset, i) { diff --git a/bower.json b/bower.json index c4868566..8c6f0729 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "angular-chart.js", - "version": "1.1.1", + "version": "1.1.3", "main": [ "./dist/angular-chart.js" ], diff --git a/dist/angular-chart.js b/dist/angular-chart.js index 3a7d5bc8..eee1f141 100644 --- a/dist/angular-chart.js +++ b/dist/angular-chart.js @@ -1,12 +1,3 @@ -/*! - * angular-chart.js - An angular.js wrapper for Chart.js - * http://jtblin.github.io/angular-chart.js/ - * Version: 1.1.1 - * - * Copyright 2016 Jerome Touffe-Blin - * Released under the BSD-2-Clause license - * https://github.com/jtblin/angular-chart.js/blob/master/LICENSE - */ (function (factory) { 'use strict'; if (typeof exports === 'object') { @@ -118,7 +109,9 @@ chartColors: '=?', chartClick: '=?', chartHover: '=?', - chartDatasetOverride: '=?' + chartDatasetOverride: '=?', + chartForceUpdate: '=?', + chartDisplayWhenNoData: '=?' }, link: function (scope, elem/*, attrs */) { if (useExcanvas) window.G_vmlCanvasManager.initElement(elem[0]); @@ -127,7 +120,7 @@ scope.$watch('chartData', watchData, true); scope.$watch('chartSeries', watchOther, true); scope.$watch('chartLabels', watchOther, true); - scope.$watch('chartOptions', watchOther, true); + scope.$watch('chartOptions', watchOptions, true); scope.$watch('chartColors', watchOther, true); scope.$watch('chartDatasetOverride', watchOther, true); scope.$watch('chartType', watchType, false); @@ -141,14 +134,14 @@ }); function watchData (newVal, oldVal) { - if (! newVal || ! newVal.length || (Array.isArray(newVal[0]) && ! newVal[0].length)) { + if (!scope.chartDisplayWhenNoData && (! newVal || ! newVal.length || (Array.isArray(newVal[0]) && ! newVal[0].length))) { destroyChart(scope); return; } var chartType = type || scope.chartType; if (! chartType) return; - if (scope.chart && canUpdateChart(newVal, oldVal)) + if (scope.chart && (canUpdateChart(newVal, oldVal) || scope.chartForceUpdate)) return updateChart(newVal, scope); createChart(chartType, scope, elem); @@ -165,6 +158,12 @@ createChart(chartType, scope, elem); } + function watchOptions (newVal, oldVal) { + if (isEmpty(newVal)) return; + if (angular.equals(newVal, oldVal)) return; + updateChartOption(newVal, scope) + } + function watchType (newVal, oldVal) { if (isEmpty(newVal)) return; if (angular.equals(newVal, oldVal)) return; @@ -176,7 +175,7 @@ function createChart (type, scope, elem) { var options = getChartOptions(type, scope); - if (! hasData(scope) || ! canDisplay(type, scope, elem, options)) return; + if (!scope.chartDisplayWhenNoData && (! hasData(scope) || ! canDisplay(type, scope, elem, options))) return; var cvs = elem[0]; var ctx = cvs.getContext('2d'); @@ -361,6 +360,18 @@ cvs.onmousemove = scope.chartHover ? getEventHandler(scope, 'chartHover', true) : angular.noop; } + function updateChartOption(values,scope) { + if (values) { + Object.keys(values).forEach((key) => { + if (scope.chart.options[key]) { + scope.chart.options[key] = values[key] + } + }) + scope.chart.update('quiet'); + scope.$emit('chart-update', scope.chart); + } + } + function updateChart (values, scope) { if (Array.isArray(scope.chartData[0])) { scope.chart.data.datasets.forEach(function (dataset, i) { diff --git a/dist/angular-chart.min.js b/dist/angular-chart.min.js index 7e017db5..8edae0fb 100644 --- a/dist/angular-chart.min.js +++ b/dist/angular-chart.min.js @@ -1,11 +1 @@ -/*! - * angular-chart.js - An angular.js wrapper for Chart.js - * http://jtblin.github.io/angular-chart.js/ - * Version: 1.1.1 - * - * Copyright 2016 Jerome Touffe-Blin - * Released under the BSD-2-Clause license - * https://github.com/jtblin/angular-chart.js/blob/master/LICENSE - */ -!function(t){"use strict";if("object"==typeof exports)module.exports=t("undefined"!=typeof angular?angular:require("angular"),"undefined"!=typeof Chart?Chart:require("chart.js"));else if("function"==typeof define&&define.amd)define(["angular","chart"],t);else{if("undefined"==typeof angular)throw new Error("AngularJS framework needs to be included, see https://angularjs.org/");if("undefined"==typeof Chart)throw new Error("Chart.js library needs to be included, see http://jtblin.github.io/angular-chart.js/");t(angular,Chart)}}(function(t,r){"use strict";function e(){var e={responsive:!0},a={Chart:r,getOptions:function(r){var a=r&&e[r]||{};return t.extend({},e,a)}};this.setOptions=function(r,n){n?e[r]=t.merge(e[r]||{},n):(n=r,e=t.merge(e,n)),t.merge(a.Chart.defaults,e)},this.$get=function(){return a}}function a(e,a){function o(t,r,a){var n=D(t,r);if(C(r)&&k(t,r,a,n)){var o=a[0],c=o.getContext("2d");r.chartGetColor=y(r);var i=b(t,r);F(r),r.chart=new e.Chart(c,{type:t,data:i,options:n}),r.$emit("chart-create",r.chart),A(o,r)}}function c(t,r){return!!(t&&r&&t.length&&r.length)&&(Array.isArray(t[0])?t.length===r.length&&t.every(function(t,e){return t.length===r[e].length}):r.reduce(i,0)>0&&t.length===r.length)}function i(t,r){return t+r}function u(r,e,a){var n={point:void 0,points:void 0};return function(o){var c=r.chart.getElementAtEvent||r.chart.getPointAtEvent,i=r.chart.getElementsAtEvent||r.chart.getPointsAtEvent;if(i){var u=i.call(r.chart,o),l=c?c.call(r.chart,o)[0]:void 0;a!==!1&&(t.equals(n.points,u)||t.equals(n.point,l))||(n.point=l,n.points=u,r[e](u,o,l))}}}function l(a,n){for(var o=t.copy(n.chartColors||e.getOptions(a).chartColors||r.defaults.global.colors),c=o.length>16&255,a=r>>8&255,n=255&r;return[e,a,n]}function v(t){var r=t.match(/^rgba?\(([\d,.]+)\)$/);if(!r)throw new Error("Cannot parse rgb value");return t=r[1].split(","),t.map(Number)}function C(t){return t.chartData&&t.chartData.length}function y(t){return"function"==typeof t.chartGetColor?t.chartGetColor:s}function b(t,r){var e=l(t,r);return Array.isArray(r.chartData[0])?m(r.chartLabels,r.chartData,r.chartSeries||[],e,r.chartDatasetOverride):w(r.chartLabels,r.chartData,e,r.chartDatasetOverride)}function m(r,e,a,n,o){return{labels:r,datasets:e.map(function(r,e){var c=t.extend({},n[e],{label:a[e],data:r});return o&&o.length>=e&&t.merge(c,o[e]),c})}}function w(r,e,a,n){var o={labels:r,datasets:[{data:e,backgroundColor:a.map(function(t){return t.pointBackgroundColor}),hoverBackgroundColor:a.map(function(t){return t.backgroundColor})}]};return n&&t.merge(o.datasets[0],n),o}function D(r,a){return t.extend({},e.getOptions(r),a.chartOptions)}function A(r,e){r.onclick=e.chartClick?u(e,"chartClick",!1):t.noop,r.onmousemove=e.chartHover?u(e,"chartHover",!0):t.noop}function B(t,r){Array.isArray(r.chartData[0])?r.chart.data.datasets.forEach(function(r,e){r.data=t[e]}):r.chart.data.datasets[0].data=t,r.chart.update(),r.$emit("chart-update",r.chart)}function $(t){return!t||Array.isArray(t)&&!t.length||"object"==typeof t&&!Object.keys(t).length}function k(t,r,e,n){return!n.responsive||0!==e[0].clientHeight||(a(function(){o(t,r,e)},50,!1),!1)}function F(t){t.chart&&(t.chart.destroy(),t.$emit("chart-destroy",t.chart))}return function(r){return{restrict:"CA",scope:{chartGetColor:"=?",chartType:"=",chartData:"=?",chartLabels:"=?",chartOptions:"=?",chartSeries:"=?",chartColors:"=?",chartClick:"=?",chartHover:"=?",chartDatasetOverride:"=?"},link:function(e,a){function i(t,n){if(!t||!t.length||Array.isArray(t[0])&&!t[0].length)return void F(e);var i=r||e.chartType;if(i)return e.chart&&c(t,n)?B(t,e):void o(i,e,a)}function u(n,c){if(!$(n)&&!t.equals(n,c)){var i=r||e.chartType;i&&o(i,e,a)}}function l(r,n){$(r)||t.equals(r,n)||o(r,e,a)}n&&window.G_vmlCanvasManager.initElement(a[0]),e.$watch("chartData",i,!0),e.$watch("chartSeries",u,!0),e.$watch("chartLabels",u,!0),e.$watch("chartOptions",u,!0),e.$watch("chartColors",u,!0),e.$watch("chartDatasetOverride",u,!0),e.$watch("chartType",l,!1),e.$on("$destroy",function(){F(e)}),e.$on("$resize",function(){e.chart&&e.chart.resize()})}}}}r.defaults.global.multiTooltipTemplate="<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>",r.defaults.global.tooltips.mode="label",r.defaults.global.elements.line.borderWidth=2,r.defaults.global.elements.rectangle.borderWidth=2,r.defaults.global.legend.display=!1,r.defaults.global.colors=["#97BBCD","#DCDCDC","#F7464A","#46BFBD","#FDB45C","#949FB1","#4D5360"];var n="object"==typeof window.G_vmlCanvasManager&&null!==window.G_vmlCanvasManager&&"function"==typeof window.G_vmlCanvasManager.initElement;return n&&(r.defaults.global.animation=!1),t.module("chart.js",[]).provider("ChartJs",e).factory("ChartJsFactory",["ChartJs","$timeout",a]).directive("chartBase",["ChartJsFactory",function(t){return new t}]).directive("chartLine",["ChartJsFactory",function(t){return new t("line")}]).directive("chartBar",["ChartJsFactory",function(t){return new t("bar")}]).directive("chartHorizontalBar",["ChartJsFactory",function(t){return new t("horizontalBar")}]).directive("chartRadar",["ChartJsFactory",function(t){return new t("radar")}]).directive("chartDoughnut",["ChartJsFactory",function(t){return new t("doughnut")}]).directive("chartPie",["ChartJsFactory",function(t){return new t("pie")}]).directive("chartPolarArea",["ChartJsFactory",function(t){return new t("polarArea")}]).directive("chartBubble",["ChartJsFactory",function(t){return new t("bubble")}]).name}); -//# sourceMappingURL=angular-chart.min.js.map +!function(t){"use strict";if("object"==typeof exports)module.exports=t("undefined"!=typeof angular?angular:require("angular"),"undefined"!=typeof Chart?Chart:require("chart.js"));else if("function"==typeof define&&define.amd)define(["angular","chart"],t);else{if("undefined"==typeof angular)throw new Error("AngularJS framework needs to be included, see https://angularjs.org/");if("undefined"==typeof Chart)throw new Error("Chart.js library needs to be included, see http://jtblin.github.io/angular-chart.js/");t(angular,Chart)}}(function(g,C){"use strict";C.defaults.global.multiTooltipTemplate="<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>",C.defaults.global.tooltips.mode="label",C.defaults.global.elements.line.borderWidth=2,C.defaults.global.elements.rectangle.borderWidth=2,C.defaults.global.legend.display=!1,C.defaults.global.colors=["#97BBCD","#DCDCDC","#F7464A","#46BFBD","#FDB45C","#949FB1","#4D5360"];var v="object"==typeof window.G_vmlCanvasManager&&null!==window.G_vmlCanvasManager&&"function"==typeof window.G_vmlCanvasManager.initElement;return v&&(C.defaults.global.animation=!1),g.module("chart.js",[]).provider("ChartJs",function(){var a={responsive:!0},e={Chart:C,getOptions:function(t){t=t&&a[t]||{};return g.extend({},a,t)}};this.setOptions=function(t,r){r?a[t]=g.merge(a[t]||{},r):a=g.merge(a,r=t),g.merge(e.Chart.defaults,a)},this.$get=function(){return e}}).factory("ChartJsFactory",["ChartJs","$timeout",function(c,i){return function(o){return{restrict:"CA",scope:{chartGetColor:"=?",chartType:"=",chartData:"=?",chartLabels:"=?",chartOptions:"=?",chartSeries:"=?",chartColors:"=?",chartClick:"=?",chartHover:"=?",chartDatasetOverride:"=?",chartForceUpdate:"=?",chartDisplayWhenNoData:"=?"},link:function(e,n){function t(t,r){d(t)||g.equals(t,r)||(r=o||e.chartType)&&h(r,e,n)}v&&window.G_vmlCanvasManager.initElement(n[0]),e.$watch("chartData",function(t,r){if(e.chartDisplayWhenNoData||t&&t.length&&(!Array.isArray(t[0])||t[0].length)){var a=o||e.chartType;if(a)return e.chart&&(function(t,a){if(t&&a&&t.length&&a.length)return Array.isArray(t[0])?t.length===a.length&&t.every(function(t,r){return t.length===a[r].length}):0{a.chart.options[t]&&(a.chart.options[t]=r[t])}),a.chart.update("quiet"),a.$emit("chart-update",a.chart))}(t,e)},!0),e.$watch("chartColors",t,!0),e.$watch("chartDatasetOverride",t,!0),e.$watch("chartType",function(t,r){d(t)||g.equals(t,r)||h(t,e,n)},!1),e.$on("$destroy",function(){p(e)}),e.$on("$resize",function(){e.chart&&e.chart.resize()})}}};function h(t,r,a){var e,n,o=(n=r,g.extend({},c.getOptions(t),n.chartOptions));(r.chartDisplayWhenNoData||(e=r).chartData&&e.chartData.length&&function(t,r,a,e){if(e.responsive&&0===a[0].clientHeight)return i(function(){h(t,r,a)},50,!1),!1;return!0}(t,r,a,o))&&(e=(n=a[0]).getContext("2d"),r.chartGetColor="function"==typeof(a=r).chartGetColor?a.chartGetColor:f,a=function(t,r){t=function(t,r){var a=g.copy(r.chartColors||c.getOptions(t).chartColors||C.defaults.global.colors),t=a.length=r&&g.merge(t,n[r]),t})}}(r.chartLabels,r.chartData,r.chartSeries||[],t,r.chartDatasetOverride):function(t,r,a,e){a={labels:t,datasets:[{data:r,backgroundColor:a.map(function(t){return t.pointBackgroundColor}),hoverBackgroundColor:a.map(function(t){return t.backgroundColor})}]};e&&g.merge(a.datasets[0],e);return a}(r.chartLabels,r.chartData,t,r.chartDatasetOverride)}(t,r),p(r),r.chart=new c.Chart(e,{type:t,data:a,options:o}),r.$emit("chart-create",r.chart),r=r,(n=n).onclick=r.chartClick?l(r,"chartClick",!1):g.noop,n.onmousemove=r.chartHover?l(r,"chartHover",!0):g.noop)}function u(t,r){return t+r}function l(e,n,o){var c={point:void 0,points:void 0};return function(t){var r=e.chart.getElementAtEvent||e.chart.getPointAtEvent,a=e.chart.getElementsAtEvent||e.chart.getPointsAtEvent;a&&(a=a.call(e.chart,t),r=r?r.call(e.chart,t)[0]:void 0,!1!==o&&(g.equals(c.points,a)||g.equals(c.point,r))||(c.point=r,c.points=a,e[n](a,t,r)))}}function s(t){return"string"==typeof t&&"r"===t[0]?r(function(t){var r=t.match(/^rgba?\(([\d,.]+)\)$/);if(!r)throw new Error("Cannot parse rgb value");return(t=r[1].split(",")).map(Number)}(t)):"string"==typeof t&&"#"===t[0]?r(function(t){t=parseInt(t,16);return[t>>16&255,t>>8&255,255&t]}(t.substr(1))):"object"==typeof t&&null!==t?t:f()}function f(){return r([t(0,255),t(0,255),t(0,255)])}function r(t){var r=t[3]||1;return{backgroundColor:a(t=t.slice(0,3),.2),pointBackgroundColor:a(t,r),pointHoverBackgroundColor:a(t,.8),borderColor:a(t,r),pointBorderColor:"#fff",pointHoverBorderColor:a(t,r)}}function t(t,r){return Math.floor(Math.random()*(r-t+1))+t}function a(t,r){return v?"rgb("+t.join(",")+")":"rgba("+t.concat(r).join(",")+")"}function d(t){return!t||Array.isArray(t)&&!t.length||"object"==typeof t&&!Object.keys(t).length}function p(t){t.chart&&(t.chart.destroy(),t.$emit("chart-destroy",t.chart))}}]).directive("chartBase",["ChartJsFactory",function(t){return new t}]).directive("chartLine",["ChartJsFactory",function(t){return new t("line")}]).directive("chartBar",["ChartJsFactory",function(t){return new t("bar")}]).directive("chartHorizontalBar",["ChartJsFactory",function(t){return new t("horizontalBar")}]).directive("chartRadar",["ChartJsFactory",function(t){return new t("radar")}]).directive("chartDoughnut",["ChartJsFactory",function(t){return new t("doughnut")}]).directive("chartPie",["ChartJsFactory",function(t){return new t("pie")}]).directive("chartPolarArea",["ChartJsFactory",function(t){return new t("polarArea")}]).directive("chartBubble",["ChartJsFactory",function(t){return new t("bubble")}]).name}); \ No newline at end of file