Reputation: 1573
in highcharts javascript file line number 1126 there is a function addEvent
/**
* Add an event listener
* @param {Object} el A HTML element or custom object
* @param {String} event The event type
* @param {Function} fn The event handler
*/
addEvent: function (el, event, fn) {
$(el).bind(event, fn);
},
I want to call my custom function instead of default function, and at the same time i don't want to change highcharts.js.
I want to assign it through external function, is there any way I can achieve this??
my new code will be
addEvent: function (el, event, fn) {
if(typeof(fn)=="string"){
try {
eval(fn);
} catch (e) {
if (e instanceof SyntaxError) {
console.log(e.message);
}
}
}
$(el).bind(event, fn);
}
Upvotes: 3
Views: 3467
Reputation: 61
Use DOM events easily in a way compatible with all browsers. Here is the experience ...
Create your function, for example mouseup ...
var MeObjectDOM_mouseup = function(){
Me blabla code....
}
Create your event now ...
if(MeObjectDOM.addEventListener){
MeObjectDOM.addEventListener("mouseup", MeObjectDOM_mouseup ,true);
}else if(MeObjectDOM.attachEvent){
MeObjectDOM.attachEvent("mouseup", MeObjectDOM_mouseup);
}else{
MeObjectDOM['onmouseup'] = MeObjectDOM_mouseup;
};
Your event is now compatible with IE, NETSCAPE, CHROME, EDGE, OPERA, FIREFOX, SAFARI, even older versions like Safari 5 or IE 5, 6 and Netscape 4 (^__^).
Upvotes: 0
Reputation: 1662
Notice these lines of code in highcharts.js:
// check for a custom HighchartsAdapter defined prior to this file
var globalAdapter = win.HighchartsAdapter,
adapter = globalAdapter || {};
// Initialize the adapter
if (globalAdapter) {
globalAdapter.init.call(globalAdapter, pathAnim);
}
// Utility functions. If the HighchartsAdapter is not defined, adapter is an empty object
// and all the utility functions will be null. In that case they are populated by the
// default adapters below.
Since addEvent
is specified in window.HighchartsAdapter
, you will need to create a custom HighchartsAdapter
to override it. There is an example of a custom highcharts adapter on github.
Upvotes: 0
Reputation: 11936
Modifying Highcharts.addEvent
with Highcharts.wrap()
doesn't work because Highcharts saves an internal reference to addEvent
. Changing the external Highcharts.addEvent
has no effect on the internal reference.
Tracing the code backwards a bit, you'll find that addEvent
comes from window.HighchartsAdapter
. Highcharts can be made to work with other JavaScript frameworks by loading the appropriate adapter, which overrides the default window.HighchartsAdapter
with a version that works with the particular framework.
To modify addEvent
on the default adapter before Highcharts saves an internal reference, we can load the main JS file twice: (demo)
<script src="http://code.highcharts.com/highcharts.js"></script>
<script>
// Highcharts detects if it has been loaded more than once
// and throws an error to alert developers
// We work around this by unsetting the Highcharts object
window.Highcharts = null;
window.HighchartsAdapter.addEvent = function (el, event, fn) {
// add your custom code here
$(el).bind(event, fn);
};
</script>
<script src="http://code.highcharts.com/highcharts.js"></script>
This will cause a second HTTP request to be made for the JS file, but it should return a 304 response as the browser should already have cached the file from the first request.
While this may work for now, monkey-patching someone else's code isn't the best way to proceed in the long term, e.g. you or another developer may decide to upgrade to the latest version of Highcharts (with a completely different internal API) a year from now, without realizing / remembering this change. I'd consider other ways to do what you're trying to do before resorting to monkey patching.
Upvotes: 0
Reputation: 7095
It's not possible to reproduce the effect of modifying the source code for addEvent
at line 1126 by using the wrap utility, because for reasons I don't fully understand, the wrap is not applied to numerous internal calls made to addEvent
including those triggered as a result of the events specified in the initial configuration, such as yours under plotOptions/series/point/events.
However the wrap is applied to events when added like this:
(function (H) {
Highcharts.Chart.prototype.callbacks.push(function (chart) {
H.addEvent(chart.container, 'click', function() { alert('click!') });
});
}(Highcharts));
or as in your case, adding a function as a string to a point event:
(function (H) {
Highcharts.Chart.prototype.callbacks.push(function (chart) {
H.addEvent(chart.series[0].data, 'click', "(function() { alert (this.y);})");
});
}(Highcharts));
so your wrap function could deal with both of these like so:
(function (H) {
H.wrap(H, "addEvent", function (addEvent, el, event, fn) {
if (typeof fn == "string") {
try {
var evalfn = eval(fn);
addEvent(el, event, evalfn);
} catch (e) {
if (e instanceof SyntaxError) {
console.log(e.message);
}
}
} else {
addEvent(el, event, fn);
}
});
})(Highcharts);
which I grant is not quite what you asked, but may offer an alternative solution for what you are trying to achieve.
Demo of all this here: http://jsfiddle.net/8wRAs/
Upvotes: 0
Reputation: 45079
Unfortuantely I don't know why wrapping addEvent doesn't work (while should!), but you can overwrite or wrap importEvents for point, to do similar thing (but only for points):
(function (H) {
H.wrap(H.Point.prototype, 'importEvents', function () {
if (!this.hasImportedEvents) {
var point = this,
options = H.merge(point.series.options.point, point.options),
events = options.events,
eventType;
point.events = events;
for (eventType in events) {
if (typeof events[eventType] == "string") {
try {
events[eventType] = eval(events[eventType]);
} catch (e) {
if (e instanceof SyntaxError) {
console.log(e.message);
}
}
}
H.addEvent(point, eventType, events[eventType]);
this.hasImportedEvents = true;
}
}
});
}(Highcharts));
Demo: http://jsfiddle.net/cXS5u/
Upvotes: 1
Reputation: 18584
I would try this:
Highcharts.addEvent = (function(orig) {
return function(el, event, fn) {
if(typeof fn == "string") {
try {
eval(fn);
} catch (e) {
if (e instanceof SyntaxError) {
console.log(e.message);
}
}
}
orig(el, event, fn);
};
})(Highcharts.addEvent);
using Highcharts' wrap
method, this should be
(function(H) {
H.wrap(H, "addEvent", function(addEvent, el, event, fn) {
if(typeof fn == "string") {
try {
eval(fn);
} catch (e) {
if (e instanceof SyntaxError) {
console.log(e.message);
}
}
}
addEvent(el, event, fn);
});
})(Highcharts);
Upvotes: 0