rounded-barchart.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. Chart.elements.Rectangle.prototype.draw = function() {
  2. var ctx = this._chart.ctx;
  3. var vm = this._view;
  4. var left, right, top, bottom, signX, signY, borderSkipped, radius;
  5. var borderWidth = vm.borderWidth;
  6. var cornerRadius = 20;
  7. if (!vm.horizontal) {
  8. // bar
  9. left = vm.x - vm.width / 2;
  10. right = vm.x + vm.width / 2;
  11. top = vm.y;
  12. bottom = vm.base;
  13. signX = 1;
  14. signY = bottom > top? 1: -1;
  15. borderSkipped = vm.borderSkipped || 'bottom';
  16. } else {
  17. // horizontal bar
  18. left = vm.base;
  19. right = vm.x;
  20. top = vm.y - vm.height / 2;
  21. bottom = vm.y + vm.height / 2;
  22. signX = right > left? 1: -1;
  23. signY = 1;
  24. borderSkipped = vm.borderSkipped || 'left';
  25. }
  26. // Canvas doesn't allow us to stroke inside the width so we can
  27. // adjust the sizes to fit if we're setting a stroke on the line
  28. if (borderWidth) {
  29. // borderWidth shold be less than bar width and bar height.
  30. var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));
  31. borderWidth = borderWidth > barSize? barSize: borderWidth;
  32. var halfStroke = borderWidth / 2;
  33. // Adjust borderWidth when bar top position is near vm.base(zero).
  34. var borderLeft = left + (borderSkipped !== 'left'? halfStroke * signX: 0);
  35. var borderRight = right + (borderSkipped !== 'right'? -halfStroke * signX: 0);
  36. var borderTop = top + (borderSkipped !== 'top'? halfStroke * signY: 0);
  37. var borderBottom = bottom + (borderSkipped !== 'bottom'? -halfStroke * signY: 0);
  38. // not become a vertical line?
  39. if (borderLeft !== borderRight) {
  40. top = borderTop;
  41. bottom = borderBottom;
  42. }
  43. // not become a horizontal line?
  44. if (borderTop !== borderBottom) {
  45. left = borderLeft;
  46. right = borderRight;
  47. }
  48. }
  49. ctx.beginPath();
  50. ctx.fillStyle = vm.backgroundColor;
  51. ctx.strokeStyle = vm.borderColor;
  52. ctx.lineWidth = borderWidth;
  53. // Corner points, from bottom-left to bottom-right clockwise
  54. // | 1 2 |
  55. // | 0 3 |
  56. var corners = [
  57. [left, bottom],
  58. [left, top],
  59. [right, top],
  60. [right, bottom]
  61. ];
  62. // Find first (starting) corner with fallback to 'bottom'
  63. var borders = ['bottom', 'left', 'top', 'right'];
  64. var startCorner = borders.indexOf(borderSkipped, 0);
  65. if (startCorner === -1) {
  66. startCorner = 0;
  67. }
  68. function cornerAt(index) {
  69. return corners[(startCorner + index) % 4];
  70. }
  71. // Draw rectangle from 'startCorner'
  72. var corner = cornerAt(0);
  73. ctx.moveTo(corner[0], corner[1]);
  74. for (var i = 1; i < 4; i++) {
  75. corner = cornerAt(i);
  76. nextCornerId = i+1;
  77. if(nextCornerId == 4){
  78. nextCornerId = 0
  79. }
  80. nextCorner = cornerAt(nextCornerId);
  81. width = corners[2][0] - corners[1][0];
  82. height = corners[0][1] - corners[1][1];
  83. x = corners[1][0];
  84. y = corners[1][1];
  85. var radius = cornerRadius;
  86. // Fix radius being too large
  87. if(radius > height/2){
  88. radius = height/2;
  89. }if(radius > width/2){
  90. radius = width/2;
  91. }
  92. ctx.moveTo(x + radius, y);
  93. ctx.lineTo(x + width - radius, y);
  94. ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
  95. ctx.lineTo(x + width, y + height - radius);
  96. ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
  97. ctx.lineTo(x + radius, y + height);
  98. ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
  99. ctx.lineTo(x, y + radius);
  100. ctx.quadraticCurveTo(x, y, x + radius, y);
  101. }
  102. ctx.fill();
  103. if (borderWidth) {
  104. ctx.stroke();
  105. }
  106. };