├── bower.json
├── examples
├── index.html
├── demo.js
└── Percussion.js
├── LICENSE
├── README.md
└── dist
├── Percussion.min.js
└── Percussion.js
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Percussion",
3 | "version": "0.1.0",
4 | "description": "Debugging tool for JS reactive programming libraries.",
5 | "main": "dist/Percussion.js",
6 | "moduleType": [
7 | "globals"
8 | ],
9 | "keywords": [
10 | "percussion",
11 | "reactive",
12 | "programming",
13 | "bacon.js",
14 | "rxjs",
15 | "kefir.js"
16 | ],
17 | "authors": [
18 | "Francisco J. Cruz Romanos "
19 | ],
20 | "license": "MIT"
21 | }
22 |
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Francisco José Cruz Romanos
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/examples/demo.js:
--------------------------------------------------------------------------------
1 | var single = null;
2 | var double = null;
3 | var poll = null;
4 |
5 | var percussion = new Percussion();
6 |
7 | if (typeof(Bacon) !== 'undefined') {
8 | single = Bacon.fromEventTarget(document.getElementById('demo'), 'click').map(
9 | function(data) {
10 | return 'click';
11 | }
12 | );
13 | double = single.bufferWithTimeOrCount(300, 2).filter(
14 | function(x) {
15 | return x.length >= 2;
16 | }
17 | ).map(
18 | function(data) {
19 | return 'dblclick';
20 | }
21 | );
22 | poll = Bacon.fromPoll(
23 | 5000,
24 | function() {
25 | return 'time!';
26 | }
27 | ).startWith('init');
28 | }
29 | else if (typeof(Rx) !== 'undefined') {
30 | single = Rx.Observable.fromEvent(document.getElementById('demo'), 'click')
31 | .map(function() { return 'click'; });
32 | double = single.buffer(function() { return single.throttle(300); })
33 | .map(function(list) { return list.length; })
34 | .filter(function(x) { return x >= 2; })
35 | .map(function() { return 'dblclick'; });
36 | poll = Rx.Observable.interval(5000)
37 | .map(function(list) { return 'time!'; })
38 | .startWith('init');
39 | }
40 | else if (typeof(Kefir) !== 'undefined') {
41 | single = Kefir.fromEvents(document.getElementById('demo'), 'click')
42 | .map(function() { return 'click'; });
43 | double = single.bufferBy(single.debounce(300))
44 | .map(function(list) { return list.length; })
45 | .filter(function(x) { return x >= 2; })
46 | .map(function() { return 'dblclick'; });
47 | poll = Kefir.interval(5000, 'time!').toProperty(
48 | function() {
49 | return 'init';
50 | }
51 | );
52 | }
53 |
54 | percussion.addStream(single);
55 | percussion.addStream(double);
56 | percussion.addStream(poll);
57 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Percussion
2 | Debugging tool for JS reactive programming libraries.
3 |
4 | This library allows to visualize streams in order to debug reactive javascript programming applications. Currently supported libraries are:
5 | * Bacon.js - [https://baconjs.github.io/](https://baconjs.github.io/)
6 | * RxJS - [http://reactivex.io/](http://reactivex.io/)
7 | * Kefir.js - [https://rpominov.github.io/kefir/](https://rpominov.github.io/kefir/)
8 |
9 |
10 | ## Simple usage
11 |
12 | You can just initialize constructor without options:
13 | ```javascript
14 | var percussion = new Percussion();
15 | ```
16 |
17 | And then add as many streams as you want:
18 | ```javascript
19 | percussion.addStream(stream1);
20 | percussion.addStream(stream2);
21 | percussion.addStream(stream3);
22 | ...
23 | ```
24 | Then, you will see streams represented as lines, and events represented as circles in those lines. You can mouse-hover in the circles in order to see their values in a tooltip, or click them to see their values in the browser debugger console.
25 |
26 | ## Methods
27 |
28 | You can stop debugging with:
29 | ```javascript
30 | percussion.stop();
31 | ```
32 |
33 | And then recover execution with:
34 | ```javascript
35 | percussion.start();
36 | ```
37 |
38 | By default, data visualization will automatically be scrolled in order to see last stream events. You can disable this in runtime with:
39 | ```javascript
40 | percussion.setAutoScroll(false);
41 | ```
42 | and enable again with:
43 | ```javascript
44 | percussion.setAutoScroll(true);
45 | ```
46 |
47 | ## Constructor options
48 |
49 | * **lineSize**: Height of the stream line in px. *Default: 20*
50 | * **pointSize**: Width of the event point in px. *Default: 10*
51 | * **speed**: Speed of stream visualization in px/sample. *Default: 20*
52 | * **timeout**: Time of each sample in ms. *Default: 250*
53 | * **autoScroll**: Whether if data visualization will automatically do scroll or not. *Default: true*
54 | * **print** = Whether if event values will be printed in the stream visualization or not. *Default: false*
55 | * **colors**: Array of colors for events in each stream. Will be repeated cyclically. *Default: ['#F00', '#0F0', '#00F']*
56 | * **textColors** = Array of text colors for events in each stream (visible only if print == true). Should be the same size as colors, and also, will be repeated cyclically. *Default: ['#FFF', '#FFF', '#FFF']*
57 | * **position** = HTML Element where data visualization will be injected. Notice this needs to be a pure Element, so if you use libraries like jQuery, you need to convert it (i.e.: $('#canvas')[0]). *Default: document.body*
58 |
59 | Example:
60 | ```javascript
61 | var percussion = new Percussion(
62 | {
63 | position: document.getElementById('canvas'),
64 | speed: 200
65 | }
66 | );
67 | ```
68 |
69 | ## Contributors
70 |
71 | grisendo: Francisco J. Cruz Romanos
72 |
73 | ## License
74 |
75 | [MIT License](http://en.wikipedia.org/wiki/MIT_License)
76 |
--------------------------------------------------------------------------------
/dist/Percussion.min.js:
--------------------------------------------------------------------------------
1 | /*! Percussion v0.1.0 | (c) 2015 grisendo */
2 | !function(){var a=function(a){"undefined"==typeof a&&(a={}),this.lineSize=20,this.pointSize=10,this.speed=20,this.timeout=250,this.autoScroll=!0,this.colors=[],this.textColors=[],this.eventIn=null,this.eventOut=null,this.position=document.body,this.print=!1,this._setOptions(a),this.interval=null,this.canvas=null,this.canvasIn=null,this.running=!1,this.lines=0,this.time=0,this.counter=0,this.streams=[],this.events=[],this._startCanvas()};a.prototype._setOptions=function(a){"undefined"!=typeof a.lineSize?this.lineSize=a.lineSize:null,"undefined"!=typeof a.pointSize?this.pointSize=a.pointSize:null,"undefined"!=typeof a.speed?this.speed=a.speed:null,"undefined"!=typeof a.timeout?this.timeout=a.timeout:null,"undefined"!=typeof a.autoScroll?this.autoScroll=a.autoScroll:null,"undefined"!=typeof a.colors?this.colors=a.colors:null,"undefined"!=typeof a.textColors?this.textColors=a.textColors:null,"undefined"!=typeof a.eventIn?this.eventIn=a.eventIn:null,"undefined"!=typeof a.eventOut?this.eventOut=a.eventOut:null,"undefined"!=typeof a.position?this.position=a.position:null,"undefined"!=typeof a.print?this.print=a.print:null},a.prototype._startCanvas=function(){this.lines=0,this.time=0,this.counter=0,this.running=!1,this.colors&&0!=this.colors.length||(this.colors=["#FF0000","#00FF00","#0000FF"]),this.textColors&&0!=this.textColors.length||(this.textColors=["#FFFFFF","#FFFFFF","#FFFFFF"]),this.eventIn||("undefined"!=typeof Bacon||"undefined"!=typeof Kefir?this.eventIn="onValue":"undefined"!=typeof Rx&&(this.eventIn="subscribe")),this.eventOut||("undefined"!=typeof Bacon?this.eventOut="":"undefined"!=typeof Rx?this.eventOut="dispose":"undefined"!=typeof Kefir&&(this.eventOut="_clear")),this.canvas=document.createElement("DIV"),this.canvasIn=document.createElement("DIV"),this.canvas.style.position="relative",this.canvas.style.width="100%",this.canvas.style.overflowX="auto",this.canvas.style.overflowY="hidden",this.canvasIn.style.position="relative",this.canvasIn.style.width=0,this.canvas.appendChild(this.canvasIn),this.position.appendChild(this.canvas),this.start();for(var a in this.streams)this.addStream(this.streams[a],!0)},a.prototype.addStream=function(a,b){"undefined"==typeof b&&(b=!1),b||this.streams.push(a);var c=this.lines,d=document.createElement("DIV"),e=this.colors[this.counter],f=this.textColors[this.counter];if(d.style.position="absolute",d.style.width="100%",d.style.top=this.lines*this.lineSize+this.pointSize+"px",d.style.left=0,d.style.height="1px",d.style.background="#000",this.canvasIn.appendChild(d),this.eventIn&&"function"==typeof a[this.eventIn]){var g=this,h=a[this.eventIn](function(a){if(g.running){var b=document.createElement("DIV");b.style.borderRadius="50%",b.style.minWidth=g.pointSize+"px",b.style.minHeight=g.pointSize+"px",b.style.position="absolute",b.style.top=c*g.lineSize+g.pointSize/2+"px",b.style.background=e,b.style.cursor="pointer",b.style.left=g.time+"px",b.style.color=f,"object"!=typeof a?(b.title=a,g.print&&(b.innerHTML=a)):b.title="Object: Click to view value via Javascript Console",b.onclick=function(){console.log(a)},g.canvasIn.appendChild(b)}});this.events.push(h)}this.counter++,this.counter=this.counter%3,this.lines++,this.canvas.style.height=(this.lines+1)*this.lineSize+"px",this.canvasIn.style.height=this.canvas.style.height},a.prototype.stop=function(){this.running&&(this.running=!1,this.interval&&clearInterval(this.interval))},a.prototype.start=function(){if(!this.running){this.running=!0;var a=this;this.interval=setInterval(function(){a.running&&(a.time+=a.speed,a.canvasIn.style.width=a.time+"px",a.autoScroll&&(a.canvas.scrollLeft=a.time))},this.timeout)}},a.prototype.setAutoScroll=function(a){this.autoScroll=a},a.prototype.restart=function(){this.stop(),this.canvas.parentNode.removeChild(this.canvas);for(var a in this.events)""===this.eventOut?this.events[a]():eventOut&&this.events[a][this.eventOut]();this.events=[],this._startCanvas()},window.Percussion=a}();
3 |
--------------------------------------------------------------------------------
/dist/Percussion.js:
--------------------------------------------------------------------------------
1 | /*! Percussion v0.1.0 | (c) 2015 grisendo */
2 |
3 | (function() {
4 |
5 | var Percussion = function(options) {
6 |
7 | if (typeof(options) === 'undefined') {
8 | options = {};
9 | }
10 |
11 | this.lineSize = 20;
12 | this.pointSize = 10;
13 | this.speed = 20;
14 | this.timeout = 250;
15 | this.autoScroll = true;
16 | this.colors = [];
17 | this.textColors = [];
18 | this.eventIn = null;
19 | this.eventOut = null;
20 | this.position = document.body;
21 | this.print = false;
22 |
23 | this._setOptions(options);
24 |
25 | this.interval = null;
26 | this.canvas = null;
27 | this.canvasIn = null;
28 | this.running = false;
29 | this.lines = 0;
30 | this.time = 0;
31 | this.counter = 0;
32 | this.streams = [];
33 | this.events = [];
34 |
35 | this._startCanvas();
36 |
37 | };
38 |
39 | Percussion.prototype._setOptions = function(options) {
40 | (typeof(options.lineSize) !== 'undefined') ? (this.lineSize = options.lineSize) : null;
41 | (typeof(options.pointSize) !== 'undefined') ? (this.pointSize = options.pointSize) : null;
42 | (typeof(options.speed) !== 'undefined') ? (this.speed = options.speed) : null;
43 | (typeof(options.timeout) !== 'undefined') ? (this.timeout = options.timeout) : null;
44 | (typeof(options.autoScroll) !== 'undefined') ? (this.autoScroll = options.autoScroll) : null;
45 | (typeof(options.colors) !== 'undefined') ? (this.colors = options.colors) : null;
46 | (typeof(options.textColors) !== 'undefined') ? (this.textColors = options.textColors) : null;
47 | (typeof(options.eventIn) !== 'undefined') ? (this.eventIn = options.eventIn) : null;
48 | (typeof(options.eventOut) !== 'undefined') ? (this.eventOut = options.eventOut) : null;
49 | (typeof(options.position) !== 'undefined') ? (this.position = options.position) : null;
50 | (typeof(options.print) !== 'undefined') ? (this.print = options.print) : null;
51 | };
52 |
53 | Percussion.prototype._startCanvas = function() {
54 | this.lines = 0;
55 | this.time = 0;
56 | this.counter = 0;
57 | this.running = false;
58 | if (!this.colors || this.colors.length == 0) {
59 | this.colors = ['#FF0000', '#00FF00', '#0000FF'];
60 | }
61 | if (!this.textColors || this.textColors.length == 0) {
62 | this.textColors = ['#FFFFFF', '#FFFFFF', '#FFFFFF'];
63 | }
64 | if (!this.eventIn) {
65 | if ((typeof(Bacon) !== 'undefined') || (typeof(Kefir) !== 'undefined')) {
66 | this.eventIn = 'onValue';
67 | }
68 | else if (typeof(Rx) !== 'undefined') {
69 | this.eventIn = 'subscribe';
70 | }
71 | }
72 | if (!this.eventOut) {
73 | if (typeof(Bacon) !== 'undefined') {
74 | this.eventOut = '';
75 | }
76 | else if (typeof(Rx) !== 'undefined') {
77 | this.eventOut = 'dispose';
78 | }
79 | else if (typeof(Kefir) !== 'undefined') {
80 | this.eventOut = '_clear';
81 | }
82 | }
83 | this.canvas = document.createElement('DIV');
84 | this.canvasIn = document.createElement('DIV');
85 | this.canvas.style.position = 'relative';
86 | this.canvas.style.width = '100%';
87 | this.canvas.style.overflowX = 'auto';
88 | this.canvas.style.overflowY = 'hidden';
89 | this.canvasIn.style.position = 'relative';
90 | this.canvasIn.style.width = 0;
91 | this.canvas.appendChild(this.canvasIn);
92 | this.position.appendChild(this.canvas);
93 | this.start();
94 | for (var key in this.streams) {
95 | this.addStream(this.streams[key], true);
96 | }
97 | };
98 |
99 | Percussion.prototype.addStream = function(stream, recover) {
100 | if (typeof(recover) === 'undefined') {
101 | recover = false;
102 | }
103 | if (!recover) {
104 | this.streams.push(stream);
105 | }
106 | var currentLine = this.lines;
107 | var line = document.createElement('DIV');
108 | var color = this.colors[this.counter];
109 | var textColor = this.textColors[this.counter];
110 | line.style.position = 'absolute';
111 | line.style.width = '100%';
112 | line.style.top = (this.lines * this.lineSize + this.pointSize) + 'px';
113 | line.style.left = 0;
114 | line.style.height = '1px';
115 | line.style.background = '#000';
116 | this.canvasIn.appendChild(line);
117 | if (this.eventIn && (typeof(stream[this.eventIn]) === 'function')) {
118 | var percussion = this;
119 | var event = stream[this.eventIn](
120 | function(data) {
121 | if (percussion.running) {
122 | var hit = document.createElement('DIV');
123 | hit.style.borderRadius = '50%';
124 | hit.style.minWidth = percussion.pointSize + 'px';
125 | hit.style.minHeight = percussion.pointSize + 'px';
126 | hit.style.position = 'absolute';
127 | hit.style.top = (currentLine * percussion.lineSize + (percussion.pointSize / 2)) + 'px';
128 | hit.style.background = color;
129 | hit.style.cursor = 'pointer';
130 | hit.style.left = percussion.time + 'px';
131 | hit.style.color = textColor;
132 | if (typeof(data) !== 'object') {
133 | hit.title = data;
134 | if (percussion.print) {
135 | hit.innerHTML = data;
136 | }
137 | }
138 | else {
139 | hit.title = 'Object: Click to view value via Javascript Console';
140 | }
141 | hit.onclick = function() {
142 | console.log(data);
143 | };
144 | percussion.canvasIn.appendChild(hit);
145 | }
146 | }
147 | );
148 | this.events.push(event);
149 | }
150 | this.counter++;
151 | this.counter = this.counter % 3;
152 | this.lines++;
153 | this.canvas.style.height = ((this.lines + 1) * this.lineSize) + 'px';
154 | this.canvasIn.style.height = this.canvas.style.height;
155 | };
156 |
157 | Percussion.prototype.stop = function() {
158 | if (!this.running) {
159 | return;
160 | }
161 | this.running = false;
162 | if (this.interval) {
163 | clearInterval(this.interval);
164 | }
165 | };
166 |
167 | Percussion.prototype.start = function() {
168 | if (this.running) {
169 | return;
170 | }
171 | this.running = true;
172 | var percussion = this;
173 | this.interval = setInterval(
174 | function() {
175 | if (percussion.running) {
176 | percussion.time += percussion.speed;
177 | percussion.canvasIn.style.width = percussion.time + 'px';
178 | if (percussion.autoScroll) {
179 | percussion.canvas.scrollLeft = percussion.time;
180 | }
181 | }
182 | },
183 | this.timeout
184 | );
185 | };
186 |
187 | Percussion.prototype.setAutoScroll = function(value) {
188 | this.autoScroll = value;
189 | };
190 |
191 | Percussion.prototype.restart = function() {
192 | this.stop();
193 | this.canvas.parentNode.removeChild(this.canvas);
194 | for (var key in this.events) {
195 | if (this.eventOut === '') {
196 | this.events[key]();
197 | }
198 | else if(eventOut) {
199 | this.events[key][this.eventOut]();
200 | }
201 | }
202 | this.events = [];
203 | this._startCanvas();
204 | };
205 |
206 | window.Percussion = Percussion;
207 |
208 | })();
209 |
--------------------------------------------------------------------------------
/examples/Percussion.js:
--------------------------------------------------------------------------------
1 | /*! Percussion v0.1.0 | (c) 2015 grisendo */
2 |
3 | (function() {
4 |
5 | var Percussion = function(options) {
6 |
7 | if (typeof(options) === 'undefined') {
8 | options = {};
9 | }
10 |
11 | this.lineSize = 20;
12 | this.pointSize = 10;
13 | this.speed = 20;
14 | this.timeout = 250;
15 | this.autoScroll = true;
16 | this.colors = [];
17 | this.textColors = [];
18 | this.eventIn = null;
19 | this.eventOut = null;
20 | this.position = document.body;
21 | this.print = false;
22 |
23 | this._setOptions(options);
24 |
25 | this.interval = null;
26 | this.canvas = null;
27 | this.canvasIn = null;
28 | this.running = false;
29 | this.lines = 0;
30 | this.time = 0;
31 | this.counter = 0;
32 | this.streams = [];
33 | this.events = [];
34 |
35 | this._startCanvas();
36 |
37 | };
38 |
39 | Percussion.prototype._setOptions = function(options) {
40 | (typeof(options.lineSize) !== 'undefined') ? (this.lineSize = options.lineSize) : null;
41 | (typeof(options.pointSize) !== 'undefined') ? (this.pointSize = options.pointSize) : null;
42 | (typeof(options.speed) !== 'undefined') ? (this.speed = options.speed) : null;
43 | (typeof(options.timeout) !== 'undefined') ? (this.timeout = options.timeout) : null;
44 | (typeof(options.autoScroll) !== 'undefined') ? (this.autoScroll = options.autoScroll) : null;
45 | (typeof(options.colors) !== 'undefined') ? (this.colors = options.colors) : null;
46 | (typeof(options.textColors) !== 'undefined') ? (this.textColors = options.textColors) : null;
47 | (typeof(options.eventIn) !== 'undefined') ? (this.eventIn = options.eventIn) : null;
48 | (typeof(options.eventOut) !== 'undefined') ? (this.eventOut = options.eventOut) : null;
49 | (typeof(options.position) !== 'undefined') ? (this.position = options.position) : null;
50 | (typeof(options.print) !== 'undefined') ? (this.print = options.print) : null;
51 | };
52 |
53 | Percussion.prototype._startCanvas = function() {
54 | this.lines = 0;
55 | this.time = 0;
56 | this.counter = 0;
57 | this.running = false;
58 | if (!this.colors || this.colors.length == 0) {
59 | this.colors = ['#FF0000', '#00FF00', '#0000FF'];
60 | }
61 | if (!this.textColors || this.textColors.length == 0) {
62 | this.textColors = ['#FFFFFF', '#FFFFFF', '#FFFFFF'];
63 | }
64 | if (!this.eventIn) {
65 | if ((typeof(Bacon) !== 'undefined') || (typeof(Kefir) !== 'undefined')) {
66 | this.eventIn = 'onValue';
67 | }
68 | else if (typeof(Rx) !== 'undefined') {
69 | this.eventIn = 'subscribe';
70 | }
71 | }
72 | if (!this.eventOut) {
73 | if (typeof(Bacon) !== 'undefined') {
74 | this.eventOut = '';
75 | }
76 | else if (typeof(Rx) !== 'undefined') {
77 | this.eventOut = 'dispose';
78 | }
79 | else if (typeof(Kefir) !== 'undefined') {
80 | this.eventOut = '_clear';
81 | }
82 | }
83 | this.canvas = document.createElement('DIV');
84 | this.canvasIn = document.createElement('DIV');
85 | this.canvas.style.position = 'relative';
86 | this.canvas.style.width = '100%';
87 | this.canvas.style.overflowX = 'auto';
88 | this.canvas.style.overflowY = 'hidden';
89 | this.canvasIn.style.position = 'relative';
90 | this.canvasIn.style.width = 0;
91 | this.canvas.appendChild(this.canvasIn);
92 | this.position.appendChild(this.canvas);
93 | this.start();
94 | for (var key in this.streams) {
95 | this.addStream(this.streams[key], true);
96 | }
97 | };
98 |
99 | Percussion.prototype.addStream = function(stream, recover) {
100 | if (typeof(recover) === 'undefined') {
101 | recover = false;
102 | }
103 | if (!recover) {
104 | this.streams.push(stream);
105 | }
106 | var currentLine = this.lines;
107 | var line = document.createElement('DIV');
108 | var color = this.colors[this.counter];
109 | var textColor = this.textColors[this.counter];
110 | line.style.position = 'absolute';
111 | line.style.width = '100%';
112 | line.style.top = (this.lines * this.lineSize + this.pointSize) + 'px';
113 | line.style.left = 0;
114 | line.style.height = '1px';
115 | line.style.background = '#000';
116 | this.canvasIn.appendChild(line);
117 | if (this.eventIn && (typeof(stream[this.eventIn]) === 'function')) {
118 | var percussion = this;
119 | var event = stream[this.eventIn](
120 | function(data) {
121 | if (percussion.running) {
122 | var hit = document.createElement('DIV');
123 | hit.style.borderRadius = '50%';
124 | hit.style.minWidth = percussion.pointSize + 'px';
125 | hit.style.minHeight = percussion.pointSize + 'px';
126 | hit.style.position = 'absolute';
127 | hit.style.top = (currentLine * percussion.lineSize + (percussion.pointSize / 2)) + 'px';
128 | hit.style.background = color;
129 | hit.style.cursor = 'pointer';
130 | hit.style.left = percussion.time + 'px';
131 | hit.style.color = textColor;
132 | if (typeof(data) !== 'object') {
133 | hit.title = data;
134 | if (percussion.print) {
135 | hit.innerHTML = data;
136 | }
137 | }
138 | else {
139 | hit.title = 'Object: Click to view value via Javascript Console';
140 | }
141 | hit.onclick = function() {
142 | console.log(data);
143 | };
144 | percussion.canvasIn.appendChild(hit);
145 | }
146 | }
147 | );
148 | this.events.push(event);
149 | }
150 | this.counter++;
151 | this.counter = this.counter % 3;
152 | this.lines++;
153 | this.canvas.style.height = ((this.lines + 1) * this.lineSize) + 'px';
154 | this.canvasIn.style.height = this.canvas.style.height;
155 | };
156 |
157 | Percussion.prototype.stop = function() {
158 | if (!this.running) {
159 | return;
160 | }
161 | this.running = false;
162 | if (this.interval) {
163 | clearInterval(this.interval);
164 | }
165 | };
166 |
167 | Percussion.prototype.start = function() {
168 | if (this.running) {
169 | return;
170 | }
171 | this.running = true;
172 | var percussion = this;
173 | this.interval = setInterval(
174 | function() {
175 | if (percussion.running) {
176 | percussion.time += percussion.speed;
177 | percussion.canvasIn.style.width = percussion.time + 'px';
178 | if (percussion.autoScroll) {
179 | percussion.canvas.scrollLeft = percussion.time;
180 | }
181 | }
182 | },
183 | this.timeout
184 | );
185 | };
186 |
187 | Percussion.prototype.setAutoScroll = function(value) {
188 | this.autoScroll = value;
189 | };
190 |
191 | Percussion.prototype.restart = function() {
192 | this.stop();
193 | this.canvas.parentNode.removeChild(this.canvas);
194 | for (var key in this.events) {
195 | if (this.eventOut === '') {
196 | this.events[key]();
197 | }
198 | else if(eventOut) {
199 | this.events[key][this.eventOut]();
200 | }
201 | }
202 | this.events = [];
203 | this._startCanvas();
204 | };
205 |
206 | window.Percussion = Percussion;
207 |
208 | })();
209 |
--------------------------------------------------------------------------------