client/annotviz/app/js/annotstimeline.js
changeset 112 3e075a48e19e
parent 109 8546e2181a73
child 113 7531e4180915
equal deleted inserted replaced
111:a7b72620d227 112:3e075a48e19e
     9 
     9 
    10 var PIXI = require('pixi');
    10 var PIXI = require('pixi');
    11 var Utils = require('./utils.js');
    11 var Utils = require('./utils.js');
    12 var _ = require('lodash');
    12 var _ = require('lodash');
    13 
    13 
    14 var defaultOptions = {		
    14 var defaultOptions = {
    15     logger: undefined,
    15     logger: undefined,
    16     intervalWidth: 10,
    16     intervalWidth: 10,
    17     intervalHeight: 5,
    17     intervalHeight: 5,
    18     maxCellHeight: 200,
    18     maxCellHeight: 200,
    19     radius: 300
    19     radius: 300
    21 
    21 
    22 
    22 
    23 function AnnotsTimeLine(options){
    23 function AnnotsTimeLine(options){
    24     var _this = this;
    24     var _this = this;
    25     var opts = _(options).defaults(defaultOptions).value();
    25     var opts = _(options).defaults(defaultOptions).value();
    26     
    26 
    27     this.container = new PIXI.DisplayObjectContainer();
    27     this.container = new PIXI.DisplayObjectContainer();
    28     this.container.x = opts.xInit;
    28     this.container.x = opts.xInit;
    29     this.container.y = opts.yInit;
    29     this.container.y = opts.yInit;
    30     this.container.width = opts.width;
    30     this.container.width = opts.width;
    31     this.container.height = opts.height;    
    31     this.container.height = opts.height;
    32     
    32 
    33     this.timeBegin = opts.timeBegin;
    33     this.timeBegin = opts.timeBegin;
    34     this.timeEnd = opts.timeEnd;
    34     this.timeEnd = opts.timeEnd;
    35     this.duration = (this.timeEnd - this.timeBegin)/1000;
    35     this.duration = (this.timeEnd - this.timeBegin)/1000;
    36     this.width = opts.width;
    36     this.width = opts.width;
    37     this.height = opts.height;
    37     this.height = opts.height;
    38     this.intervalHeight = opts.intervalHeight;
    38     this.intervalHeight = opts.intervalHeight;
    39     this.intervalWidth = opts.intervalWidth;
    39     this.intervalWidth = opts.intervalWidth;
    40     this.maxCellHeight = opts.maxCellHeight;
    40     this.maxCellHeight = opts.maxCellHeight;
    41     this.annotCategories = opts.annotCategories;
    41     this.annotCategories = opts.annotCategories;
    42     
    42 
    43     this.circleX = opts.circleX || (this.width/2);
    43     this.circleX = opts.circleX || (this.width/2);
    44     this.circleY = opts.circleY || (this.height/2);
    44     this.circleY = opts.circleY || (this.height/2);
    45     this.radius = opts.radius;
    45     this.radius = opts.radius;
    46     this.perimeter = 2*Math.PI* this.radius;
    46     this.perimeter = 2*Math.PI* this.radius;
    47     this.intervalDuration = (this.intervalWidth * this.duration / this.perimeter);
    47     this.intervalDuration = (this.intervalWidth * this.duration / this.perimeter);
    48     
    48 
    49     var currentTime = this.timeBegin;
    49     var currentTime = this.timeBegin;
    50     var totalIndex = Math.floor(this.perimeter/this.intervalWidth);
    50     var totalIndex = Math.floor(this.perimeter/this.intervalWidth);
    51     	
    51 
    52     this.cells = []
    52     this.cells = []
    53     for (var i=0; i<(this.perimeter/this.intervalWidth) ; i++){
    53     for (var i=0; i<(this.perimeter/this.intervalWidth) ; i++){
    54     	this.cells[i] = [];
    54     	this.cells[i] = [];
    55     	this.cells[i].i = i;
    55     	this.cells[i].i = i;
    56     	this.cells[i].totalAnnots = 0;
    56     	this.cells[i].totalAnnots = 0;
    57     	this.cells[i].categories = {};
    57     	this.cells[i].categories = {};
    58     	
    58 
    59     	for (var category in this.annotCategories[0].colors){
    59     	for (var category in this.annotCategories[0].colors){
    60     		this.cells[i].categories[category] = {
    60     		this.cells[i].categories[category] = {
    61 				"count": 0,
    61 				"count": 0,
    62 				"color": this.annotCategories[0].colors[category]
    62 				"color": this.annotCategories[0].colors[category]
    63     		};
    63     		};
    64     	}
    64     	}
    65     }
    65     }
    66     
    66 
    67     var ws = opts.ws;
    67     var ws = opts.ws;
    68     var stageView = opts.stageView;
    68     var stageView = opts.stageView;
    69 
    69 
    70     //draw the base - circle and line to locate the scene
    70     //draw the base - circle and line to locate the scene
    71     var graphics = new PIXI.Graphics();
    71     var graphics = new PIXI.Graphics();
    77     	.lineStyle(1, 0x646464)
    77     	.lineStyle(1, 0x646464)
    78     	.moveTo(this.circleX, this.circleY - (this.radius/3)/2)
    78     	.moveTo(this.circleX, this.circleY - (this.radius/3)/2)
    79     	.lineTo(this.circleX, this.circleY - this.radius - this.maxCellHeight - 10)
    79     	.lineTo(this.circleX, this.circleY - this.radius - this.maxCellHeight - 10)
    80     	.endFill()
    80     	.endFill()
    81     this.container.addChild(graphics);
    81     this.container.addChild(graphics);
    82     
    82 
    83     //set time text
    83     //set time text
       
    84     //TODO : move this to annotsvizview
    84     var currentTimeText = new PIXI.Text("-- : -- : --", { font: '18pt Gothic Standard', fill: '#646464' });
    85     var currentTimeText = new PIXI.Text("-- : -- : --", { font: '18pt Gothic Standard', fill: '#646464' });
    85     currentTimeText.x = this.circleX - currentTimeText.width/2;
    86     currentTimeText.x = this.circleX - currentTimeText.width/2;
    86     currentTimeText.y = this.circleY - currentTimeText.height/2;
    87     currentTimeText.y = this.circleY - currentTimeText.height/2;
    87     this.container.addChild(currentTimeText);
    88     this.container.addChild(currentTimeText);
    88     
    89 
    89     stageView.registerComponent(this);
    90     stageView.registerComponent(this);
    90 
    91 
    91     //Add Annotation to the TimeLine
    92     //Add Annotation to the TimeLine
    92     this.addAnnot = function(data){
    93     this.addAnnot = function(data){
    93     	if (typeof(this.annotCategories[0].colors[data.content.category.code]) !== 'undefined'){
    94     	if (typeof(this.annotCategories[0].colors[data.content.category.code]) !== 'undefined'){
    94     		var annotCode = data.content.category.code;
    95     		var annotCode = data.content.category.code;
    95     	} else {
    96     	} else {
    96     		var annotCode = this.annotCategories[0].order[this.annotCategories[0].order.length -1];
    97     		var annotCode = this.annotCategories[0].order[this.annotCategories[0].order.length -1];
    97     	}
    98     	}
    98     	var annotTime = Date.parse(data.ts);
    99     	var annotTime = Date.parse(data.ts);
    99     	
   100 
   100     	if (this.timeEnd > Date.parse(data.ts)){
   101     	if (this.timeEnd > Date.parse(data.ts)){
   101 	    	var i = Math.floor((Date.parse(data.ts)-this.timeBegin)/(1000*this.intervalDuration));
   102 	    	var i = Math.floor((Date.parse(data.ts)-this.timeBegin)/(1000*this.intervalDuration));
   102 	    	
   103 
   103 			this.cells[i].categories[annotCode].count += 1;
   104 			this.cells[i].categories[annotCode].count += 1;
   104 			this.cells[i].totalAnnots +=1;
   105 			this.cells[i].totalAnnots +=1;
   105 			this.redrawCell(this.cells[i], i);
   106 			this.redrawCell(this.cells[i], i);
   106     	}
   107     	}
   107     };
   108     };
   108     
   109 
   109     this.initGraphics = function(cell){
   110     this.initGraphics = function(cell){
   110     	cell.graphics = new PIXI.Graphics();
   111     	cell.graphics = new PIXI.Graphics();
   111     	cell.graphics.position.x = this.circleX + this.radius * Math.sin(cell.i*(360/totalIndex)*(Math.PI/180));
   112     	cell.graphics.position.x = this.circleX + this.radius * Math.sin(cell.i*(360/totalIndex)*(Math.PI/180));
   112     	cell.graphics.position.y = this.circleY - this.radius * Math.cos(cell.i*(360/totalIndex)*(Math.PI/180));
   113     	cell.graphics.position.y = this.circleY - this.radius * Math.cos(cell.i*(360/totalIndex)*(Math.PI/180));
   113     	cell.graphics.rotation = (cell.i)*(360/totalIndex)*(Math.PI/180) + (360/(totalIndex*2))*(Math.PI/180);
   114     	cell.graphics.rotation = (cell.i)*(360/totalIndex)*(Math.PI/180) + (360/(totalIndex*2))*(Math.PI/180);
   114     	this.container.addChild(cell.graphics);
   115     	this.container.addChild(cell.graphics);
   115     }
   116     }
   116     
   117 
   117     this.initTimeTexts = function() {
   118     this.initTimeTexts = function() {
   118 	    var tBeg = new PIXI.Text(Utils.formatTime(this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   119 	    var tBeg = new PIXI.Text(Utils.formatTime(this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   119 	    tBeg.x = this.circleX + 15;
   120 	    tBeg.x = this.circleX + 15;
   120 	    tBeg.y = this.circleY - this.radius - this.maxCellHeight - 10;
   121 	    tBeg.y = this.circleY - this.radius - this.maxCellHeight - 10;
   121 	    this.container.addChild(tBeg);
   122 	    this.container.addChild(tBeg);
   122 	    
   123 
   123 	    var tEnd = new PIXI.Text(Utils.formatTime(this.timeEnd), { font: '12pt Gothic Standard', fill: '#646464' });
   124 	    var tEnd = new PIXI.Text(Utils.formatTime(this.timeEnd), { font: '12pt Gothic Standard', fill: '#646464' });
   124 	    tEnd.x = this.circleX - 15 - tEnd.width;
   125 	    tEnd.x = this.circleX - 15 - tEnd.width;
   125 	    tEnd.y = this.circleY - this.radius - this.maxCellHeight - 10;
   126 	    tEnd.y = this.circleY - this.radius - this.maxCellHeight - 10;
   126 	    this.container.addChild(tEnd);
   127 	    this.container.addChild(tEnd);
   127 	    
   128 
   128 	    var t15 = new PIXI.Text(Utils.formatTime(((this.timeEnd - this.timeBegin)/4) + this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   129 	    var t15 = new PIXI.Text(Utils.formatTime(((this.timeEnd - this.timeBegin)/4) + this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   129 	    t15.x = this.circleX + this.radius + this.maxCellHeight + 10 ;
   130 	    t15.x = this.circleX + this.radius + this.maxCellHeight + 10 ;
   130 	    t15.y = this.circleY - t15.height;
   131 	    t15.y = this.circleY - t15.height;
   131 	    t15.rotation = Math.PI /2;
   132 	    t15.rotation = Math.PI /2;
   132 	    this.container.addChild(t15);
   133 	    this.container.addChild(t15);
   133 	    
   134 
   134 	    var t30 = new PIXI.Text(Utils.formatTime(((this.timeEnd - this.timeBegin)/2) + this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   135 	    var t30 = new PIXI.Text(Utils.formatTime(((this.timeEnd - this.timeBegin)/2) + this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   135 	    t30.x = this.circleX - t30.width/2;
   136 	    t30.x = this.circleX - t30.width/2;
   136 	    t30.y = this.circleY + this.radius + this.maxCellHeight - 2;
   137 	    t30.y = this.circleY + this.radius + this.maxCellHeight - 2;
   137 	    this.container.addChild(t30);
   138 	    this.container.addChild(t30);
   138 	    
   139 
   139 	    var t45 = new PIXI.Text(Utils.formatTime(((this.timeEnd - this.timeBegin)*3/4) + this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   140 	    var t45 = new PIXI.Text(Utils.formatTime(((this.timeEnd - this.timeBegin)*3/4) + this.timeBegin), { font: '12pt Gothic Standard', fill: '#646464' });
   140 	    t45.x = this.circleX - this.radius - this.maxCellHeight - 10 ;
   141 	    t45.x = this.circleX - this.radius - this.maxCellHeight - 10 ;
   141 	    t45.y = this.circleY + t15.height;
   142 	    t45.y = this.circleY + t15.height;
   142 	    t45.rotation = -Math.PI/2;
   143 	    t45.rotation = -Math.PI/2;
   143 	    this.container.addChild(t45);
   144 	    this.container.addChild(t45);
   144     }
   145     }
   145     
   146 
   146     //Draw the cellule
   147     //Draw the cellule
   147     this.redrawCell = function(cell){
   148     this.redrawCell = function(cell){
   148     	
   149 
   149     	if (typeof(cell.graphics) === 'undefined'){
   150     	if (typeof(cell.graphics) === 'undefined'){
   150     		this.initGraphics(cell);
   151     		this.initGraphics(cell);
   151     	} else {
   152     	} else {
   152     		cell.graphics.clear();
   153     		cell.graphics.clear();
   153     	}
   154     	}
   154     	
   155 
   155     	var y = 0;
   156     	var y = 0;
   156     	
   157 
   157     	//Check if total height is higher than Max Cell Height
   158     	//Check if total height is higher than Max Cell Height
   158     	if ((cell.totalAnnots*this.intervalHeight) > this.maxCellHeight){
   159     	if ((cell.totalAnnots*this.intervalHeight) > this.maxCellHeight){
   159     		var heightStep = this.maxCellHeight/cell.totalAnnots;
   160     		var heightStep = this.maxCellHeight/cell.totalAnnots;
   160     	} else {
   161     	} else {
   161     		var heightStep = this.intervalHeight;
   162     		var heightStep = this.intervalHeight;
   162     	}
   163     	}
   163     	
   164 
   164     	//Draw the rect depending on the height step calculated
   165     	//Draw the rect depending on the height step calculated
   165     	for (var i=0; i< this.annotCategories[0].order.length; i++){
   166     	for (var i=0; i< this.annotCategories[0].order.length; i++){
   166     		var currentCode = this.annotCategories[0].order[i];
   167     		var currentCode = this.annotCategories[0].order[i];
   167 			cell.graphics.beginFill(cell.categories[currentCode].color.replace("#", "0x"))
   168 			cell.graphics.beginFill(cell.categories[currentCode].color.replace("#", "0x"))
   168     			.drawRect(0, y, this.intervalWidth-1, -cell.categories[currentCode].count * heightStep)
   169     			.drawRect(0, y, this.intervalWidth-1, -cell.categories[currentCode].count * heightStep)
   169     			.endFill();
   170     			.endFill();
   170     		y -= cell.categories[currentCode].count*heightStep;
   171     		y -= cell.categories[currentCode].count*heightStep;
   171     	}
   172     	}
   172     }
   173     }
   173     
   174 
   174     this.init = function() {
   175     this.init = function() {
   175     	ws.message(function(data) {
   176     	ws.message(function(data) {
   176             _this.addAnnot(data);
   177             _this.addAnnot(data);
   177         });
   178         });
   178     	
   179 
   179     	this.initTimeTexts();
   180     	this.initTimeTexts();
   180     };
   181     };
   181     
   182 
   182     this.updateTime = function(){
   183     this.updateTime = function(){
   183     	currentTime += 1000;
   184     	currentTime += 1000;
   184     	
   185 
   185         var nbSec = currentTime / 1000;
   186         var nbSec = currentTime / 1000;
   186         var hours = Math.floor( nbSec / 3600 ) % 24;
   187         var hours = Math.floor( nbSec / 3600 ) % 24;
   187         var minutes = Math.floor( nbSec / 60 ) % 60;
   188         var minutes = Math.floor( nbSec / 60 ) % 60;
   188         var seconds = Math.floor(nbSec % 60);
   189         var seconds = Math.floor(nbSec % 60);
   189         var timeStr = (hours < 10 ? '0' + hours : hours) + ':' + (minutes < 10 ? '0' + minutes : minutes) + ':' + (seconds  < 10 ? '0' + seconds : seconds);
   190         var timeStr = (hours < 10 ? '0' + hours : hours) + ':' + (minutes < 10 ? '0' + minutes : minutes) + ':' + (seconds  < 10 ? '0' + seconds : seconds);
   190         
   191 
   191         currentTimeText.setText(timeStr);
   192         currentTimeText.setText(timeStr);
   192     };
   193     };
   193     
   194 
   194     var refreshTimeInterval;
   195     var refreshTimeInterval;
   195     
   196 
   196     this.start = function() {
   197     this.start = function() {
   197     	refreshTimeInterval = setInterval(function() {_this.updateTime();}, 1000);
   198     	refreshTimeInterval = setInterval(function() {_this.updateTime();}, 1000);
   198     };
   199     };
   199     
   200 
   200     this.refresh = function() {
   201     this.refresh = function() {
   201     	
   202 
   202     };
   203     };
   203     
   204 
   204     this.stop = function(){
   205     this.stop = function(){
   205     	console.log(this.cells);
   206     	console.log(this.cells);
   206     };
   207     };
   207     
   208 
   208     return this;
   209     return this;
   209 }
   210 }
   210 
   211 
   211 module.exports = {
   212 module.exports = {
   212 	AnnotsTimeLine: AnnotsTimeLine
   213 	AnnotsTimeLine: AnnotsTimeLine