3 } |
3 } |
4 |
4 |
5 IriSP.StackGraphWidget.prototype = new IriSP.Widget(); |
5 IriSP.StackGraphWidget.prototype = new IriSP.Widget(); |
6 |
6 |
7 IriSP.StackGraphWidget.prototype.draw = function() { |
7 IriSP.StackGraphWidget.prototype.draw = function() { |
8 var _ = IriSP._, |
8 var _ = IriSP._; |
9 _defaultTags = [ |
|
10 { |
|
11 "keywords" : [ "++" ], |
|
12 "description" : "positif", |
|
13 "color" : "#1D973D" |
|
14 }, |
|
15 { |
|
16 "keywords" : [ "--" ], |
|
17 "description" : "negatif", |
|
18 "color" : "#CE0A15" |
|
19 }, |
|
20 { |
|
21 "keywords" : [ "==" ], |
|
22 "description" : "reference", |
|
23 "color" : "#C5A62D" |
|
24 }, |
|
25 { |
|
26 "keywords" : [ "??" ], |
|
27 "description" : "question", |
|
28 "color" : "#036AAE" |
|
29 } |
|
30 ], |
|
31 _defaultDefColor = "#585858"; |
|
32 this.height = this._config.height || 50; |
9 this.height = this._config.height || 50; |
33 this.width = this.selector.width(); |
10 this.width = this.selector.width(); |
34 this.isStreamGraph = this._config.streamgraph || false; |
11 this.slices = this._config.slices || ~~(this.width/(this.streamgraph ? 20 : 5)); |
35 this.sliceCount = this._config.slices || ~~(this.width/(this.isStreamGraph ? 20 : 5)); |
12 _(this.tags).each(function(_a) { |
36 this.tagconf = (this._config.tags |
|
37 ? this._config.tags |
|
38 : _defaultTags); |
|
39 IriSP._(this.tagconf).each(function(_a) { |
|
40 _a.regexp = new RegExp(_(_a.keywords).map(function(_k) { |
13 _a.regexp = new RegExp(_(_a.keywords).map(function(_k) { |
41 return _k.replace(/([\W])/gm,'\\$1'); |
14 return _k.replace(/([\W])/gm,'\\$1'); |
42 }).join("|"),"im") |
15 }).join("|"),"im") |
43 }); |
16 }); |
44 this.defaultcolorconf = (this._config.defaultcolor |
|
45 ? this._config.defaultcolor |
|
46 : _defaultDefColor); |
|
47 this.paper = new Raphael(this.selector[0], this.width, this.height); |
17 this.paper = new Raphael(this.selector[0], this.width, this.height); |
48 this.groups = []; |
18 this.groups = []; |
49 this.duration = this._serializer.getDuration(); |
19 this.duration = this.getDuration(); |
50 |
20 |
51 var _annotationType = this._serializer.getTweets(), |
21 var _annotationType = this._serializer.getTweets(), |
52 _sliceDuration = ~~ ( this.duration / this.sliceCount), |
22 _sliceDuration = ~~ ( this.duration / this.slices), |
53 _annotations = this._serializer._data.annotations, |
23 _annotations = this._serializer._data.annotations, |
54 _groupedAnnotations = _(_.range(this.sliceCount)).map(function(_i) { |
24 _groupedAnnotations = _(_.range(this.slices)).map(function(_i) { |
55 return _(_annotations).filter(function(_a){ |
25 return _(_annotations).filter(function(_a){ |
56 return (_a.begin <= (1 + _i) * _sliceDuration) && (_a.end >= _i * _sliceDuration) |
26 return (_a.begin <= (1 + _i) * _sliceDuration) && (_a.end >= _i * _sliceDuration) |
57 }); |
27 }); |
58 }), |
28 }), |
59 _max = IriSP._(_groupedAnnotations).max(function(_g) { |
29 _max = IriSP._(_groupedAnnotations).max(function(_g) { |
60 return _g.length |
30 return _g.length |
61 }).length, |
31 }).length, |
62 _scale = this.height / _max, |
32 _scale = this.height / _max, |
63 _width = this.width / this.sliceCount, |
33 _width = this.width / this.slices, |
64 _showTitle = !this._config.excludeTitle, |
34 _showTitle = !this._config.excludeTitle, |
65 _showDescription = !this._config.excludeDescription; |
35 _showDescription = !this._config.excludeDescription; |
66 |
36 |
67 |
37 |
68 var _paths = _(this.tagconf).map(function() { |
38 var _paths = _(this.tags).map(function() { |
69 return []; |
39 return []; |
70 }); |
40 }); |
71 _paths.push([]); |
41 _paths.push([]); |
72 |
42 |
73 for (var i = 0; i < this.sliceCount; i++) { |
43 for (var i = 0; i < this.slices; i++) { |
74 var _group = _groupedAnnotations[i]; |
44 var _group = _groupedAnnotations[i]; |
75 if (_group) { |
45 if (_group) { |
76 var _vol = _(this.tagconf).map(function() { |
46 var _vol = _(this.tags).map(function() { |
77 return 0; |
47 return 0; |
78 }); |
48 }); |
79 for (var j = 0; j < _group.length; j++){ |
49 for (var j = 0; j < _group.length; j++){ |
80 var _txt = (_showTitle ? _group[j].content.title : '') + ' ' + (_showDescription ? _group[j].content.description : '') |
50 var _txt = (_showTitle ? _group[j].content.title : '') + ' ' + (_showDescription ? _group[j].content.description : '') |
81 var _tags = _(this.tagconf).map(function(_tag) { |
51 var _tags = _(this.tags).map(function(_tag) { |
82 return (_txt.search(_tag.regexp) == -1 ? 0 : 1) |
52 return (_txt.search(_tag.regexp) == -1 ? 0 : 1) |
83 }), |
53 }), |
84 _nbtags = _(_tags).reduce(function(_a,_b) { |
54 _nbtags = _(_tags).reduce(function(_a,_b) { |
85 return _a + _b; |
55 return _a + _b; |
86 }, 0); |
56 }, 0); |
94 return _a + _b; |
64 return _a + _b; |
95 }, 0), |
65 }, 0), |
96 _nbneutre = _group.length - _nbtags, |
66 _nbneutre = _group.length - _nbtags, |
97 _h = _nbneutre * _scale, |
67 _h = _nbneutre * _scale, |
98 _base = this.height - _h; |
68 _base = this.height - _h; |
99 if (!this.isStreamGraph) { |
69 if (!this.streamgraph) { |
100 this.paper.rect(i * _width, _base, _width - 1, _h ).attr({ |
70 this.paper.rect(i * _width, _base, _width - 1, _h ).attr({ |
101 "stroke" : "none", |
71 "stroke" : "none", |
102 "fill" : this.defaultcolorconf |
72 "fill" : this.defaultcolor |
103 }); |
73 }); |
104 } |
74 } |
105 _paths[0].push(_base); |
75 _paths[0].push(_base); |
106 for (var j = 0; j < this.tagconf.length; j++) { |
76 for (var j = 0; j < this.tags.length; j++) { |
107 _h = _vol[j] * _scale; |
77 _h = _vol[j] * _scale; |
108 _base = _base - _h; |
78 _base = _base - _h; |
109 if (!this.isStreamGraph) { |
79 if (!this.streamgraph) { |
110 this.paper.rect(i * _width, _base, _width - 1, _h ).attr({ |
80 this.paper.rect(i * _width, _base, _width - 1, _h ).attr({ |
111 "stroke" : "none", |
81 "stroke" : "none", |
112 "fill" : this.tagconf[j].color |
82 "fill" : this.tags[j].color |
113 }); |
83 }); |
114 } |
84 } |
115 _paths[j+1].push(_base); |
85 _paths[j+1].push(_base); |
116 } |
86 } |
117 this.groups.push(_(_vol).map(function(_v) { |
87 this.groups.push(_(_vol).map(function(_v) { |
119 })) |
89 })) |
120 } else { |
90 } else { |
121 for (var j = 0; j < _paths.length; j++) { |
91 for (var j = 0; j < _paths.length; j++) { |
122 _paths[j].push(this.height); |
92 _paths[j].push(this.height); |
123 } |
93 } |
124 this.groups.push(_(this.tagconf).map(function() { |
94 this.groups.push(_(this.tags).map(function() { |
125 return 0; |
95 return 0; |
126 })); |
96 })); |
127 } |
97 } |
128 } |
98 } |
129 |
99 |
130 if (this.isStreamGraph) { |
100 if (this.streamgraph) { |
131 for (var j = _paths.length - 1; j >= 0; j--) { |
101 for (var j = _paths.length - 1; j >= 0; j--) { |
132 var _d = _(_paths[j]).reduce(function(_memo, _v, _k) { |
102 var _d = _(_paths[j]).reduce(function(_memo, _v, _k) { |
133 return _memo + ( _k |
103 return _memo + ( _k |
134 ? 'C' + (_k * _width) + ' ' + _paths[j][_k - 1] + ' ' + (_k * _width) + ' ' + _v + ' ' + ((_k + .5) * _width) + ' ' + _v |
104 ? 'C' + (_k * _width) + ' ' + _paths[j][_k - 1] + ' ' + (_k * _width) + ' ' + _v + ' ' + ((_k + .5) * _width) + ' ' + _v |
135 : 'M0 ' + _v + 'L' + (.5*_width) + ' ' + _v ) |
105 : 'M0 ' + _v + 'L' + (.5*_width) + ' ' + _v ) |
136 },'') + 'L' + this.width + ' ' + _paths[j][_paths[j].length - 1] + 'L' + this.width + ' ' + this.height + 'L0 ' + this.height; |
106 },'') + 'L' + this.width + ' ' + _paths[j][_paths[j].length - 1] + 'L' + this.width + ' ' + this.height + 'L0 ' + this.height; |
137 this.paper.path(_d).attr({ |
107 this.paper.path(_d).attr({ |
138 "stroke" : "none", |
108 "stroke" : "none", |
139 "fill" : (j ? this.tagconf[j-1].color : this.defaultcolorconf) |
109 "fill" : (j ? this.tags[j-1].color : this.defaultcolor) |
140 }); |
110 }); |
141 } |
111 } |
142 } |
112 } |
143 this.rectangleFocus = this.paper.rect(0,0,_width,this.height) |
113 this.rectangleFocus = this.paper.rect(0,0,_width,this.height) |
144 .attr({ |
114 .attr({ |
160 .click(IriSP.wrap(this, this.clickHandler)) |
130 .click(IriSP.wrap(this, this.clickHandler)) |
161 .mousemove(function(_e) { |
131 .mousemove(function(_e) { |
162 _this.updateTooltip(_e); |
132 _this.updateTooltip(_e); |
163 // Trace |
133 // Trace |
164 var relX = _e.pageX - _this.selector.offset().left; |
134 var relX = _e.pageX - _this.selector.offset().left; |
165 var _duration = _this._serializer.getDuration(); |
135 var _duration = _this.getDuration(); |
166 var _time = parseInt((relX / _this.width) * _duration); |
136 var _time = parseInt((relX / _this.width) * _duration); |
167 _this._Popcorn.trigger("IriSP.TraceWidget.MouseEvents", { |
137 _this._Popcorn.trigger("IriSP.TraceWidget.MouseEvents", { |
168 "widget" : "StackGraphWidget", |
138 "widget" : "StackGraphWidget", |
169 "type": "mousemove", |
139 "type": "mousemove", |
170 "x": _e.pageX, |
140 "x": _e.pageX, |
201 this._Popcorn.trigger("IriSP.StackGraphWidget.clicked", newTime); |
171 this._Popcorn.trigger("IriSP.StackGraphWidget.clicked", newTime); |
202 this._Popcorn.currentTime(newTime); |
172 this._Popcorn.currentTime(newTime); |
203 }; |
173 }; |
204 |
174 |
205 IriSP.StackGraphWidget.prototype.updateTooltip = function(event) { |
175 IriSP.StackGraphWidget.prototype.updateTooltip = function(event) { |
206 var _segment = Math.max(0,Math.min(this.groups.length - 1, Math.floor(this.sliceCount * (event.pageX - this.selector.offset().left)/this.width))), |
176 var _segment = Math.max(0,Math.min(this.groups.length - 1, Math.floor(this.slices * (event.pageX - this.selector.offset().left)/this.width))), |
207 _valeurs = this.groups[_segment], |
177 _valeurs = this.groups[_segment], |
208 _width = this.width / this.sliceCount, |
178 _width = this.width / this.slices, |
209 _html = '<ul style="list-style: none; margin: 0; padding: 0;">' + IriSP._(this.tagconf).map(function(_tag, _i) { |
179 _html = '<ul style="list-style: none; margin: 0; padding: 0;">' + IriSP._(this.tags).map(function(_tag, _i) { |
210 return '<li style="clear: both;"><span style="float: left; width: 10px; height: 10px; margin: 2px; background: ' |
180 return '<li style="clear: both;"><span style="float: left; width: 10px; height: 10px; margin: 2px; background: ' |
211 + _tag.color |
181 + _tag.color |
212 + ';"></span>' |
182 + ';"></span>' |
213 + ~~(100 * _valeurs[_i]) |
183 + ~~(100 * _valeurs[_i]) |
214 + '% de ' |
184 + '% de ' |
215 + _tag.description |
185 + _tag.description |
216 + '</li>'; |
186 + '</li>'; |
217 }).join('') + '</ul>'; |
187 }).join('') + '</ul>'; |
218 this.TooltipWidget._shown = false; // Vraiment, on ne peut pas ouvrir le widget s'il n'est pas encore ouvert ? |
188 this.TooltipWidget._shown = false; // Vraiment, on ne peut pas ouvrir le widget s'il n'est pas encore ouvert ? |
219 this.TooltipWidget.show('','',(_segment + .5)* this.width / this.sliceCount, 0); |
189 this.TooltipWidget.show('','',(_segment + .5)* this.width / this.slices, 0); |
220 this.TooltipWidget.selector.find(".tip").html(_html); |
190 this.TooltipWidget.selector.find(".tip").html(_html); |
221 this.rectangleFocus.attr({ |
191 this.rectangleFocus.attr({ |
222 "x" : _segment * _width, |
192 "x" : _segment * _width, |
223 "opacity" : .4 |
193 "opacity" : .4 |
224 }) |
194 }) |