79 |
80 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Copyright 2016-2017 Crown Copyright
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
15 | # IRIS Worm
16 |
17 | IRIS Worm is a real-time data graphing component. With straight-forward initialisation and a core set of methods, the component is easy to set up and an intuitive and beautiful data visualisation tool.
18 |
19 | ## Features
20 | * Easy Initialisation
21 | * Zero Dependencies
22 | * Built on HTML5 canvas - performant, scalable and fully supported in all major browsers
23 | * Accessibility - using ARIA alert and aria-live tags, screenreaders can read the worm to users
24 |
25 | ## Demo
26 | [Demo on gh-pages](https://gchq.github.io/iris-worm/)
27 |
28 | ## Installation
29 |
30 | We've packaged up all the dependencies into a minified distribution for you so you just need to include it on your page somehow;
31 |
32 | ```
33 |
34 | ```
35 | This registers IRIS.Worm in the global scope, allowing you to start using the component.
36 |
37 | ## Accessibility
38 |
39 | It is very important that any applications you make are useable by visually impaired users. The worm is a graphical
40 | interface rendered on to an html canvas, and so will not naturally be parseable by screen readers. The worm provides
41 | an interface to aria live/alert features to get around this, which will broadcast changes to the worm live to screen
42 | readers. Settings follow the standard aria naming convention, so that allows you to set broadcasts to be;
43 |
44 | off - the worm will not broadcast anything.
45 | polite - if the worm changes, it will broadcast the new value when the user is idle (i.e. it won't interrupt them).
46 | assertive - if the worm changes, it will interrupt the user and tell them that the change has occurred (i.e. it will interrupt them).
47 |
48 | You should tailor which option to go for depending on what your use case is. If you have many worms on one page, with data that changes
49 | very frequently, you might be better off disabling the broadcasts and just providing a seperate screen-reader-friendly interface.
50 |
51 | Implementation details can be found in the options section.
52 |
53 | ## Example
54 |
55 | Pass in a containing div and some options, and the worm will set up a canvas element. Then just call the `start()` method
56 | to start the worm.
57 |
58 | ```
59 | // construct a new instance
60 | var worm = new IRIS.Worm(document.querySelector('#wormCanvas'));
61 |
62 | // Start it
63 | worm.start();
64 |
65 | // Change the value
66 | worm.setValue(75);
67 | ```
68 |
69 | ## Options
70 | You can get or set the options for a timeline using the following interface;
71 | ```
72 | worm.getOption();
73 | worm.setOption(, );
74 | ```
75 |
76 | The options themselves are documented within the code however have been reproduced here for convinience.
77 |
78 | ```
79 | // The width of the component
80 | width: 600,
81 |
82 | // The height of the component
83 | height: 400,
84 |
85 | // The maximum value that can be set in the component (used for scaling) -
86 | // defaults to 100, meaning that "100" is the "Top of the worm".
87 | maxValue: 100,
88 |
89 | // When a value changes, the worm will accelerate towards that value smoothly
90 | // if smoothMode is set to true, otherwise it will jump straight to it.
91 | smoothMode: true,
92 |
93 | // Color mode: options are: 'greenIsGood', 'greenIsBad', 'monochrome'
94 | colorMode: 'greenIsGood',
95 |
96 | // How quickly the worm accelerates towards its target (NOTE: this value really is only useful if you keep it
97 | // below 1, otherwise you might as well just use smoothMode: false and have it instantly jumping)
98 | acceleration: 0.1,
99 |
100 | // How thick the line is
101 | lineWidth: 5,
102 |
103 | //how insistant the aria-live tag is. Default is polite;
104 | //options are: off, polite, assertive
105 | accessibilityBroadcast: 'polite'
106 | ```
107 |
108 | ## Events
109 |
110 | The worm emits events that can be subscribed to in order to provide custom behaviour. These events are subscribed to using the following interface;
111 |
112 | ```
113 | worm.on('valueChanged', function(value) {
114 | console.log("Value changed to " + value);
115 | });
116 | ```
117 | Events are as follows
118 |
119 | ```
120 | valueChanged
121 | valueIncreased
122 | valueDecreased
123 | valueBecameMinimum
124 | valueBecameMaximum
125 | ```
126 |
127 | ## Public Methods
128 |
129 | ```
130 | worm.start()
131 | ```
132 | Starts the worm.
133 |
134 | ```
135 | worm.stop()
136 | ```
137 | Stops the worm.
138 |
139 | ```
140 | worm.setValue(value)
141 | ```
142 | Sets the current value of the worm.
143 |
144 | ```
145 | worm.getValue()
146 | ```
147 | Gets the current value of the worm.
148 |
149 | ```
150 | worm.on(event, callback)
151 | ```
152 | Event hook (see "events" section)
153 |
--------------------------------------------------------------------------------
/dist/bundle.js:
--------------------------------------------------------------------------------
1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.IRISWorm=e():t.IRISWorm=e()}(window,function(){return function(t){var e={};function i(n){if(e[n])return e[n].exports;var a=e[n]={i:n,l:!1,exports:{}};return t[n].call(a.exports,a,a.exports,i),a.l=!0,a.exports}return i.m=t,i.c=e,i.d=function(t,e,n){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var a in t)i.d(n,a,function(e){return t[e]}.bind(null,a));return n},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=0)}([function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Worm=void 0;var n,a=i(1),o=(n=a)&&n.__esModule?n:{default:n};e.Worm=o.default},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n,a=function(){function t(t,e){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{};!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this._rootDiv=e,this._options=Object.assign({},t.DEFAULT_OPTIONS,i),this._canvas=document.createElement("canvas"),this._canvas.width=this._options.width,this._canvas.height=this._options.height,this._canvas.className=this.CSS_CONTAINER,this._ctx=this._canvas.getContext("2d"),this._rootDiv.appendChild(this._canvas),this._value=50,this._metaValue=50,this._oldMetaValue=50,this._momentum=0,this._active=!1,"off"!==this._options.accessibilityBroadcast&&(this._fallbackDom=document.createElement("span"),this._fallbackDom.setAttribute("role","alert"),this._fallbackDom.setAttribute("aria-live",this._options.accessibilityBroadcast),this._fallbackDom.setAttribute("style","position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);"),this._rootDiv.appendChild(this._fallbackDom)),this._eventEmitter=new s.default}return a(t,[{key:"NAME",get:function(){}},{key:"VERSION",get:function(){return null}},{key:"CSS_CONTAINER",get:function(){return"irisWorm"}},{key:"MAX_MOMENTUM",get:function(){return 5}}],[{key:"DEFAULT_OPTIONS",get:function(){return{width:600,height:400,maxValue:100,smoothMode:!0,colorMode:"greenIsGood",acceleration:.1,lineWidth:5,accessibilityBroadcast:"polite"}}}]),a(t,[{key:"start",value:function(){this._ctx.lineWidth=this._options.lineWidth,this._active=!0,this._draw()}},{key:"stop",value:function(){this._active=!1}},{key:"_draw",value:function(){this._active&&(requestAnimationFrame(this._draw.bind(this)),this._moveViewport(),this._drawPoint(),this._resolveValues())}},{key:"_resolveValues",value:function(){if(this._options.smoothMode){var t=Math.abs(this._value-this._metaValue);if(t<.1)return this._metaValue=this._value,void(this._momentum=0);this._value=-this.MAX_MOMENTUM&&(this._momentum-=this._options.acceleration),this._value>this._metaValue&&this._momentum<=this.MAX_MOMENTUM&&(this._momentum+=this._options.acceleration),this._metaValue+=this._momentum*t/100,this._oldMetaValue=this._metaValue}else this._oldMetaValue=this._metaValue,this._metaValue=this._value}},{key:"_moveViewport",value:function(){var t=this._ctx.getImageData(1,0,this._options.width-1,this._options.height);this._ctx.putImageData(t,0,0),this._ctx.clearRect(this._options.width-1,0,1,this._options.height),t=null}},{key:"_drawPoint",value:function(){var t,e=255/this._options.height,i=Math.floor(e*this._scaleValue(this._metaValue)),n=255-Math.floor(e*this._scaleValue(this._metaValue));switch(this._options.colorMode){case"monochrome":t="rgb(0,0,0)";break;case"greenIsBad":t="rgb("+n+","+i+",0)";break;case"greenIsGood":default:t="rgb("+i+","+n+",0)"}this._ctx.strokeStyle=t,this._ctx.beginPath(),this._ctx.moveTo(this._options.width,this._scaleValue(this._metaValue)),this._ctx.lineTo(this._options.width-1,this._scaleValue(this._oldMetaValue)),this._ctx.stroke()}},{key:"_scaleValue",value:function(t){var e=this._options.height/this._options.maxValue;return this._options.height-t*e}},{key:"_getName",value:function(){var t=this.NAME;return 0!==this.VERSION.indexOf("<%=")&&(t=this.NAME+" "+this.VERSION),t}},{key:"destroy",value:function(){void 0!==this._canvas&&null!=this._canvas&&(this._canvas.remove(),delete this._canvas)}},{key:"on",value:function(t,e){var i=this;this._eventEmitter.on(t,function(t,n,a){return e.call(i,t,n,a)})}},{key:"setValue",value:function(t){t>this._options.maxValue&&(t=this._options.maxValue),"off"!==this._options.accessibilityBroadcast&&this._fallbackDom&&this._fallbackDom.remove&&(this._fallbackDom.remove(),this._fallbackDom.innerText="worm value is "+t,this._rootDiv.appendChild(this._fallbackDom)),t>this._value&&this._eventEmitter.emit("valueIncreased",this._value,t),t=this._options.maxValue&&this._eventEmitter.emit("valueBecameMaximum",this._value),t<=0&&this._eventEmitter.emit("valueBecameMinimum",this._value),this._value=t,this._momentum=0,this._eventEmitter.emit("valueChanged",this._value)}},{key:"getValue",value:function(){return this._value}},{key:"setOption",value:function(t,e){this._options[t]=e}},{key:"getOption",value:function(t){return this._options[t]}}]),t}();e.default=u},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(t,e){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{};!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this._rootDiv=e,this._options=Object.assign({},t.DEFAULT_OPTIONS,i),this._canvas=document.createElement("canvas"),this._canvas.width=this._options.width,this._canvas.height=this._options.height,this._canvas.className=this.CSS_CONTAINER,this._ctx=this._canvas.getContext("2d"),this._rootDiv.appendChild(this._canvas),this._value=50,this._metaValue=50,this._oldMetaValue=50,this._momentum=0,this._active=!1,"off"!==this._options.accessibilityBroadcast&&(this._fallbackDom=document.createElement("span"),this._fallbackDom.setAttribute("role","alert"),this._fallbackDom.setAttribute("aria-live",this._options.accessibilityBroadcast),this._fallbackDom.setAttribute("style","position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);"),this._rootDiv.appendChild(this._fallbackDom)),this._eventEmitter=new s.default}return a(t,[{key:"NAME",get:function(){}},{key:"VERSION",get:function(){return null}},{key:"CSS_CONTAINER",get:function(){return"irisWorm"}},{key:"MAX_MOMENTUM",get:function(){return 5}}],[{key:"DEFAULT_OPTIONS",get:function(){return{width:600,height:400,maxValue:100,smoothMode:!0,colorMode:"greenIsGood",acceleration:.1,lineWidth:5,accessibilityBroadcast:"polite"}}}]),a(t,[{key:"start",value:function(){this._ctx.lineWidth=this._options.lineWidth,this._active=!0,this._draw()}},{key:"stop",value:function(){this._active=!1}},{key:"_draw",value:function(){this._active&&(requestAnimationFrame(this._draw.bind(this)),this._moveViewport(),this._drawPoint(),this._resolveValues())}},{key:"_resolveValues",value:function(){if(this._options.smoothMode){var t=Math.abs(this._value-this._metaValue);if(t<.1)return this._metaValue=this._value,void(this._momentum=0);this._value=-this.MAX_MOMENTUM&&(this._momentum-=this._options.acceleration),this._value>this._metaValue&&this._momentum<=this.MAX_MOMENTUM&&(this._momentum+=this._options.acceleration),this._metaValue+=this._momentum*t/100,this._oldMetaValue=this._metaValue}else this._oldMetaValue=this._metaValue,this._metaValue=this._value}},{key:"_moveViewport",value:function(){var t=this._ctx.getImageData(1,0,this._options.width-1,this._options.height);this._ctx.putImageData(t,0,0),this._ctx.clearRect(this._options.width-1,0,1,this._options.height),t=null}},{key:"_drawPoint",value:function(){var t,e=255/this._options.height,i=Math.floor(e*this._scaleValue(this._metaValue)),n=255-Math.floor(e*this._scaleValue(this._metaValue));switch(this._options.colorMode){case"monochrome":t="rgb(0,0,0)";break;case"greenIsBad":t="rgb("+n+","+i+",0)";break;case"greenIsGood":default:t="rgb("+i+","+n+",0)"}this._ctx.strokeStyle=t,this._ctx.beginPath(),this._ctx.moveTo(this._options.width,this._scaleValue(this._metaValue)),this._ctx.lineTo(this._options.width-1,this._scaleValue(this._oldMetaValue)),this._ctx.stroke()}},{key:"_scaleValue",value:function(t){var e=this._options.height/this._options.maxValue;return this._options.height-t*e}},{key:"_getName",value:function(){var t=this.NAME;return 0!==this.VERSION.indexOf("<%=")&&(t=this.NAME+" "+this.VERSION),t}},{key:"destroy",value:function(){void 0!==this._canvas&&null!=this._canvas&&(this._canvas.remove(),delete this._canvas)}},{key:"on",value:function(t,e){var i=this;this._eventEmitter.on(t,function(t,n,a){return e.call(i,t,n,a)})}},{key:"setValue",value:function(t){t>this._options.maxValue&&(t=this._options.maxValue),"off"!==this._options.accessibilityBroadcast&&this._fallbackDom&&this._fallbackDom.remove&&(this._fallbackDom.remove(),this._fallbackDom.innerText="worm value is "+t,this._rootDiv.appendChild(this._fallbackDom)),t>this._value&&this._eventEmitter.emit("valueIncreased",this._value,t),t=this._options.maxValue&&this._eventEmitter.emit("valueBecameMaximum",this._value),t<=0&&this._eventEmitter.emit("valueBecameMinimum",this._value),this._value=t,this._momentum=0,this._eventEmitter.emit("valueChanged",this._value)}},{key:"getValue",value:function(){return this._value}},{key:"setOption",value:function(t,e){this._options[t]=e}},{key:"getOption",value:function(t){return this._options[t]}}]),t}();e.default=u},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(t,e){for(var i=0;i= -this.MAX_MOMENTUM) {
122 | this._momentum -= this._options.acceleration;
123 | }
124 | }
125 | if (this._value > this._metaValue) {
126 | if (this._momentum <= this.MAX_MOMENTUM) {
127 | this._momentum += this._options.acceleration;
128 | }
129 | }
130 |
131 | this._metaValue += (this._momentum * distanceToValue) / 100;
132 | }
133 | this._oldMetaValue = this._metaValue;
134 | } else {
135 | this._oldMetaValue = this._metaValue;
136 | this._metaValue = this._value;
137 | }
138 |
139 | }
140 |
141 | _moveViewport() {
142 | var imageData = this._ctx.getImageData(1, 0, this._options.width - 1, this._options.height);
143 | this._ctx.putImageData(imageData, 0, 0);
144 | this._ctx.clearRect(this._options.width - 1, 0, 1, this._options.height);
145 |
146 | // this thing is known to be leaky so let's force explicit garbage collecion.
147 | imageData = null;
148 | }
149 |
150 | _drawPoint() {
151 |
152 | var colorUnit = (255 / this._options.height);
153 | var bad = Math.floor(colorUnit * this._scaleValue(this._metaValue));
154 | var good = 255 - Math.floor(colorUnit * this._scaleValue(this._metaValue));
155 | var color;
156 |
157 | switch (this._options.colorMode) {
158 | case 'monochrome':
159 | color = 'rgb(0,0,0)';
160 | break;
161 | case 'greenIsBad':
162 | color = 'rgb(' + good + ',' + bad + ',0)';
163 | break;
164 | case 'greenIsGood':
165 | default:
166 | color = 'rgb(' + bad + ',' + good + ',0)';
167 | }
168 |
169 | this._ctx.strokeStyle = color;
170 |
171 | this._ctx.beginPath();
172 | this._ctx.moveTo(this._options.width, this._scaleValue(this._metaValue));
173 | this._ctx.lineTo(this._options.width - 1, this._scaleValue(this._oldMetaValue));
174 | this._ctx.stroke();
175 | }
176 |
177 | _scaleValue(value) {
178 | var scale = this._options.height / this._options.maxValue;
179 |
180 |
181 | return this._options.height - (value * scale);
182 | }
183 |
184 | /**
185 | * Returns the name (and version, if available) of this widget.
186 | *
187 | * @private
188 | * @method _getName
189 | * @returns {string} name (and version, if available) of this widget
190 | */
191 | _getName() {
192 | var name = this.NAME;
193 | // if we appear to have a version
194 | if (this.VERSION.indexOf('<%=') !== 0) {
195 | name = this.NAME + ' ' + this.VERSION;
196 | }
197 | return name;
198 | }
199 |
200 | /**
201 | * Deconstructor
202 | *
203 | * @public
204 | * @method destroy
205 | */
206 | destroy() {
207 | if (typeof this._canvas !== 'undefined' && this._canvas != null) {
208 | this._canvas.remove();
209 | delete this._canvas;
210 | }
211 | }
212 |
213 |
214 | /**
215 | * Hook into a worm event.
216 | *
217 | * @public
218 | * @method on
219 | * @param {string} eventName the event to hook into
220 | * @param {function} callback the callback to run
221 | * @returns {null}
222 | */
223 | on(eventName, callback) {
224 | var self = this;
225 | this._eventEmitter.on(eventName, (a, b, c) => callback.call(self, a, b, c));
226 | }
227 |
228 |
229 | /**
230 | * Sets the value
231 | *
232 | * @public
233 | * @method setValue
234 | * @param {number} optionValue value to set the option to
235 | * @returns {null}
236 | */
237 | setValue(newValue) {
238 |
239 | if (newValue > this._options.maxValue) {
240 | newValue = this._options.maxValue;
241 | }
242 | if (this._options.accessibilityBroadcast !== 'off') {
243 | if (this._fallbackDom && this._fallbackDom.remove) {
244 | this._fallbackDom.remove();
245 | this._fallbackDom.innerText = 'worm value is ' + newValue;
246 | this._rootDiv.appendChild(this._fallbackDom);
247 | }
248 | }
249 |
250 | if (newValue > this._value) {
251 | this._eventEmitter.emit('valueIncreased', this._value, newValue);
252 | }
253 | if (newValue < this._value) {
254 | this._eventEmitter.emit('valueDecreased', this._value, newValue);
255 | }
256 | if (newValue <= 0) {
257 | this._eventEmitter.emit('valueBecameMinimum', this._value);
258 | }
259 | if (newValue >= this._options.maxValue) {
260 | this._eventEmitter.emit('valueBecameMaximum', this._value);
261 | }
262 |
263 |
264 | if (newValue <= 0) {
265 | this._eventEmitter.emit('valueBecameMinimum', this._value);
266 | }
267 |
268 | this._value = newValue;
269 | this._momentum = 0;
270 | this._eventEmitter.emit('valueChanged', this._value);
271 | }
272 |
273 | /**
274 | * Gets the value
275 | *
276 | * @public
277 | * @method getValue
278 | * @returns {number} the current value
279 | */
280 | getValue() {
281 | return this._value;
282 | }
283 |
284 | /**
285 | * Sets the value for the specified option.
286 | *
287 | * @public
288 | * @method setOption
289 | * @param {string} optionName name of the option to set a value for
290 | * @param {object} optionValue value to set the option to
291 | * @returns {null}
292 | */
293 | setOption(optionName, optionValue) {
294 | this._options[optionName] = optionValue;
295 | }
296 |
297 | /**
298 | * Returns the value for the specified option.
299 | *
300 | * @public
301 | * @method getOption
302 | * @param {string} optionName name of the option to retrieve a value for
303 | * @returns {object} the value of the specified option
304 | */
305 | getOption(optionName) {
306 | return this._options[optionName];
307 | }
308 |
309 | }
310 |
--------------------------------------------------------------------------------
/dist/bundle.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack://IRISWorm/webpack/universalModuleDefinition","webpack://IRISWorm/webpack/bootstrap","webpack://IRISWorm/./src/_entry.js","webpack://IRISWorm/./src/iris.worm.js","webpack://IRISWorm/./src/event-emitter.js"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","_iris","Worm","WORM","_eventEmitter","div","options","arguments","length","undefined","_classCallCheck","this","_rootDiv","_options","assign","DEFAULT_OPTIONS","_canvas","document","createElement","width","height","className","CSS_CONTAINER","_ctx","getContext","appendChild","_value","_metaValue","_oldMetaValue","_momentum","_active","accessibilityBroadcast","_fallbackDom","setAttribute","EventEmitter","maxValue","smoothMode","colorMode","acceleration","lineWidth","_draw","requestAnimationFrame","_moveViewport","_drawPoint","_resolveValues","distanceToValue","Math","abs","MAX_MOMENTUM","imageData","getImageData","putImageData","clearRect","color","colorUnit","bad","floor","_scaleValue","good","strokeStyle","beginPath","moveTo","lineTo","stroke","scale","NAME","VERSION","indexOf","remove","eventName","callback","self","on","a","b","newValue","innerText","emit","optionName","optionValue","logger","_events","push","arg1","arg2","arg3","forEach","fn"],"mappings":"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","file":"bundle.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"IRISWorm\"] = factory();\n\telse\n\t\troot[\"IRISWorm\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","import WORM from './iris.worm';\n\nexport const Worm = WORM;","import EventEmitter from './event-emitter';\n\nexport default class Worm {\n\n get NAME() {\n 'IRIS Worm'\n };\n get VERSION() {\n return null\n } // TODO\n get CSS_CONTAINER() {\n return 'irisWorm'\n };\n get MAX_MOMENTUM() {\n return 5\n };\n\n static get DEFAULT_OPTIONS() {\n return {\n // The width of the component\n width: 600,\n\n // The height of the component\n height: 400,\n\n // The maximum value that can be set in the component (used for scaling) -\n // defaults to 100, meaning that \"100\" is the \"Top of the worm\".\n maxValue: 100,\n\n // When a value changes, the worm will accelerate towards that value smoothly\n // if smoothMode is set to true, otherwise it will jump straight to it.\n smoothMode: true,\n\n // Color mode: options are: 'greenIsGood', 'greenIsBad', 'monochrome'\n colorMode: 'greenIsGood',\n\n // How quickly the worm accelerates towards its target (NOTE: this value really is only useful if you keep it\n // below 1, otherwise you might as well just use smoothMode: false and have it instantly jumping)\n acceleration: 0.1,\n\n // How thick the line is\n lineWidth: 5,\n\n //how insistant the aria-live tag is. Default is polite;\n //options are: off, polite, assertive\n accessibilityBroadcast: 'polite'\n }\n };\n\n /**\n * Constructs a new IRIS Worm instance.\n * @class IRIS.Worm\n * @constructor Worm\n * @example\n * new IRIS.Worm(div, options);\n * @param {HTMLDivElement} div the div in which the visualisation will be rendered, e.g. '#map'\n * @param options visualisation options (see 'options' property)\n */\n constructor(div, options = {}) {\n this._rootDiv = div;\n this._options = Object.assign({}, Worm.DEFAULT_OPTIONS, options);\n\n // create canvas and context\n this._canvas = document.createElement('canvas');\n this._canvas.width = this._options.width;\n this._canvas.height = this._options.height;\n this._canvas.className = this.CSS_CONTAINER;\n this._ctx = this._canvas.getContext('2d');\n this._rootDiv.appendChild(this._canvas);\n\n this._value = 50;\n this._metaValue = 50;\n this._oldMetaValue = 50;\n this._momentum = 0.0;\n this._active = false;\n\n //create fallback DOM and add aria roles if the accessibilityBroadcast option isn't disabled\n if (this._options.accessibilityBroadcast !== 'off') {\n this._fallbackDom = document.createElement('span');\n this._fallbackDom.setAttribute('role', 'alert');\n this._fallbackDom.setAttribute('aria-live', this._options.accessibilityBroadcast);\n this._fallbackDom.setAttribute('style', 'position:absolute;width:1px;' + '' +\n 'height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);');\n this._rootDiv.appendChild(this._fallbackDom);\n }\n\n // Events\n this._eventEmitter = new EventEmitter();\n }\n\n start() {\n this._ctx.lineWidth = this._options.lineWidth;\n this._active = true;\n this._draw();\n }\n\n stop() {\n this._active = false;\n }\n\n _draw() {\n if (this._active) {\n requestAnimationFrame(this._draw.bind(this));\n this._moveViewport();\n this._drawPoint();\n this._resolveValues();\n }\n }\n\n _resolveValues() {\n\n if (this._options.smoothMode) {\n var distanceToValue = Math.abs(this._value - this._metaValue);\n\n if (distanceToValue < 0.1) {\n this._metaValue = this._value;\n this._momentum = 0;\n return;\n } else {\n if (this._value < this._metaValue) {\n if (this._momentum >= -this.MAX_MOMENTUM) {\n this._momentum -= this._options.acceleration;\n }\n }\n if (this._value > this._metaValue) {\n if (this._momentum <= this.MAX_MOMENTUM) {\n this._momentum += this._options.acceleration;\n }\n }\n\n this._metaValue += (this._momentum * distanceToValue) / 100;\n }\n this._oldMetaValue = this._metaValue;\n } else {\n this._oldMetaValue = this._metaValue;\n this._metaValue = this._value;\n }\n\n }\n\n _moveViewport() {\n var imageData = this._ctx.getImageData(1, 0, this._options.width - 1, this._options.height);\n this._ctx.putImageData(imageData, 0, 0);\n this._ctx.clearRect(this._options.width - 1, 0, 1, this._options.height);\n\n // this thing is known to be leaky so let's force explicit garbage collecion.\n imageData = null;\n }\n\n _drawPoint() {\n\n var colorUnit = (255 / this._options.height);\n var bad = Math.floor(colorUnit * this._scaleValue(this._metaValue));\n var good = 255 - Math.floor(colorUnit * this._scaleValue(this._metaValue));\n var color;\n\n switch (this._options.colorMode) {\n case 'monochrome':\n color = 'rgb(0,0,0)';\n break;\n case 'greenIsBad':\n color = 'rgb(' + good + ',' + bad + ',0)';\n break;\n case 'greenIsGood':\n default:\n color = 'rgb(' + bad + ',' + good + ',0)';\n }\n\n this._ctx.strokeStyle = color;\n\n this._ctx.beginPath();\n this._ctx.moveTo(this._options.width, this._scaleValue(this._metaValue));\n this._ctx.lineTo(this._options.width - 1, this._scaleValue(this._oldMetaValue));\n this._ctx.stroke();\n }\n\n _scaleValue(value) {\n var scale = this._options.height / this._options.maxValue;\n\n\n return this._options.height - (value * scale);\n }\n\n /**\n * Returns the name (and version, if available) of this widget.\n *\n * @private\n * @method _getName\n * @returns {string} name (and version, if available) of this widget\n */\n _getName() {\n var name = this.NAME;\n // if we appear to have a version\n if (this.VERSION.indexOf('<%=') !== 0) {\n name = this.NAME + ' ' + this.VERSION;\n }\n return name;\n }\n\n /**\n * Deconstructor\n *\n * @public\n * @method destroy\n */\n destroy() {\n if (typeof this._canvas !== 'undefined' && this._canvas != null) {\n this._canvas.remove();\n delete this._canvas;\n }\n }\n\n\n /**\n * Hook into a worm event.\n *\n * @public\n * @method on\n * @param {string} eventName the event to hook into\n * @param {function} callback the callback to run\n * @returns {null}\n */\n on(eventName, callback) {\n var self = this;\n this._eventEmitter.on(eventName, (a, b, c) => callback.call(self, a, b, c));\n }\n\n\n /**\n * Sets the value\n *\n * @public\n * @method setValue\n * @param {number} optionValue value to set the option to\n * @returns {null}\n */\n setValue(newValue) {\n\n if (newValue > this._options.maxValue) {\n newValue = this._options.maxValue;\n }\n if (this._options.accessibilityBroadcast !== 'off') {\n if (this._fallbackDom && this._fallbackDom.remove) {\n this._fallbackDom.remove();\n this._fallbackDom.innerText = 'worm value is ' + newValue;\n this._rootDiv.appendChild(this._fallbackDom);\n }\n }\n\n if (newValue > this._value) {\n this._eventEmitter.emit('valueIncreased', this._value, newValue);\n }\n if (newValue < this._value) {\n this._eventEmitter.emit('valueDecreased', this._value, newValue);\n }\n if (newValue <= 0) {\n this._eventEmitter.emit('valueBecameMinimum', this._value);\n }\n if (newValue >= this._options.maxValue) {\n this._eventEmitter.emit('valueBecameMaximum', this._value);\n }\n\n\n if (newValue <= 0) {\n this._eventEmitter.emit('valueBecameMinimum', this._value);\n }\n\n this._value = newValue;\n this._momentum = 0;\n this._eventEmitter.emit('valueChanged', this._value);\n }\n\n /**\n * Gets the value\n *\n * @public\n * @method getValue\n * @returns {number} the current value\n */\n getValue() {\n return this._value;\n }\n\n /**\n * Sets the value for the specified option.\n *\n * @public\n * @method setOption\n * @param {string} optionName name of the option to set a value for\n * @param {object} optionValue value to set the option to\n * @returns {null}\n */\n setOption(optionName, optionValue) {\n this._options[optionName] = optionValue;\n }\n\n /**\n * Returns the value for the specified option.\n *\n * @public\n * @method getOption\n * @param {string} optionName name of the option to retrieve a value for\n * @returns {object} the value of the specified option\n */\n getOption(optionName) {\n return this._options[optionName];\n }\n\n}\n","export default class EventEmitter {\n\n constructor(logger) {\n this._events = {};\n }\n\n /**\n * Sets a listener for the specified event name.\n *\n * @public\n * @method on\n * @param {string} eventName name of the event to listen to.\n * @param {function} callback function to call when the event occurs.\n */\n on(eventName, callback) {\n this._events[eventName] = this._events[eventName] || [];\n this._events[eventName].push(callback);\n }\n\n /**\n * Sets a listener for the specified event name.\n *\n * @public\n * @method emit\n * @param {string} eventName name of the event to emit.\n * @param {any} arg1, arg2, arg3 arguments to yield to the functioun\n */\n emit(eventName, arg1, arg2, arg3) {\n (this._events[eventName] || []).forEach((fn) => {\n fn && fn(arg1, arg2, arg3)\n });\n }\n\n}"],"sourceRoot":""}
--------------------------------------------------------------------------------
/dist/bundle.min.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack://IRISWorm/webpack/universalModuleDefinition","webpack://IRISWorm/webpack/bootstrap","webpack://IRISWorm/./src/_entry.js","webpack://IRISWorm/./src/iris.worm.js","webpack://IRISWorm/./src/event-emitter.js"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","_iris","Worm","WORM","_eventEmitter","div","options","arguments","length","undefined","_classCallCheck","this","_rootDiv","_options","assign","DEFAULT_OPTIONS","_canvas","document","createElement","width","height","className","CSS_CONTAINER","_ctx","getContext","appendChild","_value","_metaValue","_oldMetaValue","_momentum","_active","accessibilityBroadcast","_fallbackDom","setAttribute","EventEmitter","maxValue","smoothMode","colorMode","acceleration","lineWidth","_draw","requestAnimationFrame","_moveViewport","_drawPoint","_resolveValues","distanceToValue","Math","abs","MAX_MOMENTUM","imageData","getImageData","putImageData","clearRect","color","colorUnit","bad","floor","_scaleValue","good","strokeStyle","beginPath","moveTo","lineTo","stroke","scale","NAME","VERSION","indexOf","remove","eventName","callback","self","on","a","b","newValue","innerText","emit","optionName","optionValue","logger","_events","push","arg1","arg2","arg3","forEach","fn"],"mappings":"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","file":"bundle.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"IRISWorm\"] = factory();\n\telse\n\t\troot[\"IRISWorm\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","import WORM from './iris.worm';\n\nexport const Worm = WORM;","import EventEmitter from './event-emitter';\n\nexport default class Worm {\n\n get NAME() {\n 'IRIS Worm'\n };\n get VERSION() {\n return null\n } // TODO\n get CSS_CONTAINER() {\n return 'irisWorm'\n };\n get MAX_MOMENTUM() {\n return 5\n };\n\n static get DEFAULT_OPTIONS() {\n return {\n // The width of the component\n width: 600,\n\n // The height of the component\n height: 400,\n\n // The maximum value that can be set in the component (used for scaling) -\n // defaults to 100, meaning that \"100\" is the \"Top of the worm\".\n maxValue: 100,\n\n // When a value changes, the worm will accelerate towards that value smoothly\n // if smoothMode is set to true, otherwise it will jump straight to it.\n smoothMode: true,\n\n // Color mode: options are: 'greenIsGood', 'greenIsBad', 'monochrome'\n colorMode: 'greenIsGood',\n\n // How quickly the worm accelerates towards its target (NOTE: this value really is only useful if you keep it\n // below 1, otherwise you might as well just use smoothMode: false and have it instantly jumping)\n acceleration: 0.1,\n\n // How thick the line is\n lineWidth: 5,\n\n //how insistant the aria-live tag is. Default is polite;\n //options are: off, polite, assertive\n accessibilityBroadcast: 'polite'\n }\n };\n\n /**\n * Constructs a new IRIS Worm instance.\n * @class IRIS.Worm\n * @constructor Worm\n * @example\n * new IRIS.Worm(div, options);\n * @param {HTMLDivElement} div the div in which the visualisation will be rendered, e.g. '#map'\n * @param options visualisation options (see 'options' property)\n */\n constructor(div, options = {}) {\n this._rootDiv = div;\n this._options = Object.assign({}, Worm.DEFAULT_OPTIONS, options);\n\n // create canvas and context\n this._canvas = document.createElement('canvas');\n this._canvas.width = this._options.width;\n this._canvas.height = this._options.height;\n this._canvas.className = this.CSS_CONTAINER;\n this._ctx = this._canvas.getContext('2d');\n this._rootDiv.appendChild(this._canvas);\n\n this._value = 50;\n this._metaValue = 50;\n this._oldMetaValue = 50;\n this._momentum = 0.0;\n this._active = false;\n\n //create fallback DOM and add aria roles if the accessibilityBroadcast option isn't disabled\n if (this._options.accessibilityBroadcast !== 'off') {\n this._fallbackDom = document.createElement('span');\n this._fallbackDom.setAttribute('role', 'alert');\n this._fallbackDom.setAttribute('aria-live', this._options.accessibilityBroadcast);\n this._fallbackDom.setAttribute('style', 'position:absolute;width:1px;' + '' +\n 'height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);');\n this._rootDiv.appendChild(this._fallbackDom);\n }\n\n // Events\n this._eventEmitter = new EventEmitter();\n }\n\n start() {\n this._ctx.lineWidth = this._options.lineWidth;\n this._active = true;\n this._draw();\n }\n\n stop() {\n this._active = false;\n }\n\n _draw() {\n if (this._active) {\n requestAnimationFrame(this._draw.bind(this));\n this._moveViewport();\n this._drawPoint();\n this._resolveValues();\n }\n }\n\n _resolveValues() {\n\n if (this._options.smoothMode) {\n var distanceToValue = Math.abs(this._value - this._metaValue);\n\n if (distanceToValue < 0.1) {\n this._metaValue = this._value;\n this._momentum = 0;\n return;\n } else {\n if (this._value < this._metaValue) {\n if (this._momentum >= -this.MAX_MOMENTUM) {\n this._momentum -= this._options.acceleration;\n }\n }\n if (this._value > this._metaValue) {\n if (this._momentum <= this.MAX_MOMENTUM) {\n this._momentum += this._options.acceleration;\n }\n }\n\n this._metaValue += (this._momentum * distanceToValue) / 100;\n }\n this._oldMetaValue = this._metaValue;\n } else {\n this._oldMetaValue = this._metaValue;\n this._metaValue = this._value;\n }\n\n }\n\n _moveViewport() {\n var imageData = this._ctx.getImageData(1, 0, this._options.width - 1, this._options.height);\n this._ctx.putImageData(imageData, 0, 0);\n this._ctx.clearRect(this._options.width - 1, 0, 1, this._options.height);\n\n // this thing is known to be leaky so let's force explicit garbage collecion.\n imageData = null;\n }\n\n _drawPoint() {\n\n var colorUnit = (255 / this._options.height);\n var bad = Math.floor(colorUnit * this._scaleValue(this._metaValue));\n var good = 255 - Math.floor(colorUnit * this._scaleValue(this._metaValue));\n var color;\n\n switch (this._options.colorMode) {\n case 'monochrome':\n color = 'rgb(0,0,0)';\n break;\n case 'greenIsBad':\n color = 'rgb(' + good + ',' + bad + ',0)';\n break;\n case 'greenIsGood':\n default:\n color = 'rgb(' + bad + ',' + good + ',0)';\n }\n\n this._ctx.strokeStyle = color;\n\n this._ctx.beginPath();\n this._ctx.moveTo(this._options.width, this._scaleValue(this._metaValue));\n this._ctx.lineTo(this._options.width - 1, this._scaleValue(this._oldMetaValue));\n this._ctx.stroke();\n }\n\n _scaleValue(value) {\n var scale = this._options.height / this._options.maxValue;\n\n\n return this._options.height - (value * scale);\n }\n\n /**\n * Returns the name (and version, if available) of this widget.\n *\n * @private\n * @method _getName\n * @returns {string} name (and version, if available) of this widget\n */\n _getName() {\n var name = this.NAME;\n // if we appear to have a version\n if (this.VERSION.indexOf('<%=') !== 0) {\n name = this.NAME + ' ' + this.VERSION;\n }\n return name;\n }\n\n /**\n * Deconstructor\n *\n * @public\n * @method destroy\n */\n destroy() {\n if (typeof this._canvas !== 'undefined' && this._canvas != null) {\n this._canvas.remove();\n delete this._canvas;\n }\n }\n\n\n /**\n * Hook into a worm event.\n *\n * @public\n * @method on\n * @param {string} eventName the event to hook into\n * @param {function} callback the callback to run\n * @returns {null}\n */\n on(eventName, callback) {\n var self = this;\n this._eventEmitter.on(eventName, (a, b, c) => callback.call(self, a, b, c));\n }\n\n\n /**\n * Sets the value\n *\n * @public\n * @method setValue\n * @param {number} optionValue value to set the option to\n * @returns {null}\n */\n setValue(newValue) {\n\n if (newValue > this._options.maxValue) {\n newValue = this._options.maxValue;\n }\n if (this._options.accessibilityBroadcast !== 'off') {\n if (this._fallbackDom && this._fallbackDom.remove) {\n this._fallbackDom.remove();\n this._fallbackDom.innerText = 'worm value is ' + newValue;\n this._rootDiv.appendChild(this._fallbackDom);\n }\n }\n\n if (newValue > this._value) {\n this._eventEmitter.emit('valueIncreased', this._value, newValue);\n }\n if (newValue < this._value) {\n this._eventEmitter.emit('valueDecreased', this._value, newValue);\n }\n if (newValue <= 0) {\n this._eventEmitter.emit('valueBecameMinimum', this._value);\n }\n if (newValue >= this._options.maxValue) {\n this._eventEmitter.emit('valueBecameMaximum', this._value);\n }\n\n\n if (newValue <= 0) {\n this._eventEmitter.emit('valueBecameMinimum', this._value);\n }\n\n this._value = newValue;\n this._momentum = 0;\n this._eventEmitter.emit('valueChanged', this._value);\n }\n\n /**\n * Gets the value\n *\n * @public\n * @method getValue\n * @returns {number} the current value\n */\n getValue() {\n return this._value;\n }\n\n /**\n * Sets the value for the specified option.\n *\n * @public\n * @method setOption\n * @param {string} optionName name of the option to set a value for\n * @param {object} optionValue value to set the option to\n * @returns {null}\n */\n setOption(optionName, optionValue) {\n this._options[optionName] = optionValue;\n }\n\n /**\n * Returns the value for the specified option.\n *\n * @public\n * @method getOption\n * @param {string} optionName name of the option to retrieve a value for\n * @returns {object} the value of the specified option\n */\n getOption(optionName) {\n return this._options[optionName];\n }\n\n}\n","export default class EventEmitter {\n\n constructor(logger) {\n this._events = {};\n }\n\n /**\n * Sets a listener for the specified event name.\n *\n * @public\n * @method on\n * @param {string} eventName name of the event to listen to.\n * @param {function} callback function to call when the event occurs.\n */\n on(eventName, callback) {\n this._events[eventName] = this._events[eventName] || [];\n this._events[eventName].push(callback);\n }\n\n /**\n * Sets a listener for the specified event name.\n *\n * @public\n * @method emit\n * @param {string} eventName name of the event to emit.\n * @param {any} arg1, arg2, arg3 arguments to yield to the functioun\n */\n emit(eventName, arg1, arg2, arg3) {\n (this._events[eventName] || []).forEach((fn) => {\n fn && fn(arg1, arg2, arg3)\n });\n }\n\n}"],"sourceRoot":""}
--------------------------------------------------------------------------------