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 |