timeBar.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881
  1. /* eslint-disable no-cond-assign */
  2. var bindAsEventListener = function (object, fun) {
  3. var args = Array.prototype.slice.call(arguments).slice(2);
  4. return function (event) {
  5. return fun.apply(object, [event || window.event].concat(args));
  6. };
  7. };
  8. /*
  9. Function: bind
  10. Description: 绑定对象到函数
  11. Input: object 对象, fun 函数
  12. Output: 无
  13. return: 关联后的函数
  14. *************************************************/
  15. var bind = function (object, fun) {
  16. return function () {
  17. return fun.apply(object, arguments);
  18. };
  19. };
  20. /*
  21. Function: addEventHandler
  22. Description: 添加事件
  23. Input: oTarget 目标对象, sEventType 事件, fnHandler 函数
  24. Output: 无
  25. return: 无
  26. *************************************************/
  27. var addEventHandler = function (oTarget, sEventType, fnHandler) {
  28. oTarget["on" + sEventType] = fnHandler;
  29. };
  30. var removeEventHandler = function (oTarget, sEventType) {
  31. oTarget["on" + sEventType] = null;
  32. };
  33. /*
  34. Function: getObjLeft
  35. Description: 获取对象相对网页的左上角坐标
  36. Input: obj 对象
  37. Output: 无
  38. return: 坐标
  39. *************************************************/
  40. function getObjLeft(obj) {
  41. var x = obj.offsetLeft;
  42. while (obj = obj.offsetParent) {
  43. x += obj.offsetLeft;
  44. }
  45. return x;
  46. }
  47. /*
  48. Function: getObjTop
  49. Description: 获取对象相对网页的左上角坐标
  50. Input: obj 对象
  51. Output: 无
  52. return: 坐标
  53. *************************************************/
  54. function getObjTop(obj) {
  55. var y = obj.offsetTop;
  56. while (obj = obj.offsetParent) {
  57. y += obj.offsetTop;
  58. }
  59. return y;
  60. }
  61. /*
  62. * Class ScaleInfo
  63. * @version v1.0
  64. * @function 工具类,时间刻度信息
  65. *************************************************/
  66. function ScaleInfo(x, y, iSeconds) {
  67. this.m_ix = x;
  68. this.m_iy = y;
  69. this.m_ixMin = 0;
  70. this.m_ixMax = 0;
  71. this.m_iHour = parseInt(iSeconds / 3600, 10);
  72. this.m_iMinute = parseInt(iSeconds % 3600 / 60, 10);
  73. this.m_iSecond = parseInt(iSeconds % 3600 % 60, 10);
  74. this.m_szTime = "";
  75. if (this.m_iHour < 10 && this.m_iMinute < 10) {
  76. this.m_szTime = "0" + this.m_iHour + ":0" + this.m_iMinute;
  77. } else if (this.m_iHour < 10 && this.m_iMinute >= 10) {
  78. this.m_szTime = "0" + this.m_iHour + ":" + this.m_iMinute;
  79. } else if (this.m_iHour >= 10 && this.m_iMinute >= 10) {
  80. this.m_szTime = "" + this.m_iHour + ":" + this.m_iMinute;
  81. } else {
  82. this.m_szTime = "" + this.m_iHour + ":0" + this.m_iMinute;
  83. }
  84. }
  85. /*
  86. Function: setPos
  87. Description: 设置刻度的位置
  88. Input: x 横坐标, y 纵坐标
  89. Output: 无
  90. return: 无
  91. *************************************************/
  92. ScaleInfo.prototype.setPos = function (x, y) {
  93. // this.x = x;
  94. if (x < this.m_ixMin) {
  95. x = this.m_ixMax - (this.m_ixMin - x);
  96. } else if (x > this.m_ixMax) {
  97. x = this.m_ixMin + (x - this.m_ixMax);
  98. }
  99. this.m_ix = x;
  100. this.m_iy = y;
  101. };
  102. /*
  103. Function: setPosRange
  104. Description: 设置刻度显示的范围
  105. Input: ixMin 最小横坐标, ixMax 最大横坐标
  106. Output: 无
  107. return: 无
  108. *************************************************/
  109. ScaleInfo.prototype.setPosRange = function (ixMin, ixMax) {
  110. this.m_ixMin = ixMin;
  111. this.m_ixMax = ixMax;
  112. };
  113. /*
  114. Function: isInRange
  115. Description: 是否在范围内
  116. Input: ixMin 最小横坐标, ixMax 最大横坐标
  117. Output: 无
  118. return: bool
  119. *************************************************/
  120. ScaleInfo.prototype.isInRange = function (iMin, iMax) {
  121. if (this.m_ix >= iMin && this.m_ix <= iMax) {
  122. return true;
  123. }
  124. return false;
  125. };
  126. /*
  127. Function: update
  128. Description: 更新刻度时间
  129. Input: iSeconds
  130. Output: 无
  131. return: 无
  132. *************************************************/
  133. ScaleInfo.prototype.update = function (iSeconds) {
  134. this.m_iHour = parseInt(iSeconds / 3600, 10);
  135. this.m_iMinute = parseInt(iSeconds % 3600 / 60, 10);
  136. this.m_iSecond = parseInt(iSeconds % 3600 % 60, 10);
  137. if (this.m_iHour < 10 && this.m_iMinute < 10) {
  138. this.m_szTime = "0" + this.m_iHour + ":0" + this.m_iMinute;
  139. } else if (this.m_iHour < 10 && this.m_iMinute >= 10) {
  140. this.m_szTime = "0" + this.m_iHour + ":" + this.m_iMinute;
  141. } else if (this.m_iHour >= 10 && this.m_iMinute >= 10) {
  142. this.m_szTime = "" + this.m_iHour + ":" + this.m_iMinute;
  143. } else {
  144. this.m_szTime = "" + this.m_iHour + ":0" + this.m_iMinute;
  145. }
  146. };
  147. /*
  148. * Class Time
  149. * @version v1.0
  150. * @function 工具类,时间相关信息
  151. *************************************************/
  152. function Time() {
  153. var tCurrentTime = new Date();
  154. this.m_iYear = tCurrentTime.getFullYear();
  155. this.m_iMonth = tCurrentTime.getMonth() + 1;
  156. this.m_iDay = tCurrentTime.getDate();
  157. this.m_iHour = tCurrentTime.getHours();
  158. this.m_iMinute = tCurrentTime.getMinutes();
  159. this.m_iSecond = tCurrentTime.getSeconds();
  160. this.m_iMilliseconds = tCurrentTime.getTime();//返回 1970 年 1 月 1 日至今的毫秒数
  161. }
  162. /*
  163. Function: setTimeByMis
  164. Description: 设置时间
  165. Input: iMilliseconds: 1970 年 1 月 1 日至今的毫秒数
  166. Output: 无
  167. return: 无
  168. *************************************************/
  169. Time.prototype.setTimeByMis = function (iMilliseconds) {
  170. var tSetTime = new Date(iMilliseconds);
  171. this.m_iYear = tSetTime.getFullYear();
  172. this.m_iMonth = tSetTime.getMonth() + 1;
  173. this.m_iDay = tSetTime.getDate();
  174. this.m_iHour = tSetTime.getHours();
  175. this.m_iMinute = tSetTime.getMinutes();
  176. this.m_iSecond = tSetTime.getSeconds();
  177. this.m_iMilliseconds = iMilliseconds;
  178. };
  179. /*
  180. Function: getStringTime
  181. Description: 获取时间字符串
  182. Input: 无
  183. Output: 无
  184. return: string yyyy-MM-dd HH:mm:ss
  185. *************************************************/
  186. Time.prototype.getStringTime = function () {
  187. var szYear = "" + this.m_iYear;
  188. var szMonth;
  189. if (this.m_iMonth < 10) {
  190. szMonth = "0" + this.m_iMonth;
  191. } else {
  192. szMonth = "" + this.m_iMonth;
  193. }
  194. var szDay;
  195. if (this.m_iDay < 10) {
  196. szDay = "0" + this.m_iDay;
  197. } else {
  198. szDay = "" + this.m_iDay;
  199. }
  200. var szHour;
  201. if (this.m_iHour < 10) {
  202. szHour = "0" + this.m_iHour;
  203. } else {
  204. szHour = "" + this.m_iHour;
  205. }
  206. var szMinute;
  207. if (this.m_iMinute < 10) {
  208. szMinute = "0" + this.m_iMinute;
  209. } else {
  210. szMinute = "" + this.m_iMinute;
  211. }
  212. var szSecond;
  213. if (this.m_iSecond < 10) {
  214. szSecond = "0" + this.m_iSecond;
  215. } else {
  216. szSecond = "" + this.m_iSecond;
  217. }
  218. var szCurrentTime = szYear + "-" + szMonth + "-" + szDay + " " + szHour + ":" + szMinute + ":" + szSecond;
  219. return szCurrentTime;
  220. };
  221. /*
  222. Function: parseTime
  223. Description: 通过时间字符串设置时间
  224. Input: szTime 时间 yyyy-MM-dd HH:mm:ss
  225. Output: 无
  226. return: 无
  227. *************************************************/
  228. Time.prototype.parseTime = function (szTime) {
  229. var aDate = szTime.split(' ')[0].split('-');
  230. var aTime = szTime.split(' ')[1].split(':');
  231. this.m_iYear = parseInt(aDate[0], 10);
  232. this.m_iMonth = parseInt(aDate[1], 10);
  233. this.m_iDay = parseInt(aDate[2], 10);
  234. this.m_iHour = parseInt(aTime[0], 10);
  235. this.m_iMinute = parseInt(aTime[1], 10);
  236. this.m_iSecond = parseInt(aTime[2], 10);
  237. var tTime = new Date();
  238. tTime.setFullYear(this.m_iYear);
  239. tTime.setMonth(this.m_iMonth - 1, this.m_iDay);
  240. tTime.setHours(this.m_iHour);
  241. tTime.setMinutes(this.m_iMinute);
  242. tTime.setSeconds(this.m_iSecond);
  243. this.m_iMilliseconds = tTime.getTime();
  244. };
  245. /*
  246. * Class FileInfo
  247. * @version v1.0
  248. * @function 工具类,录像文件相关信息
  249. *************************************************/
  250. function FileInfo(iX, iY, iWidth, iHeight, iType, cColor, tStartTime, tStopTime) {
  251. this.m_iX = iX;
  252. this.m_ixMin = 0;
  253. this.m_ixMax = 0;
  254. this.m_iY = iY;
  255. this.m_iWidth = iWidth;
  256. this.m_iHeight = iHeight;
  257. this.m_cColor = cColor;
  258. this.m_iType = iType;
  259. this.m_tStartTime = tStartTime;
  260. this.m_tStopTime = tStopTime;
  261. }
  262. /*
  263. Function: isInRange
  264. Description: 是否在范围之内
  265. Input: left 左起始点 right 右终点
  266. Output: 无
  267. return: 无
  268. *************************************************/
  269. FileInfo.prototype.isInRange = function (left, right) {
  270. if ((this.m_iX + this.m_iWidth) <= left || this.m_iX >= right) {
  271. return false;
  272. }
  273. return true;
  274. };
  275. /*
  276. Function: setPos
  277. Description: 设置位置内
  278. Input: iX iY左起始点坐标 iWidth 宽度 iHeight高度
  279. Output: 无
  280. return: 无
  281. *************************************************/
  282. FileInfo.prototype.setPos = function (iX, iY, iWidth, iHeight) {
  283. this.m_iX = iX;
  284. this.m_iWidth = iWidth;
  285. this.m_iY = iY;
  286. this.m_iHeight = iHeight;
  287. };
  288. /*
  289. Function: setPosRange
  290. Description: 设置范围
  291. Input: ixMin, ixMax
  292. Output: 无
  293. return: 无
  294. *************************************************/
  295. FileInfo.prototype.setPosRange = function (ixMin, ixMax) {
  296. this.m_ixMin = ixMin;
  297. this.m_ixMax = ixMax;
  298. };
  299. /*
  300. Function: draw
  301. Description: 画文件信息
  302. Input: g 设备资源
  303. Output: 无
  304. return: 无
  305. *************************************************/
  306. FileInfo.prototype.draw = function (g) {
  307. if (this.isInRange(this.m_ixMin, this.m_ixMax)) {
  308. var colorOld = g.fillStyle;
  309. g.fillStyle = this.m_cColor;
  310. if ((this.m_iX >= this.m_ixMin) && (this.m_iX + this.m_iWidth) <= this.m_ixMax) {
  311. g.fillRect(this.m_iX, this.m_iY, this.m_iWidth, this.m_iHeight);
  312. } else if ((this.m_iX < this.m_ixMax) && ((this.m_iX + this.m_iWidth) > this.m_ixMax)) {
  313. g.fillRect(this.m_iX, this.m_iY, this.m_ixMax - this.m_iX, this.m_iHeight);
  314. } else {
  315. g.fillRect(this.m_ixMin, this.m_iY, (this.m_iX + this.m_iWidth) - this.m_ixMin, this.m_iHeight);
  316. }
  317. g.fillStyle = colorOld;
  318. }
  319. };
  320. /*
  321. * Class TimeBar
  322. * @version v1.0
  323. * @function 工具类,时间条
  324. *************************************************/
  325. function TimeBar(canvas, iWidth, iHeight, options) {
  326. canvas.width = iWidth || 300;
  327. canvas.height = iHeight || 50;
  328. this.m_canvas = canvas;
  329. this.m_ctx = canvas.getContext("2d");
  330. this.m_iMinFileWidth = 1; //文件的最小宽度
  331. let backgroundColor = 'rgb(0, 0, 0)'; //时间条背景颜色
  332. let partLineColor = 'rgb(0,0,0)'; //分割线颜色
  333. let timeScaleColor = 'rgb(150, 250, 150)'; //时间条刻度颜色
  334. let middleLineColor = 'rgb(0, 250, 0)'; //中轴线颜色
  335. let middleLineTimeColor = 'rgb(0, 250, 0)'; //中轴时间颜色
  336. if (options) {
  337. if (options.backgroundColor) {
  338. backgroundColor = options.backgroundColor;
  339. }
  340. if (options.partLineColor) {
  341. partLineColor = options.partLineColor;
  342. }
  343. if (options.timeScaleColor) {
  344. timeScaleColor = options.timeScaleColor;
  345. }
  346. if (options.middleLineColor) {
  347. middleLineColor = options.middleLineColor;
  348. }
  349. if (options.middleLineTimeColor) {
  350. middleLineTimeColor = options.middleLineTimeColor;
  351. }
  352. }
  353. this.backgroundColor = backgroundColor; //时间条背景颜色
  354. this.partLineColor = partLineColor; //分割线颜色
  355. this.channelNameColor = 'rgb(150, 150, 150)'; //通道名称颜色
  356. this.timeScaleColor = timeScaleColor; //时间条刻度颜色
  357. this.middleLineColor = middleLineColor; //中轴线颜色
  358. this.middleLineTimeColor = middleLineTimeColor; //中轴时间颜色
  359. this.defaultFileColor = 'rgb(0, 255, 0)'; //默认录像类型颜色
  360. this.cmdFileColor = 'rgb(21, 184, 155)'; //命令触发录像颜色
  361. this.scheFileColor = 'rgb(33, 150, 243)'; //录像计划颜色
  362. this.alarmFileColor = 'rgb(255, 104, 66)'; //警告录像颜色
  363. this.manualFileColor = 'rgb(247, 199, 5)'; //手动录像颜色
  364. this.anrFileColor = 'rgb(138, 146, 153)'; //回传录像颜色
  365. this.m_fMidTimeFont = '14px Verdana'; //中线时间字体及大小
  366. this.m_fCurTimeFont = 'bold 12px Arial'; //鼠标当前时间字体及大小
  367. this.m_fScaleFont = 'bold 10px Arial'; //刻度字体及大小 sans-serif
  368. this.m_fChannelNameFont = '14px Verdana'; //通道名称字体
  369. canvas.style.backgroundColor = this.backgroundColor;
  370. this.m_szCurChannelName = ''; //当前通道名称
  371. this.m_fCellTime = parseFloat(2.0); //每个代表几个小时
  372. this.ScaleInfo = [];
  373. this.ScaleInfoNum = parseInt(24 / this.m_fCellTime, 10); //总的刻度数量
  374. this.ScaleInfoDisNum = 12; //显示的刻度数量
  375. //初始化刻度
  376. for (var i = 0; i < this.ScaleInfoNum; i++) {
  377. this.ScaleInfo.push(new ScaleInfo(0, 0, parseInt(i * 3600 * this.m_fCellTime, 10)));
  378. }
  379. this.m_iMaxWndNum = 16; //最大窗口数
  380. this.m_iSelWnd = 0; //选中的窗口号
  381. this.FileInfoSet = new Array(this.m_iMaxWndNum); //文件信息集合
  382. //初始化文件信息集合
  383. for (i = 0; i < this.m_iMaxWndNum; i++) {
  384. this.FileInfoSet[i] = [];
  385. }
  386. this.m_iHeight = parseInt(canvas.height, 10);
  387. this.m_iWidth = parseInt(canvas.width, 10);
  388. this.m_iFileListStartPos = 0; // 文件列表起始位置
  389. this.m_iBlankHeight = 4; // 中间及底边空白高度
  390. this.m_iTimeRectHeight = 30; //parseInt(this.m_iHeight * 4 / 7) 时间块的高度
  391. this.m_iFileRectHeight = this.m_iHeight - this.m_iTimeRectHeight - this.m_iBlankHeight; //文件块的高度
  392. this.m_iMiddleLinePos = parseInt((this.m_iFileListStartPos + this.m_iWidth) / 2, 10); //中轴线的位置
  393. this.m_iCellWidth = Math.floor((this.m_iWidth - this.m_iFileListStartPos) / this.ScaleInfoDisNum); //每个像素的秒数
  394. this.m_iCellMilliseconds = parseInt((3600 * this.m_fCellTime * 1000) / this.m_iCellWidth, 10); //每个像素的毫秒数
  395. this.m_tCurrentMidTime = new Time(); //当前中轴线的时间
  396. this.m_ctx.font = this.m_fMidTimeFont;
  397. this.m_iTextWidth = this.m_ctx.measureText(this.m_tCurrentMidTime.getStringTime()).width;
  398. this.m_tMouseCurTime = new Time(); //当前鼠标点的时间
  399. this.m_ctx.font = this.m_fCurTimeFont;
  400. this.m_iCurTextWidth = this.m_ctx.measureText(this.m_tMouseCurTime.getStringTime()).width;
  401. this.m_iCanvasLeft = getObjLeft(this.m_canvas);
  402. this.m_iCanvasTop = getObjTop(this.m_canvas);
  403. //初始化时间刻度信息
  404. for (i = 0; i < this.ScaleInfoNum; i++) {
  405. // 计算与中轴线的时间差(只计算时分秒)
  406. var seconds = (this.ScaleInfo[i].m_iHour - this.m_tCurrentMidTime.m_iHour) * 3600 + (this.ScaleInfo[i].m_iMinute - this.m_tCurrentMidTime.m_iMinute) * 60 + (this.ScaleInfo[i].m_iSecond - this.m_tCurrentMidTime.m_iSecond);
  407. var iScalePos = this.m_iMiddleLinePos + parseInt(parseFloat(seconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
  408. // 设置刻度位置范围
  409. this.ScaleInfo[i].setPosRange(this.m_iFileListStartPos, this.m_iFileListStartPos + parseInt(this.m_iCellWidth * this.ScaleInfoNum, 10));
  410. this.ScaleInfo[i].setPos(iScalePos, this.m_iTimeRectHeight);
  411. }
  412. //注册消息响应
  413. this.m_ieventX = 0;
  414. this.m_iMousePosX = 0;
  415. this.m_bMouseDown = false;
  416. this.m_bMouseOver = false;
  417. this.m_iMove = 0;
  418. this.m_iMiddleLineTime = 0;
  419. this.Start = function (oEvent) {
  420. this.m_iMove = 0;
  421. this.m_ieventX = oEvent.clientX;
  422. this.m_iMiddleLineTime = this.m_tCurrentMidTime.m_iMilliseconds;
  423. this.m_bMouseDown = true;
  424. this.mouseDownCallbackFunc();
  425. addEventHandler(document, 'mousemove', bindAsEventListener(this, this.Move));
  426. addEventHandler(document, 'mouseup', bind(this, this.Stop));
  427. addEventHandler(parent.document, 'mouseup', bind(this, this.Stop)); //解决鼠标在父页面释放时不能响应的问题
  428. //焦点丢失
  429. addEventHandler(window, "blur", bindAsEventListener(this, bindAsEventListener(this, this.Stop)));
  430. //阻止默认动作
  431. oEvent.preventDefault();
  432. removeEventHandler(canvas, 'mousemove', bindAsEventListener(this, this.onMouseMove));
  433. };
  434. this.mouseDownCallbackFunc = function () {
  435. //
  436. };
  437. this.mouseUpCallbackFunc = function () {
  438. //
  439. };
  440. this.mouseMoveCallbackFunc = function () {
  441. //
  442. };
  443. this.Stop = function () {
  444. this.m_bMouseDown = false;
  445. if (this.m_iMove === 0) {
  446. this.m_tCurrentMidTime.setTimeByMis(this.m_tMouseCurTime.m_iMilliseconds);
  447. }
  448. this.mouseUpCallbackFunc();
  449. removeEventHandler(document, 'mousemove', bindAsEventListener(this, this.Move));
  450. removeEventHandler(document, 'mouseup', bindAsEventListener(this, this.Stop));
  451. removeEventHandler(window, "blur", bindAsEventListener(this, this.Stop));
  452. addEventHandler(canvas, 'mousemove', bindAsEventListener(this, this.onMouseMove));
  453. };
  454. this.onMouseMoveIn = true;
  455. this.Move = function (oEvent) {
  456. this.m_iMove = oEvent.clientX - this.m_ieventX;
  457. if (this.m_bMouseDown) {
  458. //清除选择
  459. window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
  460. this.m_tCurrentMidTime.setTimeByMis(this.m_iMiddleLineTime - this.m_iMove * this.m_iCellMilliseconds);
  461. this.repaint();
  462. this.mouseMoveCallbackFunc();
  463. }
  464. };
  465. this.onMouseMove = function (oEvent) {
  466. this.m_iMousePosX = oEvent.clientX - this.m_iCanvasLeft;
  467. this.m_tMouseCurTime.setTimeByMis((this.m_iMousePosX - this.m_iMiddleLinePos) * this.m_iCellMilliseconds + this.m_tCurrentMidTime.m_iMilliseconds);
  468. this.repaint();
  469. var szCurMouseTime = this.m_tMouseCurTime.getStringTime();
  470. this.m_ctx.fillStyle = this.middleLineTimeColor;
  471. this.m_ctx.font = this.m_fCurTimeFont;
  472. this.m_ctx.fillText(szCurMouseTime.split(' ')[1], this.m_iMousePosX/*(this.m_iMousePosX - parseInt(this.m_iCurTextWidth / 2))*/, 20/*parseInt(this.m_iTimeRectHeight / 4)*/);
  473. };
  474. this.onMouseOut = function (/*oEvent*/) {
  475. this.repaint();
  476. };
  477. addEventHandler(canvas, 'mousedown', bindAsEventListener(this, this.Start));
  478. addEventHandler(canvas, 'mousemove', bindAsEventListener(this, this.onMouseMove));
  479. addEventHandler(canvas, 'mouseout', bindAsEventListener(this, this.onMouseOut));
  480. this.repaint();
  481. }
  482. /*
  483. Function: repaint
  484. Description: 重绘
  485. Input: 无
  486. Output: 无
  487. return: 无
  488. *************************************************/
  489. TimeBar.prototype.repaint = function () {
  490. // var szCurrentTime = this.m_tCurrentMidTime.getStringTime();
  491. this.updateScalePos();
  492. this.updateFileListPos();
  493. this.m_ctx.clearRect(0, 0, this.m_iWidth, this.m_iHeight);
  494. //画通道名称分割线
  495. this.m_ctx.strokeStyle = this.partLineColor;
  496. this.m_ctx.lineWidth = 1;
  497. this.m_ctx.beginPath();
  498. this.m_ctx.moveTo(this.m_iFileListStartPos, this.m_iTimeRectHeight);
  499. this.m_ctx.lineTo(this.m_iFileListStartPos, this.m_iHeight);
  500. this.m_ctx.stroke();
  501. //画文件两条横轴和纵轴
  502. this.m_ctx.lineWidth = this.m_iBlankHeight;
  503. this.m_ctx.beginPath();
  504. this.m_ctx.moveTo(0, this.m_iTimeRectHeight);
  505. this.m_ctx.lineTo(this.m_iWidth, this.m_iTimeRectHeight);
  506. this.m_ctx.stroke();
  507. this.m_ctx.beginPath();
  508. this.m_ctx.moveTo(0, this.m_iHeight - this.m_iBlankHeight / 2);
  509. this.m_ctx.lineTo(this.m_iWidth, this.m_iHeight - this.m_iBlankHeight / 2);
  510. this.m_ctx.stroke();
  511. //显示通道名称
  512. this.m_ctx.fillStyle = this.channelNameColor;
  513. this.m_ctx.font = this.m_fChannelNameFont;
  514. this.m_ctx.fillText(this.m_szCurChannelName, 0, this.m_iTimeRectHeight + this.m_iBlankHeight + parseInt(this.m_iFileRectHeight / 2, 10) + 5, 90);
  515. this.m_ctx.strokeStyle = this.timeScaleColor;
  516. this.m_ctx.font = this.m_fScaleFont;
  517. this.m_ctx.lineWidth = 1;
  518. //画时间刻度
  519. var i;
  520. for (i = 0; i < this.ScaleInfoNum; i++) {
  521. if (this.ScaleInfo[i].isInRange(this.m_iFileListStartPos, this.m_iWidth)) {
  522. this.m_ctx.beginPath();
  523. this.m_ctx.moveTo(this.ScaleInfo[i].m_ix, 2/*this.m_iTimeRectHeight*/);
  524. this.m_ctx.lineTo(this.ScaleInfo[i].m_ix, 10/*this.m_iHeight*/);
  525. this.m_ctx.stroke();
  526. this.m_ctx.fillText(this.ScaleInfo[i].m_szTime, this.ScaleInfo[i].m_ix + 2/*this.ScaleInfo[i].m_ix - 15*/, 12/*this.m_iTimeRectHeight - 5*/);
  527. }
  528. }
  529. //画文件信息区域
  530. for (i = 0; i < this.FileInfoSet[this.m_iSelWnd].length; i++) {
  531. this.FileInfoSet[this.m_iSelWnd][i].draw(this.m_ctx);
  532. }
  533. //画中轴线
  534. this.m_ctx.strokeStyle = this.middleLineColor;
  535. this.m_ctx.lineWidth = 2;
  536. this.m_ctx.beginPath();
  537. this.m_ctx.moveTo(this.m_iMiddleLinePos, 0);
  538. this.m_ctx.lineTo(this.m_iMiddleLinePos, this.m_iHeight);
  539. this.m_ctx.stroke();
  540. };
  541. /*
  542. Function: updateScalePos
  543. Description: 更新刻度
  544. Input: 无
  545. Output: 无
  546. return: 无
  547. *************************************************/
  548. TimeBar.prototype.updateScalePos = function () {
  549. if (this.ScaleInfo.length === 0) {
  550. return;
  551. }
  552. // 以00:00移动的距离为准
  553. var seconds = (this.ScaleInfo[0].m_iHour - this.m_tCurrentMidTime.m_iHour) * 3600 + (this.ScaleInfo[0].m_iMinute - this.m_tCurrentMidTime.m_iMinute) * 60 + (this.ScaleInfo[0].m_iSecond - this.m_tCurrentMidTime.m_iSecond);
  554. var iPos0 = this.m_iMiddleLinePos + parseInt(parseFloat(seconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
  555. if (iPos0 < this.ScaleInfo[0].m_ixMin) {
  556. iPos0 = this.ScaleInfo[0].m_ixMax - (this.ScaleInfo[0].m_ixMin - iPos0);
  557. } else if (iPos0 > this.ScaleInfo[0].m_ixMax) {
  558. iPos0 = this.ScaleInfo[0].m_ixMin + (iPos0 - this.ScaleInfo[0].m_ixMax);
  559. }
  560. var iMoved = iPos0 - this.ScaleInfo[0].m_ix;
  561. //没有移动直接返回
  562. if (iMoved === 0) {
  563. return;
  564. }
  565. // 更新所有的刻度
  566. for (var i = 0; i < this.ScaleInfoNum; i++) {
  567. var iScalePos = this.ScaleInfo[i].m_ix + iMoved;
  568. // 设置刻度位置范围
  569. this.ScaleInfo[i].setPosRange(this.m_iFileListStartPos, this.m_iFileListStartPos + parseInt(this.m_iCellWidth * this.ScaleInfoNum, 10));
  570. this.ScaleInfo[i].setPos(iScalePos, this.m_iTimeRectHeight);
  571. }
  572. };
  573. /*
  574. Function: updateFileListPos
  575. Description: 更新文件
  576. Input: 无
  577. Output: 无
  578. return: 无
  579. *************************************************/
  580. TimeBar.prototype.updateFileListPos = function () {
  581. var iFileLength = this.FileInfoSet[this.m_iSelWnd].length;
  582. if (iFileLength === 0) {
  583. return;
  584. }
  585. var tStartTime = this.FileInfoSet[this.m_iSelWnd][0].m_tStartTime;
  586. var seconds = parseInt((tStartTime.m_iMilliseconds - this.m_tCurrentMidTime.m_iMilliseconds) / 1000, 10);
  587. var iFile0Pos = this.m_iMiddleLinePos + parseInt(parseFloat(seconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
  588. var iMoved = iFile0Pos - this.FileInfoSet[this.m_iSelWnd][0].m_iX;
  589. //没有移动直接返回
  590. if (iMoved === 0) {
  591. return;
  592. }
  593. // 更新所有
  594. for (var i = 0; i < iFileLength; i++) {
  595. var iX = this.FileInfoSet[this.m_iSelWnd][i].m_iX + iMoved;
  596. var iY = this.FileInfoSet[this.m_iSelWnd][i].m_iY;
  597. var iWidth = this.FileInfoSet[this.m_iSelWnd][i].m_iWidth;
  598. var iHeight = this.FileInfoSet[this.m_iSelWnd][i].m_iHeight;
  599. this.FileInfoSet[this.m_iSelWnd][i].setPos(iX, iY, iWidth, iHeight);
  600. }
  601. };
  602. /*
  603. Function: resize
  604. Description: 重置大小
  605. Input: iWidth宽度, iHeight高度
  606. Output: 无
  607. return: 无
  608. *************************************************/
  609. TimeBar.prototype.resize = function (iWidth, iHeight) {
  610. this.m_canvas.height = iHeight;
  611. this.m_canvas.width = iWidth;
  612. this.m_iHeight = iHeight;
  613. this.m_iWidth = iWidth;
  614. this.m_iTimeRectHeight = parseInt(this.m_iHeight * 4 / 7, 10);
  615. this.m_iFileRectHeight = this.m_iHeight - this.m_iTimeRectHeight - this.m_iBlankHeight;
  616. this.m_iMiddleLinePos = parseInt((this.m_iFileListStartPos + this.m_iWidth) / 2, 10);
  617. this.m_iCellWidth = Math.floor((this.m_iWidth - this.m_iFileListStartPos) / this.ScaleInfoDisNum);
  618. this.m_iCellMilliseconds = parseInt((3600 * this.m_fCellTime * 1000) / this.m_iCellWidth, 10);
  619. //初始化时间刻度信息
  620. var i;
  621. for (i = 0; i < this.ScaleInfoNum; i++) {
  622. // 计算与中轴线的时间差(只计算时分秒)
  623. var seconds = (this.ScaleInfo[i].m_iHour - this.m_tCurrentMidTime.m_iHour) * 3600 + (this.ScaleInfo[i].m_iMinute - this.m_tCurrentMidTime.m_iMinute) * 60 + (this.ScaleInfo[i].m_iSecond - this.m_tCurrentMidTime.m_iSecond);
  624. var iScalePos = this.m_iMiddleLinePos + parseInt(parseFloat(seconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
  625. // 设置刻度位置范围
  626. this.ScaleInfo[i].setPosRange(this.m_iFileListStartPos, this.m_iFileListStartPos + parseInt(this.m_iCellWidth * this.ScaleInfoNum, 10));
  627. this.ScaleInfo[i].setPos(iScalePos, this.m_iTimeRectHeight);
  628. }
  629. //初始化文件列表信息
  630. for (i = 0; i < this.FileInfoSet[this.m_iSelWnd].length; i++) {
  631. var FileInfoSetSel = this.FileInfoSet[this.m_iSelWnd][i];
  632. var iXLeftSeconds = parseInt((FileInfoSetSel.m_tStartTime.m_iMilliseconds - this.m_tCurrentMidTime.m_iMilliseconds) / 1000, 10);
  633. var iFilePosLeft = this.m_iMiddleLinePos + parseInt(parseFloat(iXLeftSeconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
  634. var iXRightSeconds = parseInt((FileInfoSetSel.m_tStopTime.m_iMilliseconds - this.m_tCurrentMidTime.m_iMilliseconds) / 1000, 10);
  635. var iFilePosRight = this.m_iMiddleLinePos + parseInt(parseFloat(iXRightSeconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
  636. if ((iFilePosRight - iFilePosLeft) < this.m_iMinFileWidth) {
  637. iFilePosRight = iFilePosLeft + this.m_iMinFileWidth;
  638. }
  639. FileInfoSetSel.setPos(iFilePosLeft, this.m_iTimeRectHeight + parseInt(this.m_iBlankHeight / 2, 10), iFilePosRight - iFilePosLeft, this.m_iFileRectHeight + 2);
  640. }
  641. this.repaint();
  642. };
  643. /*
  644. Function: setSpanType
  645. Description: 设置时间条的显示样式
  646. Input: 无
  647. Output: 无
  648. return: 无
  649. *************************************************/
  650. TimeBar.prototype.setSpanType = function (iSpanType) {
  651. switch (iSpanType) {
  652. case 6://每2小时一格
  653. this.ScaleInfoDisNum = 12;
  654. this.m_fCellTime = parseFloat(2.0);
  655. break;
  656. case 7://每小时一格
  657. this.ScaleInfoDisNum = 12;
  658. this.m_fCellTime = parseFloat(1.0);
  659. break;
  660. case 8://每半小时一格
  661. this.ScaleInfoDisNum = 12;
  662. this.m_fCellTime = parseFloat(0.5);
  663. break;
  664. case 9://每10分钟一格
  665. this.ScaleInfoDisNum = 12;
  666. this.m_fCellTime = parseFloat(1 / 6);
  667. break;
  668. case 10://每5分钟一格
  669. this.ScaleInfoDisNum = 12;
  670. this.m_fCellTime = parseFloat(1 / 12);
  671. break;
  672. case 11://每1分钟一格
  673. this.ScaleInfoDisNum = 12;
  674. this.m_fCellTime = parseFloat(1 / 60);
  675. break;
  676. default:
  677. this.ScaleInfoDisNum = 12;
  678. this.m_fCellTime = parseFloat(2.0);
  679. return;
  680. }
  681. this.ScaleInfoNum = parseInt(24 / this.m_fCellTime, 10);
  682. this.m_iCellWidth = Math.floor((this.m_iWidth - this.m_iFileListStartPos) / this.ScaleInfoDisNum);
  683. this.m_iCellMilliseconds = parseInt((3600 * this.m_fCellTime * 1000) / this.m_iCellWidth, 10);
  684. //初始化刻度
  685. this.ScaleInfo.length = 0;
  686. for (var i = 0; i < this.ScaleInfoNum; i++) {
  687. this.ScaleInfo.push(new ScaleInfo(0, 0, parseInt(i * 3600 * this.m_fCellTime, 10)));
  688. }
  689. //初始化时间刻度信息
  690. for (i = 0; i < this.ScaleInfoNum; i++) {
  691. // 计算与中轴线的时间差(只计算时分秒)
  692. var seconds = (this.ScaleInfo[i].m_iHour - this.m_tCurrentMidTime.m_iHour) * 3600 + (this.ScaleInfo[i].m_iMinute - this.m_tCurrentMidTime.m_iMinute) * 60 + (this.ScaleInfo[i].m_iSecond - this.m_tCurrentMidTime.m_iSecond);
  693. var iScalePos = this.m_iMiddleLinePos + parseInt(parseFloat(seconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
  694. // 设置刻度位置范围
  695. this.ScaleInfo[i].setPosRange(this.m_iFileListStartPos, this.m_iFileListStartPos + parseInt(this.m_iCellWidth * this.ScaleInfoNum, 10));
  696. this.ScaleInfo[i].setPos(iScalePos, this.m_iTimeRectHeight);
  697. }
  698. //初始化文件列表信息
  699. for (i = 0; i < this.FileInfoSet[this.m_iSelWnd].length; i++) {
  700. var FileInfoSetSel = this.FileInfoSet[this.m_iSelWnd][i];
  701. var iXLeftSeconds = parseInt((FileInfoSetSel.m_tStartTime.m_iMilliseconds - this.m_tCurrentMidTime.m_iMilliseconds) / 1000, 10);
  702. var iFilePosLeft = this.m_iMiddleLinePos + parseInt(parseFloat(iXLeftSeconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
  703. var iXRightSeconds = parseInt((FileInfoSetSel.m_tStopTime.m_iMilliseconds - this.m_tCurrentMidTime.m_iMilliseconds) / 1000, 10);
  704. var iFilePosRight = this.m_iMiddleLinePos + parseInt(parseFloat(iXRightSeconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
  705. if ((iFilePosRight - iFilePosLeft) < this.m_iMinFileWidth) {
  706. iFilePosRight = iFilePosLeft + this.m_iMinFileWidth;
  707. }
  708. FileInfoSetSel.setPos(iFilePosLeft, this.m_iTimeRectHeight + parseInt(this.m_iBlankHeight / 2, 10), iFilePosRight - iFilePosLeft, this.m_iFileRectHeight + 2);
  709. }
  710. this.repaint();
  711. };
  712. /*
  713. Function: addFile
  714. Description: 添加文件
  715. Input: StartTime 开始时间, StopTime 结束时间, iType 类型, iWndNum 默认当前窗口 添加到某个窗口
  716. Output: 无
  717. return: 无
  718. *************************************************/
  719. TimeBar.prototype.addFile = function (StartTime, StopTime, iType/*, iWndNum*/) {
  720. var tStartTime = new Time();
  721. var tStopTime = new Time();
  722. tStartTime.parseTime(StartTime);
  723. tStopTime.parseTime(StopTime);
  724. var fileColor;
  725. switch (iType) {
  726. case 1:
  727. fileColor = this.scheFileColor;
  728. break;
  729. case 2:
  730. fileColor = this.alarmFileColor;
  731. break;
  732. case 3:
  733. fileColor = this.cmdFileColor;
  734. break;
  735. case 4:
  736. fileColor = this.manualFileColor;
  737. break;
  738. case 5:
  739. fileColor = this.anrFileColor;
  740. break;
  741. default:
  742. fileColor = this.defaultFileColor;
  743. break;
  744. }
  745. var iXLeftSeconds = parseInt((tStartTime.m_iMilliseconds - this.m_tCurrentMidTime.m_iMilliseconds) / 1000, 10);
  746. var iFilePosLeft = this.m_iMiddleLinePos + parseInt(parseFloat(iXLeftSeconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
  747. var iXRightSeconds = parseInt((tStopTime.m_iMilliseconds - this.m_tCurrentMidTime.m_iMilliseconds) / 1000, 10);
  748. var iFilePosRight = this.m_iMiddleLinePos + parseInt(parseFloat(iXRightSeconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
  749. var fileInfo = new FileInfo(iFilePosLeft, this.m_iTimeRectHeight + parseInt(this.m_iBlankHeight / 2, 10), iFilePosRight - iFilePosLeft, this.m_iFileRectHeight + 2, iType, fileColor, tStartTime, tStopTime);
  750. fileInfo.setPosRange(this.m_iFileListStartPos, this.m_iFileListStartPos + parseInt(this.m_iCellWidth * this.ScaleInfoNum, 10));
  751. if (arguments.length >= 4) {
  752. this.FileInfoSet[arguments[3]].push(fileInfo);
  753. } else {
  754. this.FileInfoSet[this.m_iSelWnd].push(fileInfo);
  755. }
  756. };
  757. /*
  758. Function: clearWndFileList
  759. Description: 清空某个窗口的文件信息
  760. Input: iWndNum 窗口号 0-15 默认当前选中窗口
  761. Output: 无
  762. return: 无
  763. *************************************************/
  764. TimeBar.prototype.clearWndFileList = function ()/*iWndNum*/ {
  765. var iWndParam;
  766. if (arguments.length === 0) {
  767. iWndParam = this.m_iSelWnd;
  768. } else {
  769. iWndParam = arguments[0];
  770. }
  771. if (iWndParam < 0) {
  772. iWndParam = 0;
  773. }
  774. if (iWndParam >= 16) {
  775. iWndParam = 15;
  776. }
  777. this.FileInfoSet[iWndParam].length = 0;
  778. };
  779. /*
  780. Function: setMidLineTime
  781. Description: 设置中轴线时间
  782. Input: szTime yyyy-MM-dd HH:mm:ss
  783. Output: 无
  784. return: 无
  785. *************************************************/
  786. TimeBar.prototype.setMidLineTime = function (szTime) {
  787. var tCurTime = new Time();
  788. tCurTime.parseTime(szTime);
  789. this.m_tCurrentMidTime.setTimeByMis(tCurTime.m_iMilliseconds);
  790. this.repaint();
  791. };
  792. TimeBar.prototype.setMouseDownCallback = function (callbackFunc) {
  793. this.mouseDownCallbackFunc = callbackFunc;
  794. };
  795. /*
  796. Function: setMouseUpCallback
  797. Description: 设置鼠标弹起回调函数
  798. Input: func 回调函数 function(tStartTime, tStopTime)
  799. Output: 无
  800. return: 无
  801. *************************************************/
  802. TimeBar.prototype.setMouseUpCallback = function (callbackFunc) {
  803. this.mouseUpCallbackFunc = callbackFunc;
  804. };
  805. TimeBar.prototype.setMouseMoveCallback = function (callbackFunc) {
  806. this.mouseMoveCallbackFunc = callbackFunc;
  807. };