client/annotviz/app/js/annotstimeline.js
changeset 134 119b6193c493
parent 131 0bb70072a56f
child 135 d3066fa80a81
equal deleted inserted replaced
133:12f782a13fa2 134:119b6193c493
    42     this.height = opts.height;
    42     this.height = opts.height;
    43     this.intervalHeight = opts.intervalHeight;
    43     this.intervalHeight = opts.intervalHeight;
    44     this.intervalWidth = opts.intervalWidth;
    44     this.intervalWidth = opts.intervalWidth;
    45     this.maxCellHeight = opts.maxCellHeight;
    45     this.maxCellHeight = opts.maxCellHeight;
    46     this.annotCategories = opts.annotCategories;
    46     this.annotCategories = opts.annotCategories;
    47 	this.startTs = options.startTs || Date.now();
    47     this.startTs = options.startTs || Date.now();
    48     this.showClockGraphics = opts.showClockGraphics;
    48     this.showClockGraphics = opts.showClockGraphics;
    49     this.archive = opts.archive;
    49     this.archive = opts.archive;
    50     
    50 
    51     this.circleX = opts.circleX || (this.width/2);
    51     this.circleX = opts.circleX || (this.width/2);
    52     this.circleY = opts.circleY || (this.height/2);
    52     this.circleY = opts.circleY || (this.height/2);
    53     this.radius = opts.radius;
    53     this.radius = opts.radius;
    54     var perimeter = 2*Math.PI* this.radius;
    54     var perimeter = 2*Math.PI* this.radius;
    55     this.intervalDuration = (this.intervalWidth * this.duration / perimeter);
    55     this.intervalDuration = (this.intervalWidth * this.duration / perimeter);
    56     
    56 
    57     var channel = opts.channel;
    57     var channel = opts.channel;
    58     var eventCode = opts.eventCode;
    58     var eventCode = opts.eventCode;
    59     var serverUrl = opts.serverUrl;
    59     var serverUrl = opts.serverUrl;
    60     var maxPages = opts.maxPages;
    60     var maxPages = opts.maxPages;
    61     
    61 
    62     var totalIndex = Math.floor( perimeter/this.intervalWidth);
    62     var totalIndex = Math.floor( perimeter/this.intervalWidth);
    63 
    63 
    64     this.cells = []
    64     this.cells = [];
    65     for (var i=0; i<(perimeter/this.intervalWidth) ; i++){
    65     for (var i=0; i<(perimeter/this.intervalWidth) ; i++){
    66     	this.cells[i] = [];
    66         this.cells[i] = [];
    67     	this.cells[i].i = i;
    67         this.cells[i].i = i;
    68     	this.cells[i].totalAnnots = 0;
    68         this.cells[i].totalAnnots = 0;
    69     	this.cells[i].categories = {};
    69         this.cells[i].categories = {};
    70     }
    70     }
    71 
    71 
    72     var ws = opts.ws;
    72     var ws = opts.ws;
    73     var stageView = opts.stageView;
    73     var stageView = opts.stageView;
    74 
    74 
    75     //draw the base - circle and line to locate the scene
    75     //draw the base - circle and line to locate the scene
    76     var graphics = new PIXI.Graphics();
    76     var graphics = new PIXI.Graphics();
    77     graphics.lineStyle(2, 0x646464)
    77     graphics.lineStyle(2, 0x646464)
    78     	.drawCircle(this.circleX, this.circleY, this.radius - 3)
    78         .drawCircle(this.circleX, this.circleY, this.radius - 3)
    79     	.endFill()
    79         .endFill();
    80     this.container.addChild(graphics);
    80     this.container.addChild(graphics);
    81 
    81 
    82     stageView.registerComponent(this);
    82     stageView.registerComponent(this);
    83 
    83 
    84 	var loadArchives = function() {
    84     var loadArchives = function() {
    85         //start timeBegin end startTime
    85         //start timeBegin end startTime
    86         //query -> need channel + eventCode
    86         //query -> need channel + eventCode
    87         //iterate over data fill cells
    87         //iterate over data fill cells
    88         var startTs = _this.timeBegin;
    88         var startTs = _this.timeBegin;
    89         var endTs = _this.startTs;
    89         var endTs = _this.startTs;
   123     };
   123     };
   124 
   124 
   125     //Add Annotation to the TimeLine
   125     //Add Annotation to the TimeLine
   126     this.addAnnot = function(data){
   126     this.addAnnot = function(data){
   127 
   127 
   128     	var ts = Date.parse(data.ts);
   128         var ts = Date.parse(data.ts);
   129     	var colorsDef;
   129         var colorsDef;
   130     	_(this.annotCategories).eachRight(function(cdef) {
   130         _(this.annotCategories).eachRight(function(cdef) {
   131             if(cdef.ts < ts) {
   131             if(cdef.ts < ts) {
   132                 colorsDef = cdef;
   132                 colorsDef = cdef;
   133                 return false;
   133                 return false;
   134             }
   134             }
   135         });
   135         });
   136 
   136 
   137     	if (this.timeEnd > ts){
   137         if (this.timeEnd > ts){
   138 	    	var i = Math.floor((ts - this.timeBegin)/(1000*this.intervalDuration));
   138             var i = Math.floor((ts - this.timeBegin)/(1000*this.intervalDuration));
   139 
   139 
   140 	    	if (typeof(this.cells[i].graphics) === 'undefined'){
   140             if (typeof(this.cells[i].graphics) === 'undefined'){
   141 	    		this.initCell(this.cells[i], colorsDef);
   141                 this.initCell(this.cells[i], colorsDef);
   142 	    	}
   142             }
   143 
   143 
   144 	    	if (typeof(colorsDef.colors[data.content.category.code]) !== 'undefined'){
   144             var annotCode;
   145 	    		var annotCode = data.content.category.code;
   145             if (typeof(colorsDef.colors[data.content.category.code]) !== 'undefined'){
   146 	    	} else {
   146                 annotCode = data.content.category.code;
   147 	    		var annotCode = 'default';
   147             } else {
   148 	    	}
   148                 annotCode = 'default';
   149 
   149             }
   150 			this.cells[i].categories[annotCode].count += 1;
   150 
   151 			this.cells[i].totalAnnots +=1;
   151             this.cells[i].categories[annotCode].count += 1;
   152 			this.redrawCell(this.cells[i], colorsDef);
   152             this.cells[i].totalAnnots +=1;
   153     	}
   153             this.redrawCell(this.cells[i], colorsDef);
       
   154         }
   154     };
   155     };
   155 
   156 
   156     this.initClockGraphics = function() {
   157     this.initClockGraphics = function() {
   157 	    var tBeg = new PIXI.Text(Utils.formatTime(this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   158         var tBeg = new PIXI.Text(Utils.formatTime(this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   158 	    tBeg.x = this.circleX + 15;
   159         tBeg.x = this.circleX + 15;
   159 	    tBeg.y = this.circleY - this.radius - this.maxCellHeight - 10;
   160         tBeg.y = this.circleY - this.radius - this.maxCellHeight - 10;
   160 	    this.container.addChild(tBeg);
   161         this.container.addChild(tBeg);
   161 
   162 
   162 	    var tEnd = new PIXI.Text(Utils.formatTime(this.timeEnd), { font: '12pt Gothic Standard', fill: '#646464' });
   163         var tEnd = new PIXI.Text(Utils.formatTime(this.timeEnd), { font: '12pt Gothic Standard', fill: '#646464' });
   163 	    tEnd.x = this.circleX - 15 - tEnd.width;
   164         tEnd.x = this.circleX - 15 - tEnd.width;
   164 	    tEnd.y = this.circleY - this.radius - this.maxCellHeight - 10;
   165         tEnd.y = this.circleY - this.radius - this.maxCellHeight - 10;
   165 	    this.container.addChild(tEnd);
   166         this.container.addChild(tEnd);
   166 
   167 
   167 	    var t15 = new PIXI.Text(Utils.formatTime(((this.timeEnd - this.timeBegin)/4) + this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   168         var t15 = new PIXI.Text(Utils.formatTime(((this.timeEnd - this.timeBegin)/4) + this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   168 	    t15.x = this.circleX + this.radius + this.maxCellHeight + 10 ;
   169         t15.x = this.circleX + this.radius + this.maxCellHeight + 10 ;
   169 	    t15.y = this.circleY - t15.height;
   170         t15.y = this.circleY - t15.height;
   170 	    t15.rotation = Math.PI /2;
   171         t15.rotation = Math.PI /2;
   171 	    this.container.addChild(t15);
   172         this.container.addChild(t15);
   172 
   173 
   173 	    var t30 = new PIXI.Text(Utils.formatTime(((this.timeEnd - this.timeBegin)/2) + this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   174         var t30 = new PIXI.Text(Utils.formatTime(((this.timeEnd - this.timeBegin)/2) + this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   174 	    t30.x = this.circleX - t30.width/2;
   175         t30.x = this.circleX - t30.width/2;
   175 	    t30.y = this.circleY + this.radius + this.maxCellHeight - 2;
   176         t30.y = this.circleY + this.radius + this.maxCellHeight - 2;
   176 	    this.container.addChild(t30);
   177         this.container.addChild(t30);
   177 
   178 
   178 	    var t45 = new PIXI.Text(Utils.formatTime(((this.timeEnd - this.timeBegin)*3/4) + this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   179         var t45 = new PIXI.Text(Utils.formatTime(((this.timeEnd - this.timeBegin)*3/4) + this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   179 	    t45.x = this.circleX - this.radius - this.maxCellHeight - 10 ;
   180         t45.x = this.circleX - this.radius - this.maxCellHeight - 10 ;
   180 	    t45.y = this.circleY + t15.height;
   181         t45.y = this.circleY + t15.height;
   181 	    t45.rotation = -Math.PI/2;
   182         t45.rotation = -Math.PI/2;
   182 	    this.container.addChild(t45);
   183         this.container.addChild(t45);
   183 	    
   184 
   184 	    var lineV = new PIXI.Graphics();
   185         var lineV = new PIXI.Graphics();
   185 	    lineV.lineStyle(1, 0x646464)
   186         lineV.lineStyle(1, 0x646464)
   186 	    	.moveTo(this.circleX, this.circleY - (this.radius/3)/2)
   187             .moveTo(this.circleX, this.circleY - (this.radius/3)/2)
   187 	    	.lineTo(this.circleX, this.circleY - this.radius - this.maxCellHeight - 10)
   188             .lineTo(this.circleX, this.circleY - this.radius - this.maxCellHeight - 10)
   188     	.endFill();
   189             .endFill();
   189 	    this.container.addChild(lineV);
   190         this.container.addChild(lineV);
   190     }
   191     };
   191 
   192 
   192     //Draw the cellule
   193     //Draw the cellule
   193     this.redrawCell = function(cell, colorsDef){
   194     this.redrawCell = function(cell, colorsDef){
   194     	var y = 0;
   195         var y = 0;
   195 
   196 
   196         //Check if total height is higher than Max Cell Height
   197         //Check if total height is higher than Max Cell Height
   197         var heightStep;
   198         var heightStep;
   198         if ((cell.totalAnnots*this.intervalHeight) > this.maxCellHeight){
   199         if ((cell.totalAnnots*this.intervalHeight) > this.maxCellHeight){
   199             heightStep = this.maxCellHeight/cell.totalAnnots;
   200             heightStep = this.maxCellHeight/cell.totalAnnots;
   200         } else {
   201         } else {
   201             heightStep = this.intervalHeight;
   202             heightStep = this.intervalHeight;
   202         }
   203         }
   203 
   204 
   204     	//Draw the rect depending on the height step calculated
   205         //Draw the rect depending on the height step calculated
   205     	for (var i=0; i< colorsDef.order.length; i++){
   206         for (var i=0; i< colorsDef.order.length; i++){
   206     		var currentCode = colorsDef.order[i];
   207             var currentCode = colorsDef.order[i];
   207 			cell.graphics.beginFill(cell.categories[currentCode].color.replace("#", "0x"))
   208             cell.graphics.beginFill(cell.categories[currentCode].color.replace('#', '0x'))
   208     			.drawRect(0, y, this.intervalWidth-1, -cell.categories[currentCode].count * heightStep)
   209                 .drawRect(0, y, this.intervalWidth-1, -cell.categories[currentCode].count * heightStep)
   209     			.endFill();
   210                 .endFill();
   210     		y -= cell.categories[currentCode].count*heightStep;
   211             y -= cell.categories[currentCode].count*heightStep;
   211     	}
   212         }
   212     }
   213     };
   213 
   214 
   214     this.initCell = function(cell, colorsDef){
   215     this.initCell = function(cell, colorsDef){
   215     	cell.graphics = new PIXI.Graphics();
   216         cell.graphics = new PIXI.Graphics();
   216     	cell.graphics.position.x = this.circleX + this.radius * Math.sin(cell.i*(360/totalIndex)*(Math.PI/180));
   217         cell.graphics.position.x = this.circleX + this.radius * Math.sin(cell.i*(360/totalIndex)*(Math.PI/180));
   217     	cell.graphics.position.y = this.circleY - this.radius * Math.cos(cell.i*(360/totalIndex)*(Math.PI/180));
   218         cell.graphics.position.y = this.circleY - this.radius * Math.cos(cell.i*(360/totalIndex)*(Math.PI/180));
   218     	cell.graphics.rotation = (cell.i)*(360/totalIndex)*(Math.PI/180) + (360/(totalIndex*2))*(Math.PI/180);
   219         cell.graphics.rotation = (cell.i)*(360/totalIndex)*(Math.PI/180) + (360/(totalIndex*2))*(Math.PI/180);
   219     	this.container.addChild(cell.graphics);
   220         this.container.addChild(cell.graphics);
   220 
   221 
   221     	for (var category in colorsDef.colors){
   222         for (var category in colorsDef.colors){
   222     		cell.categories[category] = {
   223             cell.categories[category] = {
   223 				"count": 0,
   224                 'count': 0,
   224 				"color": colorsDef.colors[category]
   225                 'color': colorsDef.colors[category]
   225     		};
   226             };
   226     	}
   227         }
   227     	if (typeof(cell.categories['default']) === 'undefined'){
   228         if (typeof(cell.categories['default']) === 'undefined'){
   228 			cell.categories['default'] = {
   229             cell.categories['default'] = {
   229 				"count": 0,
   230                 'count': 0,
   230 				"color": colorsDef.defaultColor
   231                 'color': colorsDef.defaultColor
   231 			}
   232             };
   232     	}
   233         }
   233     }
   234     };
   234 
   235 
   235     this.init = function() {
   236     this.init = function() {
   236     	if (!this.archive){
   237         if (!this.archive){
   237 	        ws.message(function(data) {
   238             ws.message(function(data) {
   238 	            _this.addAnnot(data);
   239                 _this.addAnnot(data);
   239 	        });
   240             });
   240     	}
   241         }
   241 
   242 
   242     	if (this.showClockGraphics){this.initClockGraphics();}
   243         if (this.showClockGraphics){this.initClockGraphics();}
   243     };
   244     };
   244 
   245 
   245 
   246 
   246     this.start = function() {
   247     this.start = function() {
   247     	this.startTs = Date.now();
   248         this.startTs = Date.now();
   248         loadArchives();
   249         loadArchives();
   249     };
   250     };
   250 
   251 
   251     this.refresh = function() {
   252     this.refresh = function() {
   252 
   253 
   257 
   258 
   258     return this;
   259     return this;
   259 }
   260 }
   260 
   261 
   261 module.exports = {
   262 module.exports = {
   262 	AnnotsTimeLine: AnnotsTimeLine
   263     AnnotsTimeLine: AnnotsTimeLine
   263 };
   264 };