ESRMeter taken from http://members.shaw.ca/swstuff/esrmeter.html (find website on internet archive). Offered here with permission.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
3.9 KiB

5 years ago
  1. function getEventX(event) {
  2. var posx = 0;
  3. if (event.pageX || event.pageY) {
  4. posx = event.pageX;
  5. }
  6. else if (event.clientX || event.clientY) {
  7. posx = event.clientX + document.body.scrollLeft
  8. + document.documentElement.scrollLeft;
  9. }
  10. return posx;
  11. }
  12. function getElementX(obj) {
  13. var x = 0;
  14. if (obj.offsetParent) {
  15. do {
  16. x += obj.offsetLeft;
  17. } while (obj = obj.offsetParent);
  18. }
  19. return x;
  20. }
  21. function zeroPad(v, len) {
  22. v = v.toString();
  23. return v.length >= len ? v : "00000000".substring(0, len - v.length) + v;
  24. }
  25. /**
  26. * Check if the difference between the max and the min non zero capture numbers
  27. * is larger than 3 orders of magnitude. If yes, we need to scale.
  28. **/
  29. function capturegraph_scale_is_required(captures) {
  30. var max = 0;
  31. var min = 1000;
  32. for (var i = 0; i < captures.length; i++) {
  33. var year = captures[i];
  34. max = Math.max(max, Math.max.apply(null, year[1]));
  35. min = Math.min(min, Math.min.apply(null,
  36. year[1].filter(Boolean)));
  37. }
  38. return (Math.log1p(max) - Math.log1p(min) > 3);
  39. }
  40. /**
  41. * Scale captugraph counts and max maxcount using log1p if necessary.
  42. */
  43. function capturegraph_scale(captures) {
  44. var maxcount = 0;
  45. for (var i = 0; i < captures.length; i++) {
  46. maxcount = Math.max(maxcount, Math.max.apply(null, captures[i][1]));
  47. }
  48. if (capturegraph_scale_is_required(captures)) {
  49. var scaled = [];
  50. for (var i = 0; i < captures.length; i++) {
  51. var year = captures[i];
  52. // XXX map may not be available on all platforms
  53. scaled.push([year[0], year[1].map(Math.log1p)]);
  54. }
  55. captures = scaled;
  56. maxcount = Math.log1p(maxcount);
  57. }
  58. return [captures, maxcount];
  59. }
  60. /**
  61. * Draw years, highlight current year, draw capture frequency per month
  62. */
  63. function sparkline(captures, width, height, canvas_id, start_year,
  64. cur_year, cur_month) {
  65. var c = document.getElementById(canvas_id);
  66. if (!c || !c.getContext) return;
  67. var ctx = c.getContext("2d");
  68. if (!ctx) return;
  69. ctx.fillStyle = "#FFF";
  70. var end_year = new Date().getUTCFullYear();
  71. var year_width = width / (end_year - start_year + 1);
  72. var scaled = capturegraph_scale(captures.years);
  73. var years = scaled[0];
  74. var maxcount = scaled[1];
  75. var yscale = height / maxcount;
  76. function year_left(year) {
  77. return Math.ceil((year - start_year) * year_width) + 0.5;
  78. }
  79. if (cur_year >= start_year) {
  80. var x = year_left(cur_year);
  81. ctx.fillStyle = "#FFFFA5";
  82. ctx.fillRect(x, 0, year_width, height);
  83. }
  84. for (var year = start_year; year <= end_year; year++) {
  85. var x = year_left(year);
  86. ctx.beginPath();
  87. ctx.moveTo(x, 0);
  88. ctx.lineTo(x, height);
  89. ctx.lineWidth = 1;
  90. ctx.strokeStyle = "#CCC";
  91. ctx.stroke();
  92. }
  93. cur_month = parseInt(cur_month) - 1;
  94. var month_width = (year_width - 1) / 12;
  95. for (var i = 0; i < years.length; i++) {
  96. var year = years[i][0];
  97. var months = years[i][1];
  98. var left = year_left(year) + 1.0;
  99. for (var month = 0; month < 12; month++) {
  100. var count = months[month];
  101. if (count > 0) {
  102. var h = Math.ceil(count * yscale);
  103. if (year == cur_year && month == cur_month) {
  104. ctx.fillStyle = "#EC008C";
  105. } else {
  106. ctx.fillStyle = "#000";
  107. }
  108. // must note that when I use width=Math.round(month_width+1),
  109. // the replay toolbar looks more accurate whereas the
  110. // bubble calendar looks somehow different.
  111. ctx.fillRect(Math.round(left), Math.ceil(height - h),
  112. Math.ceil(month_width), Math.round(h));
  113. }
  114. left += month_width;
  115. }
  116. }
  117. }
  118. function clear_canvas(canvas_id) {
  119. var c = document.getElementById(canvas_id);
  120. if (!c || !c.getContext) return;
  121. var ctx = c.getContext("2d");
  122. if (!ctx) return;
  123. ctx.clearRect(0, 0, c.width, c.height);
  124. }