fork download
  1. <html>
  2. <!-- chart объявлен в самом низу-->
  3. <canvas onmousemove="chart.onMouseMove(event)" id="canvas"></canvas>
  4. ...
  5. ...
  6. ...
  7. </html>
  8. <script>
  9. var Chart = function(data) {
  10. this.prototype = Object.prototype;
  11. this.data = data;
  12. this.canvas = document.getElementById("canvas");
  13. if (!this.canvas.getContext) return null;
  14. //Трюк для увеличения DPI canvas'a
  15. this.scaleFactor = 8;
  16. this.canvas.width = Math.ceil(this.canvas.width * this.scaleFactor);
  17. this.canvas.height = Math.ceil(this.canvas.height * this.scaleFactor);
  18. this.g = this.canvas.getContext("2d");
  19. this.g.scale(this.scaleFactor, this.scaleFactor);
  20. //Однако теперь каждое выводимое значение надо будет масштабировать scaleFactor'ом
  21. this.g.lineCap="round"; //Круглые изгибы стыков линий
  22. this.g.textBaseline="middle";
  23. this.width = this.canvas.width; //Ширина холста
  24. this.height = this.canvas.height; //Высота холста
  25. this.padding = 100; //Отступы
  26. this.zero_x = this.padding; //Ноль графический X
  27. this.zero_y = this.height-this.padding; //Ноль графический Y
  28. this.canvas_x_min = this.padding; //Графический минимум Х
  29. this.canvas_x_max = this.padding + this.width; //Графический максимум Х
  30. this.canvas_y_min = this.height - this.padding; //Граф мин Y
  31. this.canvas_y_max = this.padding;//Граф макс Y
  32. this.k_x;//Коэфф на которые надо умножить чтобы
  33. this.k_y;//привести данные к системе координат холста
  34. this.data_x_min; //Минимальное значение данных по оси Х
  35. this.data_x_max; //Макс знач данных Х
  36. this.data_y_min; //Мин знач данных Y
  37. this.data_y_max;//Макс знач данных Y
  38. this.data_x_min = this.data[0].minX;
  39. this.data_x_max = this.data[0].maxX;
  40. this.data_y_min = this.data[0].minY;
  41. this.data_y_max = this.data[0].maxY;
  42. //Понадобится для быстрых проверок и интерактивности
  43. this.view = [];
  44. this.view.data = [];
  45. //Ищем мимакс значения среди всех данных
  46. for (var i=0;i<this.data.length;i++) {
  47. if (this.data_x_min>this.data[i].minX) this.data_x_min = this.data[i].minX;
  48. if (this.data_x_max<this.data[i].maxX) this.data_x_max = this.data[i].maxX;
  49. if (this.data_y_min>this.data[i].minY) this.data_y_min = this.data[i].minY;
  50. if (this.data_y_max<this.data[i].maxY) this.data_y_max = this.data[i].maxY;
  51. //Присваеваем случайный цвет каждой серии
  52. var color = "#"+(Math.random()*999999).toFixed(0).toString(16);
  53. console.log(color);
  54. this.data[i].color = color;
  55. //Эти свойства понадобится впоследствии для интерактивности
  56. this.view.data[i] = {};
  57. this.view.data[i].highlighted = false;
  58. this.view.data[i].points = [];
  59. for (var j=0;j<this.data[i].timestamp.length;j++) {
  60. this.view.data[i].points[j] = [];
  61. }
  62. }
  63. //Вычисляем коэффициенты для приведения к системе координат холста
  64. if (this.data_x_min!=this.data_x_max) {
  65. this.k_x = (this.canvas_x_max-this.canvas_x_min)/(this.data_x_max-this.data_x_min);
  66. } else { //Чтобы не получилось деления на ноль
  67. this.k_x = (this.canvas_x_max-this.canvas_x_min)/(this.data_x_max);
  68. }
  69. if (this.data_y_min!=this.data_y_max) {
  70. this.k_y = (this.canvas_y_min-this.canvas_y_max)/(this.data_y_max-this.data_y_min);
  71. } else { //Чтобы не получилось деления на ноль
  72. this.k_y = (this.canvas_y_min-this.canvas_y_max)/(this.data_y_max);
  73. }
  74. /**
  75. *
  76. * ЭТОТ МЕТОД НОРМАЛЬНО РИСУЕТ ГРАФИК
  77. *
  78. **/
  79. //Объявляем метод
  80. this.prototype.repaint = function(args) {
  81. //Чертим ось Y
  82. this.g.lineWidth = 2;
  83. this.g.strokeStyle="#000000";
  84. this.g.beginPath();
  85. this.g.moveTo(this.zero_x/this.scaleFactor,this.zero_y/this.scaleFactor);
  86. this.g.lineTo(this.zero_x/this.scaleFactor,this.padding/this.scaleFactor);
  87. this.g.closePath();
  88. this.g.stroke();
  89. //Чертим ось X
  90. this.g.beginPath();
  91. this.g.moveTo(this.zero_x/this.scaleFactor,this.zero_y/this.scaleFactor);
  92. this.g.lineTo((this.width-this.padding)/this.scaleFactor,this.zero_y/this.scaleFactor);
  93. this.g.closePath();
  94. this.g.stroke();
  95. this.g.lineWidth = 0.5;
  96. //Текст на оси Y
  97. var gFontArgs = this.g.font.split(" "); //"?px %fontName%"
  98. var newSize = "4px";
  99. this.g.font = newSize+" "+gFontArgs[gFontArgs.length-1];//"12px %fontName%"
  100. this.g.fillText(this.data_y_max,0,(this.zero_y - (this.data_y_max-this.data_y_min)*this.k_y)/this.scaleFactor); //MAX
  101. this.g.fillText(this.data_y_min,0,this.zero_y/this.scaleFactor); //MIN
  102. //Текст на оси Х
  103. this.g.save();
  104. this.g.translate(this.zero_x/this.scaleFactor, this.zero_y/this.scaleFactor);
  105. this.g.rotate(-Math.PI/2);
  106. var ddd = new Date(this.data_x_max);
  107. this.g.fillText(ddd.toLocaleTimeString(), 0, this.curX/this.scaleFactor);
  108. this.g.restore();
  109. //Содержимое графика
  110. for(var i=0;i<this.data.length;i++) {
  111. this.g.strokeStyle=this.data[i].color;
  112. //Выделяем серию, на которую наведена мышь
  113. if (this.view.data[i].highlighted) {
  114. this.g.lineWidth = 5;
  115. this.view.data[i].highlighted = false;
  116. } else {
  117. this.g.lineWidth = 1;
  118. }
  119. for (var j=0;j<this.data[i].timestamp.length-1;j++) {
  120. var curX = this.zero_x + (this.data[i].timestamp[j]-this.data_x_min) * this.k_x;
  121. var curY = this.zero_y - (this.data[i].values[j]-this.data_y_min) * this.k_y;
  122. var nextX = this.zero_x + (this.data[i].timestamp[j+1]-this.data_x_min) * this.k_x;
  123. var nextY = this.zero_y - (this.data[i].values[j+1]-this.data_y_min) * this.k_y;
  124. //Линии
  125. this.g.beginPath();
  126. this.g.moveTo(curX/this.scaleFactor,curY/this.scaleFactor);
  127. this.g.lineTo(nextX/this.scaleFactor,nextY/this.scaleFactor);
  128. //Сохраняем точки для последующего взаимодействия
  129. this.view.data[i].points[j] = {};
  130. this.view.data[i].points[j] = { x: curX/this.scaleFactor,
  131. y: curY/this.scaleFactor};
  132. this.g.closePath();
  133. this.g.stroke();
  134. }
  135. }
  136. }
  137. /**
  138. *
  139. * ЭТОТ МЕТОД НЕ МОЖЕТ ПОЛУЧИТЬ ДОСТУП К СВОЙСТВАМ ОБЪЕКТА
  140. *
  141. *
  142. *
  143. * **/
  144. //Объявляем метод
  145. this.prototype.onMouseMove = function(event) {
  146. var x = event.clientX*this.scalefactor/this.k_x-this.zero_x+this.data_min_x; //уже NaN
  147. var y = this.zero_y - event.clientY*this.scalefactor/this.k_y-this.data_min_y; //уже NaN
  148. for (var i=0;i<this.data.length;i++) // TYPE ERROR this.data IS UNDEFINED
  149. for (var j=0;j<this.data[i].length;j++) {
  150. if (this.view.data[i].points[j].x==x && this.view.data[i].points[j].y==y) {
  151. this.model.data[i].highlighted = true;
  152. }
  153. }
  154. }
  155. };
  156. };
  157. var req = new XMLHttpRequest();
  158. var ajaxURL = "http://localhost:8080/economiq1/ChartAJAX";
  159. var params = "date=2016-01-25";
  160. req.open("POST", ajaxURL, true);
  161. req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  162. req.setRequestHeader("Content-length", params.length);
  163. req.setRequestHeader("Connection", "close");
  164. req.send(params);
  165. req.onreadystatechange = function () {
  166. if (req.readyState == 4 & req.status == 200) {
  167. var chartData = JSON.parse(req.responseText);
  168. var chart = new Chart(chartData);
  169. chart.repaint();
  170. }
  171. }
  172.  
Runtime error #stdin #stdout #stderr 0.42s 323072KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
js: "prog.js", line 9: syntax error
js: var Chart = function(data) {
js: ...^
js: "prog.js", line 10: syntax error
js: 	this.prototype = Object.prototype;
js: ......^
js: "prog.js", line 13: invalid return
js: 	if (!this.canvas.getContext) return null;
js: ....................................^
js: "prog.js", line 155: syntax error
js: 	};
js: .^
js: "prog.js", line 156: syntax error
js: };
js: ^
js: "prog.js", line 1: Compilation produced 5 syntax errors.