src/js/widgets/stackGraphWidget.js
branchpopcorn-port
changeset 842 4ae2247a59f4
parent 834 573c7ca752e0
equal deleted inserted replaced
841:8da49ff273e0 842:4ae2247a59f4
     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     })