forked from chartjs/chartjs-plugin-annotation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathannotation.js
132 lines (117 loc) · 3.93 KB
/
annotation.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
module.exports = function(Chart) {
/* eslint-disable global-require */
var chartHelpers = Chart.helpers;
var helpers = require('./helpers.js')(Chart);
var events = require('./events.js')(Chart);
/* eslint-enable global-require */
var annotationTypes = Chart.Annotation.types;
function setAfterDataLimitsHook(axisOptions) {
helpers.decorate(axisOptions, 'afterDataLimits', function(previous, scale) {
if (previous) {
previous(scale);
}
helpers.adjustScaleRange(scale);
});
}
function draw(drawTime) {
return function(chartInstance, easingDecimal) {
var defaultDrawTime = chartInstance.annotation.options.drawTime;
helpers.elements(chartInstance)
.filter(function(element) {
return drawTime === (element.options.drawTime || defaultDrawTime);
})
.forEach(function(element) {
element.configure();
element.transition(easingDecimal).draw();
});
};
}
function getAnnotationConfig(chartOptions) {
var plugins = chartOptions.plugins;
var pluginAnnotation = plugins && plugins.annotation ? plugins.annotation : null;
return pluginAnnotation || chartOptions.annotation || {};
}
return {
beforeInit: function(chartInstance) {
var chartOptions = chartInstance.options;
// Initialize chart instance plugin namespace
var ns = chartInstance.annotation = {
elements: {},
options: helpers.initConfig(getAnnotationConfig(chartOptions)),
onDestroy: [],
firstRun: true,
supported: false
};
// Add the annotation scale adjuster to each scale's afterDataLimits hook
chartInstance.ensureScalesHaveIDs();
if (chartOptions.scales) {
ns.supported = true;
chartHelpers.each(chartOptions.scales.xAxes, setAfterDataLimitsHook);
chartHelpers.each(chartOptions.scales.yAxes, setAfterDataLimitsHook);
}
},
beforeUpdate: function(chartInstance) {
var ns = chartInstance.annotation;
if (!ns.supported) {
return;
}
if (!ns.firstRun) {
ns.options = helpers.initConfig(getAnnotationConfig(chartInstance.options));
} else {
ns.firstRun = false;
}
var elementIds = [];
// Add new elements, or update existing ones
ns.options.annotations.forEach(function(annotation) {
var id = annotation.id || helpers.objectId();
// No element with that ID exists, and it's a valid annotation type
if (!ns.elements[id] && annotationTypes[annotation.type]) {
var cls = annotationTypes[annotation.type];
var element = new cls({
id: id,
options: annotation,
chartInstance: chartInstance,
});
element.initialize();
ns.elements[id] = element;
annotation.id = id;
elementIds.push(id);
} else if (ns.elements[id]) {
// Nothing to do for update, since the element config references
// the same object that exists in the chart annotation config
elementIds.push(id);
}
});
// Delete removed elements
Object.keys(ns.elements).forEach(function(id) {
if (elementIds.indexOf(id) === -1) {
ns.elements[id].destroy();
delete ns.elements[id];
}
});
},
beforeDatasetsDraw: draw('beforeDatasetsDraw'),
afterDatasetsDraw: draw('afterDatasetsDraw'),
afterDraw: draw('afterDraw'),
afterInit: function(chartInstance) {
// Detect and intercept events that happen on an annotation element
var watchFor = chartInstance.annotation.options.events;
if (chartHelpers.isArray(watchFor) && watchFor.length > 0) {
var canvas = chartInstance.chart.canvas;
var eventHandler = events.dispatcher.bind(chartInstance);
events.collapseHoverEvents(watchFor).forEach(function(eventName) {
chartHelpers.addEvent(canvas, eventName, eventHandler);
chartInstance.annotation.onDestroy.push(function() {
chartHelpers.removeEvent(canvas, eventName, eventHandler);
});
});
}
},
destroy: function(chartInstance) {
var deregisterers = chartInstance.annotation.onDestroy;
while (deregisterers.length > 0) {
deregisterers.pop()();
}
}
};
};