1 /** @class The constructor for the sparkline widget */ |
|
2 IriSP.SparklineWidget = function(Popcorn, config, Serializer) { |
|
3 IriSP.Widget.call(this, Popcorn, config, Serializer); |
|
4 |
|
5 this._oldAnnotation = null; |
|
6 this._results = []; |
|
7 |
|
8 this.slices = this._config.slices || Math.floor(this.width/20); |
|
9 if (!this.width) { |
|
10 this.width = this.selector.width(); |
|
11 } |
|
12 if (!this.height) { |
|
13 this.height = 40; |
|
14 } |
|
15 this.selector.css("height", this.height + "px"); |
|
16 if (this._config.background) { |
|
17 this.selector.css("background", this._config.background); |
|
18 } |
|
19 }; |
|
20 |
|
21 |
|
22 IriSP.SparklineWidget.prototype = new IriSP.Widget(); |
|
23 |
|
24 IriSP.SparklineWidget.prototype.clear = function() { |
|
25 |
|
26 }; |
|
27 |
|
28 /** draw the sparkline using jquery sparkline */ |
|
29 IriSP.SparklineWidget.prototype.draw = function() { |
|
30 this.duration = this.getDuration(); |
|
31 this.paper = new Raphael(this.selector[0], this.width, this.height); |
|
32 var _this = this; |
|
33 |
|
34 var views = this._serializer._data.views; |
|
35 var stat_view; |
|
36 if (!IriSP.null_or_undefined(views)) { |
|
37 for (var i = 0; i < views.length; i++) { |
|
38 var view = views[i]; |
|
39 if (view.id === "stat") { |
|
40 stat_view = view; |
|
41 break; |
|
42 } |
|
43 } |
|
44 } |
|
45 |
|
46 var _ = IriSP.underscore; |
|
47 // If we've found the correct view, feed the directly the data from the view |
|
48 // to jquery sparkline. Otherwise, compute it ourselves. |
|
49 if (!IriSP.null_or_undefined(stat_view)) { |
|
50 //console.log("sparklinewidget : using stats embedded in the json"); |
|
51 var _results = stat_view.meta.stat.split(","); |
|
52 } else { |
|
53 var _annotations = this._serializer._data.annotations; |
|
54 if (this.cinecast_version) { |
|
55 _annotations = _(_annotations).filter(function(_a) { |
|
56 return _a.type !== "cinecast:MovieExtract"; |
|
57 }); |
|
58 } |
|
59 var _sliceDuration = Math.floor( this.duration / this.slices), |
|
60 _results = _(_.range(this.slices)).map(function(_i) { |
|
61 return _(_annotations).filter(function(_a){ |
|
62 return (_a.begin <= (1 + _i) * _sliceDuration) && (_a.end >= _i * _sliceDuration) |
|
63 }).length; |
|
64 }); |
|
65 } |
|
66 var _max = Math.max(1, _(_results).max()), |
|
67 _h = this.height, |
|
68 _scale = (_h - this.lineWidth) / _max, |
|
69 _width = this.width / this.slices, |
|
70 _y = _(_results).map(function(_v) { |
|
71 return _h - (_scale * _v); |
|
72 }), |
|
73 _d = _(_y).reduce(function(_memo, _v, _k) { |
|
74 return _memo + ( _k |
|
75 ? 'C' + (_k * _width) + ' ' + _y[_k - 1] + ' ' + (_k * _width) + ' ' + _v + ' ' + ((_k + .5) * _width) + ' ' + _v |
|
76 : 'M0 ' + _v + 'L' + (.5*_width) + ' ' + _v ) |
|
77 },'') + 'L' + this.width + ' ' + _y[_y.length - 1], |
|
78 _d2 = _d + 'L' + this.width + ' ' + this.height + 'L0 ' + this.height; |
|
79 this.paper.path(_d2).attr({ |
|
80 "stroke" : "none", |
|
81 "fill" : this.fillColor |
|
82 }); |
|
83 |
|
84 this.paper.path(_d).attr({ |
|
85 "fill" : "none", |
|
86 "stroke" : this.lineColor, |
|
87 "stroke-width" : this.lineWidth |
|
88 }); |
|
89 |
|
90 this.rectangleProgress = this.paper.rect(0,0,0,this.height) |
|
91 .attr({ |
|
92 "stroke" : "none", |
|
93 "fill" : "#808080", |
|
94 "opacity" : .3 |
|
95 }); |
|
96 this.ligneProgress = this.paper.path("M0 0L0 "+this.height).attr({"stroke":"#ff00ff", "line-width" : 2}); |
|
97 // save the results in an array so that we can re-use them when a new annotation |
|
98 // is added. |
|
99 this._results = _results; |
|
100 |
|
101 this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.timeUpdateHandler)); |
|
102 // this._Popcorn.listen("IriSP.createAnnotationWidget.addedAnnotation", IriSP.wrap(this, this.handleNewAnnotation)); |
|
103 |
|
104 this.selector.click(IriSP.wrap(this, this.clickHandler)); |
|
105 }; |
|
106 |
|
107 /** react to a timeupdate event */ |
|
108 IriSP.SparklineWidget.prototype.timeUpdateHandler = function() { |
|
109 var _currentTime = this._Popcorn.currentTime(), |
|
110 _x = (1000 * _currentTime / this.duration) * this.width; |
|
111 this.rectangleProgress.attr({ |
|
112 "width" : _x |
|
113 }); |
|
114 this.ligneProgress.attr({ |
|
115 "path" : "M" + _x + " 0L" + _x + " " + this.height |
|
116 }); |
|
117 |
|
118 } |
|
119 |
|
120 /** handle clicks on the widget */ |
|
121 IriSP.SparklineWidget.prototype.clickHandler = function(event) { |
|
122 var relX = event.pageX - this.selector.offset().left; |
|
123 var newTime = ((relX / this.width) * this.duration/1000).toFixed(2); |
|
124 |
|
125 this._Popcorn.trigger("IriSP.SparklineWidget.clicked", newTime); |
|
126 this._Popcorn.currentTime(newTime); |
|
127 }; |
|
128 |
|
129 /** react when a new annotation is added */ |
|
130 IriSP.SparklineWidget.prototype.handleNewAnnotation = function(annotation) { |
|
131 // var num_columns = this._results.length; |
|
132 // var duration = this._serializer.getDuration(); |
|
133 // var time_step = Math.round(duration / num_columns); /* the time interval between two columns */ |
|
134 // var begin = +annotation.begin; |
|
135 // var end = +annotation.end; |
|
136 // |
|
137 // /* increment all the values between the beginning and the end of the annotation */ |
|
138 // var index_begin = Math.floor(begin / time_step); |
|
139 // var index_end = Math.floor(end / time_step); |
|
140 // |
|
141 // for (var i = index_begin; i < Math.min(index_end, this._results.length); i++) { |
|
142 // this._results[i]++; |
|
143 // } |
|
144 // |
|
145 // this.selector.find(".Ldt-sparkLine").sparkline(this._results, {lineColor: "#7492b4", fillColor: "#aeaeb8", |
|
146 // spotColor: "#b70056", |
|
147 // width: this.width, height: this.height}); |
|
148 }; |
|