Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

highcharts-ng

Package Overview
Dependencies
Maintainers
2
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

highcharts-ng - npm Package Compare versions

Comparing version 0.0.13 to 1.0.0

coverage/Chrome 55.0.2883 (Mac OS X 10.12.1)/base.css

535

dist/highcharts-ng.js
/**
* highcharts-ng
* @version v0.0.13 - 2016-10-04
* @version v1.0.0 - 2017-01-14
* @link https://github.com/pablojim/highcharts-ng

@@ -19,464 +19,125 @@ * @author Barry Fitzgerald <>

angular.module('highcharts-ng', [])
.factory('highchartsNG', ['$q', '$window', highchartsNG])
.directive('highchart', ['highchartsNG', '$timeout', highchart]);
.component('highchart', {
bindings: {
config: '<',
changeDetection: '<'
},
controller: HighChartNGController
});
//IE8 support
function indexOf(arr, find, i /*opt*/) {
if (i === undefined) i = 0;
if (i < 0) i += arr.length;
if (i < 0) i = 0;
for (var n = arr.length; i < n; i++)
if (i in arr && arr[i] === find)
return i;
return -1;
}
HighChartNGController.$inject = ['$element', '$timeout'];
function prependMethod(obj, method, func) {
var original = obj[method];
obj[method] = function () {
var args = Array.prototype.slice.call(arguments);
func.apply(this, args);
if (original) {
return original.apply(this, args);
} else {
return;
}
};
}
function deepExtend(destination, source) {
//Slightly strange behaviour in edge cases (e.g. passing in non objects)
//But does the job for current use cases.
if (angular.isArray(source)) {
destination = angular.isArray(destination) ? destination : [];
for (var i = 0; i < source.length; i++) {
destination[i] = deepExtend(destination[i] || {}, source[i]);
}
} else if (angular.isObject(source)) {
destination = angular.isObject(destination) ? destination : {};
for (var property in source) {
destination[property] = deepExtend(destination[property] || {}, source[property]);
}
} else {
destination = source;
}
return destination;
}
function highchartsNG($q, $window) {
var highchartsProm = $q.when($window.Highcharts);
function getHighchartsOnce() {
return highchartsProm;
}
return {
getHighcharts: getHighchartsOnce,
ready: function ready(callback, thisArg) {
getHighchartsOnce().then(function() {
callback.call(thisArg);
});
}
};
}
function highchart(highchartsNGUtils, $timeout) {
// acceptable shared state
function HighChartNGController($element, $timeout) {
var seriesId = 0;
var ensureIds = function (series) {
var changed = false;
angular.forEach(series, function(s) {
if (!angular.isDefined(s.id)) {
s.id = 'series-' + seriesId++;
changed = true;
}
});
return changed;
};
// immutable
var axisNames = [ 'xAxis', 'yAxis' ];
var chartTypeMap = {
'stock': 'StockChart',
'map': 'Map',
'chart': 'Chart'
};
var getMergedOptions = function (scope, element, config) {
var mergedOptions = {};
var defaultOptions = {
chart: {
events: {}
},
title: {},
subtitle: {},
series: [],
credits: {},
plotOptions: {},
navigator: {enabled: false},
xAxis: {
events: {}
},
yAxis: {
events: {}
}
var ctrl = this;
var prevConfig = {};
var mergedConfig = {};
var detector = ctrl.changeDetection || angular.equals;
this.$onInit = function() {
ctrl.config.getChartObj = function(){
return ctrl.chart;
};
if (config.options) {
mergedOptions = deepExtend(defaultOptions, config.options);
} else {
mergedOptions = defaultOptions;
}
mergedOptions.chart.renderTo = element[0];
angular.forEach(axisNames, function(axisName) {
if(angular.isDefined(config[axisName])) {
mergedOptions[axisName] = deepExtend(mergedOptions[axisName] || {}, config[axisName]);
if(angular.isDefined(config[axisName].currentMin) ||
angular.isDefined(config[axisName].currentMax)) {
prependMethod(mergedOptions.chart.events, 'selection', function(e){
var thisChart = this;
if (e[axisName]) {
scope.$apply(function () {
scope.config[axisName].currentMin = e[axisName][0].min;
scope.config[axisName].currentMax = e[axisName][0].max;
});
} else {
//handle reset button - zoom out to all
scope.$apply(function () {
scope.config[axisName].currentMin = thisChart[axisName][0].dataMin;
scope.config[axisName].currentMax = thisChart[axisName][0].dataMax;
});
}
});
prependMethod(mergedOptions.chart.events, 'addSeries', function(e){
scope.config[axisName].currentMin = this[axisName][0].min || scope.config[axisName].currentMin;
scope.config[axisName].currentMax = this[axisName][0].max || scope.config[axisName].currentMax;
});
prependMethod(mergedOptions[axisName].events, 'setExtremes', function (e) {
if (e.trigger && e.trigger !== 'zoom') { // zoom trigger is handled by selection event
$timeout(function () {
scope.config[axisName].currentMin = e.min;
scope.config[axisName].currentMax = e.max;
scope.config[axisName].min = e.min; // set min and max to adjust scrollbar/navigator
scope.config[axisName].max = e.max;
}, 0);
}
});
}
}
});
if(config.title) {
mergedOptions.title = config.title;
}
if (config.subtitle) {
mergedOptions.subtitle = config.subtitle;
}
if (config.credits) {
mergedOptions.credits = config.credits;
}
if(config.size) {
if (config.size.width) {
mergedOptions.chart.width = config.size.width;
}
if (config.size.height) {
mergedOptions.chart.height = config.size.height;
}
}
return mergedOptions;
prevConfig = angular.merge({}, ctrl.config);
mergedConfig = getMergedOptions($element, ctrl.config, seriesId);
ctrl.chart = new Highcharts[getChartType(mergedConfig)](mergedConfig);
};
var updateZoom = function (axis, modelAxis) {
var extremes = axis.getExtremes();
if(modelAxis.currentMin !== extremes.dataMin || modelAxis.currentMax !== extremes.dataMax) {
if (axis.setExtremes) {
axis.setExtremes(modelAxis.currentMin, modelAxis.currentMax, false);
} else {
axis.detachedsetExtremes(modelAxis.currentMin, modelAxis.currentMax, false);
}
}
};
var processExtremes = function(chart, axis, axisName) {
if(axis.currentMin || axis.currentMax) {
chart[axisName][0].setExtremes(axis.currentMin, axis.currentMax, true);
}
};
var chartOptionsWithoutEasyOptions = function (options) {
return angular.extend(
deepExtend({}, options),
{ data: null, visible: null }
);
};
var getChartType = function(scope) {
if (scope.config === undefined) return 'Chart';
return chartTypeMap[('' + scope.config.chartType).toLowerCase()] ||
(scope.config.useHighStocks ? 'StockChart' : 'Chart');
};
function linkWithHighcharts(Highcharts, scope, element, attrs) {
// We keep some chart-specific variables here as a closure
// instead of storing them on 'scope'.
// prevSeriesOptions is maintained by processSeries
var prevSeriesOptions = {};
// chart is maintained by initChart
var chart = false;
var processSeries = function(series, seriesOld) {
var i;
var ids = [];
if(series) {
var setIds = ensureIds(series);
if(setIds && !scope.disableDataWatch) {
//If we have set some ids this will trigger another digest cycle.
//In this scenario just return early and let the next cycle take care of changes
return false;
this.$doCheck = function() {
if(!detector(ctrl.config, prevConfig)) {
prevConfig = angular.merge({}, ctrl.config);
mergedConfig = getMergedOptions($element, ctrl.config, seriesId);
var ids = ensureIds(mergedConfig.series, seriesId);
if (mergedConfig.series) {
//Remove any missing series
for (var i = ctrl.chart.series.length - 1; i >= 0; i--) {
var s = ctrl.chart.series[i];
if (s.options.id !== 'highcharts-navigator-series' && ids.indexOf(s.options.id) < 0) {
s.remove(false);
}
}
//Find series to add or update
angular.forEach(series, function(s, idx) {
ids.push(s.id);
var chartSeries = chart.get(s.id);
if (chartSeries) {
if (!angular.equals(prevSeriesOptions[s.id], chartOptionsWithoutEasyOptions(s))) {
chartSeries.update(angular.copy(s), false);
} else {
if (s.visible !== undefined && chartSeries.visible !== s.visible) {
chartSeries.setVisible(s.visible, false);
}
// Make sure the current series index can be accessed in seriesOld
if (idx < seriesOld.length) {
var sOld = seriesOld[idx];
var sCopy = angular.copy(sOld);
// Get the latest data point from the new series
var ptNew = s.data[s.data.length - 1];
// Check if the new and old series are identical with the latest data point added
// If so, call addPoint without shifting
sCopy.data.push(ptNew);
if (angular.equals(sCopy, s)) {
chartSeries.addPoint(ptNew, false);
}
// Check if the data change was a push and shift operation
// If so, call addPoint WITH shifting
else {
sCopy.data.shift();
if (angular.equals(sCopy, s)) {
chartSeries.addPoint(ptNew, false, true);
}
else {
chartSeries.setData(angular.copy(s.data), false);
}
}
}
else {
chartSeries.setData(angular.copy(s.data), false);
}
}
} else {
chart.addSeries(angular.copy(s), false);
// Add any new series
angular.forEach(ctrl.config.series, function(s) {
if (!ctrl.chart.get(s.id)) {
ctrl.chart.addSeries(s);
}
prevSeriesOptions[s.id] = chartOptionsWithoutEasyOptions(s);
});
// Shows no data text if all series are empty
if(scope.config.noData) {
var chartContainsData = false;
for(i = 0; i < series.length; i++) {
if (series[i].data && series[i].data.length > 0) {
chartContainsData = true;
break;
}
}
if (!chartContainsData) {
chart.showLoading(scope.config.noData);
} else {
chart.hideLoading();
}
}
}
ctrl.chart.update(mergedConfig, true);
}
};
//Now remove any missing series
for(i = chart.series.length - 1; i >= 0; i--) {
var s = chart.series[i];
if (s.options.id !== 'highcharts-navigator-series' && indexOf(ids, s.options.id) < 0) {
s.remove(false);
this.$onDestroy = function() {
if (ctrl.chart) {
try{
ctrl.chart.destroy();
}catch(ex){
// fail silently as highcharts will throw exception if element doesn't exist
}
}
return true;
};
var initChart = function() {
if (chart) chart.destroy();
prevSeriesOptions = {};
var config = scope.config || {};
var mergedOptions = getMergedOptions(scope, element, config);
var func = config.func || undefined;
var chartType = getChartType(scope);
chart = new Highcharts[chartType](mergedOptions, func);
for (var i = 0; i < axisNames.length; i++) {
if (config[axisNames[i]]) {
processExtremes(chart, config[axisNames[i]], axisNames[i]);
}
$timeout(function(){
$element.remove();
}, 0);
}
if(config.loading) {
chart.showLoading();
}
config.getHighcharts = function() {
return chart;
};
};
initChart();
}
function getMergedOptions(element, config, seriesId) {
var mergedOptions = {};
if(scope.disableDataWatch){
scope.$watchCollection('config.series', function (newSeries, oldSeries) {
processSeries(newSeries);
chart.redraw();
});
} else {
scope.$watch('config.series', function (newSeries, oldSeries) {
var needsRedraw = processSeries(newSeries, oldSeries);
if(needsRedraw) {
chart.redraw();
}
}, true);
var defaultOptions = {
chart: {
events: {}
},
title: {},
subtitle: {},
series: [],
credits: {},
plotOptions: {},
navigator: {},
xAxis: {
events: {}
},
yAxis: {
events: {}
}
};
scope.$watch('config.title', function (newTitle) {
chart.setTitle(newTitle, true);
}, true);
if (config) {
//check all series and axis ids are set
if(config.series) {
ensureIds(config.series, seriesId);
}
scope.$watch('config.subtitle', function (newSubtitle) {
chart.setTitle(true, newSubtitle);
}, true);
mergedOptions = angular.merge(defaultOptions, config);
} else {
mergedOptions = defaultOptions;
}
mergedOptions.chart.renderTo = element[0];
scope.$watch('config.loading', function (loading) {
if(loading) {
chart.showLoading(loading === true ? null : loading);
} else {
chart.hideLoading();
}
});
scope.$watch('config.noData', function (noData) {
if(scope.config && scope.config.loading) {
chart.showLoading(noData);
}
}, true);
//check chart type is set
return mergedOptions;
}
scope.$watch('config.credits.enabled', function (enabled) {
if (enabled) {
chart.credits.show();
} else if (chart.credits) {
chart.credits.hide();
}
});
var chartTypeMap = {
'stock': 'StockChart',
'map': 'Map',
'chart': 'Chart'
};
scope.$watch(getChartType, function (chartType, oldChartType) {
if (chartType === oldChartType) return;
initChart();
});
function getChartType(config) {
if (config === undefined || config.chartType === undefined) return 'Chart';
return chartTypeMap[('' + config.chartType).toLowerCase()];
}
angular.forEach(axisNames, function(axisName) {
scope.$watch('config.' + axisName, function(newAxes) {
if (!newAxes) {
return;
}
if (angular.isArray(newAxes)) {
for (var axisIndex = 0; axisIndex < newAxes.length; axisIndex++) {
var axis = newAxes[axisIndex];
if (axisIndex < chart[axisName].length) {
chart[axisName][axisIndex].update(axis, false);
updateZoom(chart[axisName][axisIndex], angular.copy(axis));
}
}
} else {
// update single axis
chart[axisName][0].update(newAxes, false);
updateZoom(chart[axisName][0], angular.copy(newAxes));
}
chart.redraw();
}, true);
});
scope.$watch('config.options', function (newOptions, oldOptions, scope) {
//do nothing when called on registration
if (newOptions === oldOptions) return;
initChart();
processSeries(scope.config.series);
chart.redraw();
}, true);
scope.$watch('config.size', function (newSize, oldSize) {
if(newSize === oldSize) return;
if(newSize) {
chart.setSize(newSize.width || chart.chartWidth, newSize.height || chart.chartHeight);
}
}, true);
scope.$on('highchartsng.reflow', function () {
chart.reflow();
});
scope.$on('$destroy', function() {
if (chart) {
try{
chart.destroy();
}catch(ex){
// fail silently as highcharts will throw exception if element doesn't exist
}
$timeout(function(){
element.remove();
}, 0);
}
});
}
function link(scope, element, attrs) {
function highchartsCb(Highcharts) {
linkWithHighcharts(Highcharts, scope, element, attrs);
function ensureIds(series, seriesId) {
var ids = [];
angular.forEach(series, function(s) {
if (!angular.isDefined(s.id)) {
s.id = 'series-' + seriesId++;
}
highchartsNGUtils
.getHighcharts()
.then(highchartsCb);
}
ids.push(s.id);
});
return ids;
}
return {
restrict: 'EAC',
replace: true,
template: '<div></div>',
scope: {
config: '=',
disableDataWatch: '='
},
link: link
};
}
}());
/**
* highcharts-ng
* @version v0.0.13 - 2016-10-04
* @version v1.0.0 - 2017-01-14
* @link https://github.com/pablojim/highcharts-ng

@@ -8,2 +8,2 @@ * @author Barry Fitzgerald <>

*/
"undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports="highcharts-ng"),function(){"use strict";function a(a,b,c){void 0===c&&(c=0),c<0&&(c+=a.length),c<0&&(c=0);for(var d=a.length;c<d;c++)if(c in a&&a[c]===b)return c;return-1}function b(a,b,c){var d=a[b];a[b]=function(){var a=Array.prototype.slice.call(arguments);return c.apply(this,a),d?d.apply(this,a):void 0}}function c(a,b){if(angular.isArray(b)){a=angular.isArray(a)?a:[];for(var d=0;d<b.length;d++)a[d]=c(a[d]||{},b[d])}else if(angular.isObject(b)){a=angular.isObject(a)?a:{};for(var e in b)a[e]=c(a[e]||{},b[e])}else a=b;return a}function d(a,b){function c(){return d}var d=a.when(b.Highcharts);return{getHighcharts:c,ready:function(a,b){c().then(function(){a.call(b)})}}}function e(d,e){function f(b,c,d,f){var g={},h=!1,k=function(b,d){var e,f=[];if(b){var j=i(b);if(j&&!c.disableDataWatch)return!1;if(angular.forEach(b,function(a,b){f.push(a.id);var c=h.get(a.id);if(c)if(angular.equals(g[a.id],o(a)))if(void 0!==a.visible&&c.visible!==a.visible&&c.setVisible(a.visible,!1),b<d.length){var e=d[b],i=angular.copy(e),j=a.data[a.data.length-1];i.data.push(j),angular.equals(i,a)?c.addPoint(j,!1):(i.data.shift(),angular.equals(i,a)?c.addPoint(j,!1,!0):c.setData(angular.copy(a.data),!1))}else c.setData(angular.copy(a.data),!1);else c.update(angular.copy(a),!1);else h.addSeries(angular.copy(a),!1);g[a.id]=o(a)}),c.config.noData){var k=!1;for(e=0;e<b.length;e++)if(b[e].data&&b[e].data.length>0){k=!0;break}k?h.hideLoading():h.showLoading(c.config.noData)}}for(e=h.series.length-1;e>=0;e--){var l=h.series[e];"highcharts-navigator-series"!==l.options.id&&a(f,l.options.id)<0&&l.remove(!1)}return!0},q=function(){h&&h.destroy(),g={};var a=c.config||{},e=l(c,d,a),f=a.func||void 0,i=p(c);h=new b[i](e,f);for(var k=0;k<j.length;k++)a[j[k]]&&n(h,a[j[k]],j[k]);a.loading&&h.showLoading(),a.getHighcharts=function(){return h}};q(),c.disableDataWatch?c.$watchCollection("config.series",function(a,b){k(a),h.redraw()}):c.$watch("config.series",function(a,b){var c=k(a,b);c&&h.redraw()},!0),c.$watch("config.title",function(a){h.setTitle(a,!0)},!0),c.$watch("config.subtitle",function(a){h.setTitle(!0,a)},!0),c.$watch("config.loading",function(a){a?h.showLoading(a===!0?null:a):h.hideLoading()}),c.$watch("config.noData",function(a){c.config&&c.config.loading&&h.showLoading(a)},!0),c.$watch("config.credits.enabled",function(a){a?h.credits.show():h.credits&&h.credits.hide()}),c.$watch(p,function(a,b){a!==b&&q()}),angular.forEach(j,function(a){c.$watch("config."+a,function(b){if(b){if(angular.isArray(b))for(var c=0;c<b.length;c++){var d=b[c];c<h[a].length&&(h[a][c].update(d,!1),m(h[a][c],angular.copy(d)))}else h[a][0].update(b,!1),m(h[a][0],angular.copy(b));h.redraw()}},!0)}),c.$watch("config.options",function(a,b,c){a!==b&&(q(),k(c.config.series),h.redraw())},!0),c.$watch("config.size",function(a,b){a!==b&&a&&h.setSize(a.width||h.chartWidth,a.height||h.chartHeight)},!0),c.$on("highchartsng.reflow",function(){h.reflow()}),c.$on("$destroy",function(){if(h){try{h.destroy()}catch(a){}e(function(){d.remove()},0)}})}function g(a,b,c){function e(d){f(d,a,b,c)}d.getHighcharts().then(e)}var h=0,i=function(a){var b=!1;return angular.forEach(a,function(a){angular.isDefined(a.id)||(a.id="series-"+h++,b=!0)}),b},j=["xAxis","yAxis"],k={stock:"StockChart",map:"Map",chart:"Chart"},l=function(a,d,f){var g={},h={chart:{events:{}},title:{},subtitle:{},series:[],credits:{},plotOptions:{},navigator:{enabled:!1},xAxis:{events:{}},yAxis:{events:{}}};return g=f.options?c(h,f.options):h,g.chart.renderTo=d[0],angular.forEach(j,function(d){angular.isDefined(f[d])&&(g[d]=c(g[d]||{},f[d]),(angular.isDefined(f[d].currentMin)||angular.isDefined(f[d].currentMax))&&(b(g.chart.events,"selection",function(b){var c=this;b[d]?a.$apply(function(){a.config[d].currentMin=b[d][0].min,a.config[d].currentMax=b[d][0].max}):a.$apply(function(){a.config[d].currentMin=c[d][0].dataMin,a.config[d].currentMax=c[d][0].dataMax})}),b(g.chart.events,"addSeries",function(b){a.config[d].currentMin=this[d][0].min||a.config[d].currentMin,a.config[d].currentMax=this[d][0].max||a.config[d].currentMax}),b(g[d].events,"setExtremes",function(b){b.trigger&&"zoom"!==b.trigger&&e(function(){a.config[d].currentMin=b.min,a.config[d].currentMax=b.max,a.config[d].min=b.min,a.config[d].max=b.max},0)})))}),f.title&&(g.title=f.title),f.subtitle&&(g.subtitle=f.subtitle),f.credits&&(g.credits=f.credits),f.size&&(f.size.width&&(g.chart.width=f.size.width),f.size.height&&(g.chart.height=f.size.height)),g},m=function(a,b){var c=a.getExtremes();b.currentMin===c.dataMin&&b.currentMax===c.dataMax||(a.setExtremes?a.setExtremes(b.currentMin,b.currentMax,!1):a.detachedsetExtremes(b.currentMin,b.currentMax,!1))},n=function(a,b,c){(b.currentMin||b.currentMax)&&a[c][0].setExtremes(b.currentMin,b.currentMax,!0)},o=function(a){return angular.extend(c({},a),{data:null,visible:null})},p=function(a){return void 0===a.config?"Chart":k[(""+a.config.chartType).toLowerCase()]||(a.config.useHighStocks?"StockChart":"Chart")};return{restrict:"EAC",replace:!0,template:"<div></div>",scope:{config:"=",disableDataWatch:"="},link:g}}angular.module("highcharts-ng",[]).factory("highchartsNG",["$q","$window",d]).directive("highchart",["highchartsNG","$timeout",e])}();
"undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports="highcharts-ng"),function(){"use strict";function a(a,e){var f=0,g=this,h={},i={},j=g.changeDetection||angular.equals;this.$onInit=function(){g.config.getChartObj=function(){return g.chart},h=angular.merge({},g.config),i=b(a,g.config,f),g.chart=new(Highcharts[c(i)])(i)},this.$doCheck=function(){if(!j(g.config,h)){h=angular.merge({},g.config),i=b(a,g.config,f);var c=d(i.series,f);if(i.series){for(var e=g.chart.series.length-1;e>=0;e--){var k=g.chart.series[e];"highcharts-navigator-series"!==k.options.id&&c.indexOf(k.options.id)<0&&k.remove(!1)}angular.forEach(g.config.series,function(a){g.chart.get(a.id)||g.chart.addSeries(a)})}g.chart.update(i,!0)}},this.$onDestroy=function(){if(g.chart){try{g.chart.destroy()}catch(b){}e(function(){a.remove()},0)}}}function b(a,b,c){var e={},f={chart:{events:{}},title:{},subtitle:{},series:[],credits:{},plotOptions:{},navigator:{},xAxis:{events:{}},yAxis:{events:{}}};return b?(b.series&&d(b.series,c),e=angular.merge(f,b)):e=f,e.chart.renderTo=a[0],e}function c(a){return void 0===a||void 0===a.chartType?"Chart":e[(""+a.chartType).toLowerCase()]}function d(a,b){var c=[];return angular.forEach(a,function(a){angular.isDefined(a.id)||(a.id="series-"+b++),c.push(a.id)}),c}angular.module("highcharts-ng",[]).component("highchart",{bindings:{config:"<",changeDetection:"<"},controller:a}),a.$inject=["$element","$timeout"];var e={stock:"StockChart",map:"Map",chart:"Chart"}}();
{
"name": "highcharts-ng",
"version": "0.0.13",
"version": "1.0.0",
"description": "highcharts-ng",

@@ -5,0 +5,0 @@ "keywords": [

@@ -10,5 +10,12 @@ highcharts-ng

Current Version (0.0.12)
------------------------
Basic jsfiddle: http://jsfiddle.net/pablojim/LnkgL135/
See example in ./example/charts/general-example.html (Also served here: https://rawgit.com/pablojim/highcharts-ng/master/example/charts/general-example.html)
Current Version (1.0.0)
-----------------------
**Note Needs Highcharts/Highstock >= 5.0.0**
**Only supports AngularJS >= 1.5**
**Configuration Format is not compatible with highcharts-ng 0.x.0**
**Setup:**

@@ -22,2 +29,9 @@

or with bower:
```bash
bower install highcharts-ng --save
```
Add references to Highcharts/Highstocks:

@@ -47,70 +61,9 @@

__Warning__: The `chartConfig` object is _slightly different_ than the default Highcharts config object. ( _Please see the FAQ below for details_ )
The `chartConfig` object should be the same as a normal highcharts configuration. Any options that work in highcharts should work here also.
- See http://pablojim.github.io/highcharts-ng/examples/example.html for an extended example. Also Available in the example directory - thanks @crusat
- Basic example: http://jsfiddle.net/pablojim/Hjdnw/
- Example with dynamic x-axis: http://jsfiddle.net/pablojim/7cAq3/
- Basic Highstocks example http://jsfiddle.net/pablojim/r88yszk0/
- Support for Highmaps - see: http://rawgit.com/pablojim/highcharts-ng/master/example/maps/example.html
- Getting access to the Chart object/Add a print button - http://jsfiddle.net/pablojim/m4pcpv5g/
It is **Highly Recommended** to give all Series and Axes a distinct ID.
The `chartConfig` attribute mentioned above resembles an exploded Highcharts options object:
```javascript
//This is not a highcharts object. It just looks a little like one!
var chartConfig = {
options: {
//This is the Main Highcharts chart config. Any Highchart options are valid here.
//will be overriden by values specified below.
chart: {
type: 'bar'
},
tooltip: {
style: {
padding: 10,
fontWeight: 'bold'
}
}
},
//The below properties are watched separately for changes.
//Series object (optional) - a list of series using normal Highcharts series options.
series: [{
data: [10, 15, 12, 8, 7]
}],
//Title configuration (optional)
title: {
text: 'Hello'
},
//Boolean to control showing loading status on chart (optional)
//Could be a string if you want to show specific loading text.
loading: false,
//Configuration for the xAxis (optional). Currently only one x axis can be dynamically controlled.
//properties currentMin and currentMax provided 2-way binding to the chart's maximum and minimum
xAxis: {
currentMin: 0,
currentMax: 20,
title: {text: 'values'}
},
//Whether to use Highstocks instead of Highcharts (optional). Defaults to false.
useHighStocks: false,
//size (optional) if left out the chart will default to size of the div or something sensible.
size: {
width: 400,
height: 300
},
//function (optional)
func: function (chart) {
//setup some logic for the chart
}
};
```
All properties on the chart configuration are optional. If you don't need a feature best to leave it out completely - Highcharts will usually default to something sensible. Each property is watched for changes by angularjs.
NOTE:
A common error is to put other Highcharts options directly into the chartConfig.
In general if the Highcharts option you want isn't listed above you probably want to put it in chartConfig.options
The Highcharts object can be accessed with ```chartConfig.getHighcharts()```. This is a simple way to access all the Highcharts API that is not currently managed by this directive. See the JSFiddle basic example to see how this is used to call the print function of Highcharts.
After construction the Highcharts Chart object can be accessed with ```chartConfig.getChartObj()```. This is a simple way to access all the Highcharts API that is not currently managed by this directive. See the JSFiddle basic example to see how this is used to call the print function of Highcharts.

@@ -123,17 +76,20 @@ Features:

- Updating the chart title
- 2 way binding to chart xAxis
- Control of Loading status
- Resizes with screen size changes.
- Providing a custom changeDetection function or expression - for speed a custom changeDetection function can be provided to save dirty checking the full chart config.
Features Not Supported that were previously supported:
------------------------------------------------------
- 2 way binding to chart xAxis. (use chartConfig.getChartObj() to get axis values)
- Control of Loading status though the config (use chartConfig.getChartObj() to get axis values)
Both of these should be possible to add with the right PR
- Use of add and remove points on dynamically updated series
Caveats:
--------
- Due to many equality checks the directive maybe slow with large datasets
- Due to many equality checks the directive maybe slow with large datasets - try using changeDetection instead
- Whole Chart/Series is often redrawn where a simple update of data would suffice
- If you don't assign ids to your series - incremental ids will be added
- The 2 way binding to xAxis properties should be treated as experimental
- Navigator/scrollbar cannot run with liveRedraw enabled at this time
- Highcharts <=3 requires jQuery or ```<script src="http://code.highcharts.com/3/adapters/standalone-framework.js"></script>```
- Needs tests!
- If you don't assign ids to your series - incremental ids will be added. This may mean extra redraws.
- Needs more tests!

@@ -144,11 +100,10 @@ FAQ:

- Why doesn't my plot options/tooltip/drilldown/other feature work?
- Whats different to previous 0.0.X versions?
*At least half of all issues filed are due to this. Before you file an issue read this!*
A common error is to put other Highcharts options directly into the chartConfig.
In general if the Highcharts option you want isn't listed above you probably want to put it in chartConfig.options.
This version is much much simpler and should be more stable. Some features however are still to be implemented
e.g. 2-way binding to axes and loading functionality
- How do I get access to the chart object?
From version 0.0.8 onwards you can use `config.getHighcharts`. 95% of the time you won't need this and should instead change the chartConfig instead.
You can use `config.getChartObj`. 95% of the time you should not need this and should instead change the chartConfig instead.

@@ -159,83 +114,19 @@ Be careful - if you manually change something with the chart object that is also in the chartConfig the chart and the config may end up out of sync.

Let's consider the below snippet.
Since 0.1.0, vanilla Highcharts objects are supported!
```javascript
$scope.chartConfig = {
options: {...}, //Highcharts options - using standard Highcharts config
//other "dynamic" options
title: {...}
series [...]
}
```
In the ```chartConfig``` object above the ```options``` property is a standard Highcharts options object. e.g. anything you can pass into ````new Highcharts.Chart(options);``` works here.
This options object is watched for changes. When something changes here the whole chart is recreated.
The other dynamic properties are ones that we can change without affecting the whole chart - using the API at http://api.highcharts.com/highcharts#Chart e.g. if you change the title we can call chart.setTitle and not have to recreate the whole chart. Splitting them out from the main options object means we can watch them separately.
So anything that has an API to change is declared outside the main options object.
Hope this makes sense!
- The chart does not fit into the parent container? How to fix that?
This may happen for example, when you place your chart in a bootstrap col - element. For now, you may apply the following workaround to fit your chart in the container:
```javascript
$scope.config = {
options: {
...
},
...
// other configuration here,
...
func: function(chart) {
$timeout(function() {
chart.reflow();
}, 0);
}
};
}
```
This forces the chart to reflow after container and chart have finished rendering. Don't forget to include the dependency to $timeout. Full discussion in https://github.com/pablojim/highcharts-ng/issues/300.
Lazy loading
------------
If you used to use the lazyload feature, this has been moved to a separate
module. It is recommended to use a module loader such as Webpack or browserify
instead.
```html
<script src="path/to/highcharts-ng/dist/lazyload.js"></script>
```
```javascript
var app = angular.module('myapp', ["highcharts-ng-lazyload"])
.config(['highchartsNGProvider', function (highchartsNGProvider) {
// will load highcharts (and standalone framework if jquery is not present) from code.highcharts.com
highchartsNGProvider.lazyLoad();
highchartsNGProvider.lazyLoad([
highchartsNGProvider.HIGHCHART, // or HIGHSTOCK,
// you may add any additional modules and they will be loaded in the same sequence
"maps/modules/map.js",
"mapdata/custom/world.js",
]);
highchartsNGProvider.basePath("/js/"); // change base path for scripts, default is http(s)://code.highcharts.com/
}])
.controller(["highchartsNG", function(highchartsNG){
// do anything you like
// ...
highchartsNG.getHighcharts().then(function(Highcharts){
// init chart config, see lazyload example
});
});
```
Versions
--------------
Version 1.0.0
-------------
- only support Highchart/Highstock >= 5.0.0
- only support AngularJS >= 1.5 (see https://github.com/toddmotto/angular-component for lower versions)
- Move to AngularJS Component
- Now supports vanilla Highcharts config
- Supports custom change detection functions
- Should be much more stable and less bugs
- 2 way axes binding no longer supported
- loading property no longer supported

@@ -277,3 +168,2 @@ Version 0.0.13

Version 0.0.6

@@ -286,3 +176,2 @@ ----------------

Version 0.0.5

@@ -293,3 +182,2 @@ ----------------

Version 0.0.4

@@ -310,3 +198,2 @@ ----------------

Version 0.0.1 (not compatible with current version)

@@ -313,0 +200,0 @@ ----------------

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc