diff --git a/Chart.roundedBarCharts.js b/Chart.roundedBarCharts.js index efbbeca..59e66de 100644 --- a/Chart.roundedBarCharts.js +++ b/Chart.roundedBarCharts.js @@ -1,6 +1,7 @@ /* * Rounded Rectangle Extension for Bar Charts and Horizontal Bar Charts * Tested with Charts.js 2.7.0 +* Modified by anthony0030 */ Chart.elements.Rectangle.prototype.draw = function() { @@ -12,8 +13,12 @@ Chart.elements.Rectangle.prototype.draw = function() { // If radius is less than 0 or is large enough to cause drawing errors a max // radius is imposed. If cornerRadius is not defined set it to 0. var cornerRadius = this._chart.config.options.cornerRadius; + var fullCornerRadius = this._chart.config.options.fullCornerRadius; + var typeOfChart = this._chart.config.type; + if(cornerRadius < 0){ cornerRadius = 0; } - if(typeof cornerRadius == 'undefined'){ cornerRadius = 0; } + if(typeof cornerRadius === "undefined"){ cornerRadius = 0; } + if(typeof fullCornerRadius === "undefined"){ fullCornerRadius = true; } if (!vm.horizontal) { // bar @@ -23,7 +28,7 @@ Chart.elements.Rectangle.prototype.draw = function() { bottom = vm.base; signX = 1; signY = bottom > top? 1: -1; - borderSkipped = vm.borderSkipped || 'bottom'; + borderSkipped = vm.borderSkipped || "bottom"; } else { // horizontal bar left = vm.base; @@ -32,7 +37,7 @@ Chart.elements.Rectangle.prototype.draw = function() { bottom = vm.y + vm.height / 2; signX = right > left? 1: -1; signY = 1; - borderSkipped = vm.borderSkipped || 'left'; + borderSkipped = vm.borderSkipped || "left"; } // Canvas doesn't allow us to stroke inside the width so we can @@ -43,10 +48,10 @@ Chart.elements.Rectangle.prototype.draw = function() { borderWidth = borderWidth > barSize? barSize: borderWidth; var halfStroke = borderWidth / 2; // Adjust borderWidth when bar top position is near vm.base(zero). - var borderLeft = left + (borderSkipped !== 'left'? halfStroke * signX: 0); - var borderRight = right + (borderSkipped !== 'right'? -halfStroke * signX: 0); - var borderTop = top + (borderSkipped !== 'top'? halfStroke * signY: 0); - var borderBottom = bottom + (borderSkipped !== 'bottom'? -halfStroke * signY: 0); + var borderLeft = left + (borderSkipped !== "left"? halfStroke * signX: 0); + var borderRight = right + (borderSkipped !== "right"? -halfStroke * signX: 0); + var borderTop = top + (borderSkipped !== "top"? halfStroke * signY: 0); + var borderBottom = bottom + (borderSkipped !== "bottom"? -halfStroke * signY: 0); // not become a vertical line? if (borderLeft !== borderRight) { top = borderTop; @@ -75,7 +80,7 @@ Chart.elements.Rectangle.prototype.draw = function() { ]; // Find first (starting) corner with fallback to 'bottom' - var borders = ['bottom', 'left', 'top', 'right']; + var borders = ["bottom", "left", "top", "right"]; var startCorner = borders.indexOf(borderSkipped, 0); if (startCorner === -1) { startCorner = 0; @@ -89,11 +94,12 @@ Chart.elements.Rectangle.prototype.draw = function() { var corner = cornerAt(0); ctx.moveTo(corner[0], corner[1]); + var nextCornerId, nextCorner, width, height, x, y; for (var i = 1; i < 4; i++) { corner = cornerAt(i); nextCornerId = i+1; - if(nextCornerId == 4){ - nextCornerId = 0 + if(nextCornerId === 4){ + nextCornerId = 0; } nextCorner = cornerAt(nextCornerId); @@ -103,7 +109,7 @@ Chart.elements.Rectangle.prototype.draw = function() { x = corners[1][0]; y = corners[1][1]; - var radius = cornerRadius; + radius = cornerRadius; // Fix radius being too large if(radius > Math.abs(height)/2){ radius = Math.floor(Math.abs(height)/2); @@ -112,6 +118,7 @@ Chart.elements.Rectangle.prototype.draw = function() { radius = Math.floor(Math.abs(width)/2); } + var x_tl, x_tr, y_tl, y_tr, x_bl, x_br, y_bl, y_br; if(height < 0){ // Negative values in a standard bar chart x_tl = x; x_tr = x+width; @@ -122,13 +129,28 @@ Chart.elements.Rectangle.prototype.draw = function() { // Draw ctx.moveTo(x_bl+radius, y_bl); + ctx.lineTo(x_br-radius, y_br); + + // bottom right ctx.quadraticCurveTo(x_br, y_br, x_br, y_br-radius); + + ctx.lineTo(x_tr, y_tr+radius); - ctx.quadraticCurveTo(x_tr, y_tr, x_tr-radius, y_tr); + + // top right + fullCornerRadius ? ctx.quadraticCurveTo(x_tr, y_tr, x_tr-radius, y_tr) : ctx.lineTo(x_tr, y_tr, x_tr-radius, y_tr); + + ctx.lineTo(x_tl+radius, y_tl); - ctx.quadraticCurveTo(x_tl, y_tl, x_tl, y_tl+radius); + + // top left + fullCornerRadius ? ctx.quadraticCurveTo(x_tl, y_tl, x_tl, y_tl+radius) : ctx.lineTo(x_tl, y_tl, x_tl, y_tl+radius); + + ctx.lineTo(x_bl, y_bl-radius); + + // bottom left ctx.quadraticCurveTo(x_bl, y_bl, x_bl+radius, y_bl); }else if(width < 0){ @@ -141,26 +163,70 @@ Chart.elements.Rectangle.prototype.draw = function() { // Draw ctx.moveTo(x_bl+radius, y_bl); + ctx.lineTo(x_br-radius, y_br); - ctx.quadraticCurveTo(x_br, y_br, x_br, y_br-radius); + + // Bottom right corner + fullCornerRadius ? ctx.quadraticCurveTo(x_br, y_br, x_br, y_br-radius) : ctx.lineTo(x_br, y_br, x_br, y_br-radius); + ctx.lineTo(x_tr, y_tr+radius); - ctx.quadraticCurveTo(x_tr, y_tr, x_tr-radius, y_tr); + + // top right Corner + fullCornerRadius ? ctx.quadraticCurveTo(x_tr, y_tr, x_tr-radius, y_tr) : ctx.lineTo(x_tr, y_tr, x_tr-radius, y_tr); + ctx.lineTo(x_tl+radius, y_tl); + + // top left corner ctx.quadraticCurveTo(x_tl, y_tl, x_tl, y_tl+radius); + ctx.lineTo(x_bl, y_bl-radius); + + // bttom left corner ctx.quadraticCurveTo(x_bl, y_bl, x_bl+radius, y_bl); }else{ //Positive Value ctx.moveTo(x + radius, y); + + + ctx.lineTo(x + width - radius, y); + + // top right ctx.quadraticCurveTo(x + width, y, x + width, y + radius); + + ctx.lineTo(x + width, y + height - radius); - ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); + + // bottom right + if(fullCornerRadius || typeOfChart === "horizontalBar"){ + ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); + } + else{ + ctx.lineTo(x + width, y + height, x + width - radius, y + height); + } + + ctx.lineTo(x + radius, y + height); - ctx.quadraticCurveTo(x, y + height, x, y + height - radius); + + // bottom left + if(fullCornerRadius){ + ctx.quadraticCurveTo(x, y + height, x, y + height - radius); + } + else{ + ctx.lineTo(x, y + height, x, y + height - radius); + } + + ctx.lineTo(x, y + radius); - ctx.quadraticCurveTo(x, y, x + radius, y); + + // top left + if(fullCornerRadius || typeOfChart === "bar"){ + ctx.quadraticCurveTo(x, y, x + radius, y); + } + else{ + ctx.lineTo(x, y, x + radius, y); + } } } diff --git a/Chart.roundedBarCharts.min.js b/Chart.roundedBarCharts.min.js index 7d5f62c..abedbb4 100644 --- a/Chart.roundedBarCharts.min.js +++ b/Chart.roundedBarCharts.min.js @@ -1 +1 @@ -Chart.elements.Rectangle.prototype.draw=function(){function t(t){return s[(f+t)%4]}var r,e,i,o,_,h,l,a,b=this._chart.ctx,d=this._view,n=d.borderWidth,u=this._chart.config.options.cornerRadius;if(u<0&&(u=0),void 0===u&&(u=0),d.horizontal?(r=d.base,e=d.x,i=d.y-d.height/2,o=d.y+d.height/2,_=e>r?1:-1,h=1,l=d.borderSkipped||"left"):(r=d.x-d.width/2,e=d.x+d.width/2,i=d.y,_=1,h=(o=d.base)>i?1:-1,l=d.borderSkipped||"bottom"),n){var T=Math.min(Math.abs(r-e),Math.abs(i-o)),v=(n=n>T?T:n)/2,g=r+("left"!==l?v*_:0),c=e+("right"!==l?-v*_:0),C=i+("top"!==l?v*h:0),w=o+("bottom"!==l?-v*h:0);g!==c&&(i=C,o=w),C!==w&&(r=g,e=c)}b.beginPath(),b.fillStyle=d.backgroundColor,b.strokeStyle=d.borderColor,b.lineWidth=n;var s=[[r,o],[r,i],[e,i],[e,o]],f=["bottom","left","top","right"].indexOf(l,0);-1===f&&(f=0);var q=t(0);b.moveTo(q[0],q[1]);for(var m=1;m<4;m++)q=t(m),nextCornerId=m+1,4==nextCornerId&&(nextCornerId=0),nextCorner=t(nextCornerId),width=s[2][0]-s[1][0],height=s[0][1]-s[1][1],x=s[1][0],y=s[1][1],(a=u)>Math.abs(height)/2&&(a=Math.floor(Math.abs(height)/2)),a>Math.abs(width)/2&&(a=Math.floor(Math.abs(width)/2)),height<0?(x_tl=x,x_tr=x+width,y_tl=y+height,y_tr=y+height,x_bl=x,x_br=x+width,y_bl=y,y_br=y,b.moveTo(x_bl+a,y_bl),b.lineTo(x_br-a,y_br),b.quadraticCurveTo(x_br,y_br,x_br,y_br-a),b.lineTo(x_tr,y_tr+a),b.quadraticCurveTo(x_tr,y_tr,x_tr-a,y_tr),b.lineTo(x_tl+a,y_tl),b.quadraticCurveTo(x_tl,y_tl,x_tl,y_tl+a),b.lineTo(x_bl,y_bl-a),b.quadraticCurveTo(x_bl,y_bl,x_bl+a,y_bl)):width<0?(x_tl=x+width,x_tr=x,y_tl=y,y_tr=y,x_bl=x+width,x_br=x,y_bl=y+height,y_br=y+height,b.moveTo(x_bl+a,y_bl),b.lineTo(x_br-a,y_br),b.quadraticCurveTo(x_br,y_br,x_br,y_br-a),b.lineTo(x_tr,y_tr+a),b.quadraticCurveTo(x_tr,y_tr,x_tr-a,y_tr),b.lineTo(x_tl+a,y_tl),b.quadraticCurveTo(x_tl,y_tl,x_tl,y_tl+a),b.lineTo(x_bl,y_bl-a),b.quadraticCurveTo(x_bl,y_bl,x_bl+a,y_bl)):(b.moveTo(x+a,y),b.lineTo(x+width-a,y),b.quadraticCurveTo(x+width,y,x+width,y+a),b.lineTo(x+width,y+height-a),b.quadraticCurveTo(x+width,y+height,x+width-a,y+height),b.lineTo(x+a,y+height),b.quadraticCurveTo(x,y+height,x,y+height-a),b.lineTo(x,y+a),b.quadraticCurveTo(x,y,x+a,y));b.fill(),n&&b.stroke()}; +Chart.elements.Rectangle.prototype.draw=function(){var o,t,i,e,r,a,n,l,T=this._chart.ctx,h=this._view,u=h.borderWidth,d=this._chart.config.options.cornerRadius,c=this._chart.config.options.fullCornerRadius,v=this._chart.config.type;if(d<0&&(d=0),void 0===d&&(d=0),void 0===c&&(c=!0),h.horizontal?(o=h.base,t=h.x,i=h.y-h.height/2,e=h.y+h.height/2,r=t>o?1:-1,a=1,n=h.borderSkipped||"left"):(o=h.x-h.width/2,t=h.x+h.width/2,i=h.y,r=1,a=(e=h.base)>i?1:-1,n=h.borderSkipped||"bottom"),u){var s=Math.min(Math.abs(o-t),Math.abs(i-e)),b=(u=u>s?s:u)/2,f=o+("left"!==n?b*r:0),C=t+("right"!==n?-b*r:0),q=i+("top"!==n?b*a:0),p=e+("bottom"!==n?-b*a:0);f!==C&&(i=q,e=p),q!==p&&(o=f,t=C)}T.beginPath(),T.fillStyle=h.backgroundColor,T.strokeStyle=h.borderColor,T.lineWidth=u;var g=[[o,e],[o,i],[t,i],[t,e]],m=["bottom","left","top","right"].indexOf(n,0);function M(o){return g[(m+o)%4]}-1===m&&(m=0);var y,k,x,_,w,S=M(0);T.moveTo(S[0],S[1]);for(var R=1;R<4;R++){var z,W,B,O,P,j,A,D;S=M(R),4===(y=R+1)&&(y=0),M(y),k=g[2][0]-g[1][0],x=g[0][1]-g[1][1],_=g[1][0],w=g[1][1],(l=d)>Math.abs(x)/2&&(l=Math.floor(Math.abs(x)/2)),l>Math.abs(k)/2&&(l=Math.floor(Math.abs(k)/2)),x<0?(z=_,W=_+k,B=w+x,O=w+x,P=_,j=_+k,A=w,D=w,T.moveTo(P+l,A),T.lineTo(j-l,D),T.quadraticCurveTo(j,D,j,D-l),T.lineTo(W,O+l),c?T.quadraticCurveTo(W,O,W-l,O):T.lineTo(W,O,W-l,O),T.lineTo(z+l,B),c?T.quadraticCurveTo(z,B,z,B+l):T.lineTo(z,B,z,B+l),T.lineTo(P,A-l),T.quadraticCurveTo(P,A,P+l,A)):k<0?(z=_+k,W=_,B=w,O=w,P=_+k,j=_,A=w+x,D=w+x,T.moveTo(P+l,A),T.lineTo(j-l,D),c?T.quadraticCurveTo(j,D,j,D-l):T.lineTo(j,D,j,D-l),T.lineTo(W,O+l),c?T.quadraticCurveTo(W,O,W-l,O):T.lineTo(W,O,W-l,O),T.lineTo(z+l,B),T.quadraticCurveTo(z,B,z,B+l),T.lineTo(P,A-l),T.quadraticCurveTo(P,A,P+l,A)):(T.moveTo(_+l,w),T.lineTo(_+k-l,w),T.quadraticCurveTo(_+k,w,_+k,w+l),T.lineTo(_+k,w+x-l),c||"horizontalBar"===v?T.quadraticCurveTo(_+k,w+x,_+k-l,w+x):T.lineTo(_+k,w+x,_+k-l,w+x),T.lineTo(_+l,w+x),c?T.quadraticCurveTo(_,w+x,_,w+x-l):T.lineTo(_,w+x,_,w+x-l),T.lineTo(_,w+l),c||"bar"===v?T.quadraticCurveTo(_,w,_+l,w):T.lineTo(_,w,_+l,w))}T.fill(),u&&T.stroke()}; \ No newline at end of file diff --git a/README.md b/README.md index cd616a3..95823c5 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ To use include the following: Then set the radius in the options e.g. ```javascript var options = { - cornerRadius: 20, + cornerRadius: number, + fullCornerRadius: boolean, (default is true) }; ``` + +"cornerRadius" option will define how much of a curve you whant your bars to have. +"fullCornerRadius" option will make all the corners in the chart round and is a boolean; true or false. \ No newline at end of file diff --git a/demo/index.html b/demo/index.html index adc0d1c..f3c9cf6 100644 --- a/demo/index.html +++ b/demo/index.html @@ -1,66 +1,39 @@ - - Chart.js Rounded Bar Charts Demo - - - - -
- -
-
- -
- + + + - function onLoad(){ - // Standard Bar Chart - var ctxBar = document.getElementById("bar_chart"); - var myBarChart = new Chart(ctxBar, { - type: 'bar', - data: data, - options: options - }); - // Horizontal Bar Chart - var ctxHBar = document.getElementById("horizontal_bar_chart"); - var myHorizBarChart = new Chart(ctxHBar, { - type: 'horizontalBar', - data: data, - options: options - }); - } - - - +

Bar chart

+ +

With rounded coreners

+
+ +
+ +

With all rounded corener

+
+ +
+ + +

Horizontal Bar chart

+ +

With rounded corener

+
+ +
+ + +

With all rounded corener

+
+ +
+ + + + \ No newline at end of file diff --git a/demo/script.js b/demo/script.js new file mode 100644 index 0000000..93beab0 --- /dev/null +++ b/demo/script.js @@ -0,0 +1,76 @@ +var data = { + labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], + datasets: [{ + label: '% change in support', + data: [12, -19, -3, 5, 2, 3], + backgroundColor: [ + 'rgba(255, 99, 132, 1)', + 'rgba(54, 162, 235, 1)', + 'rgba(255, 206, 86, 1)', + 'rgba(75, 192, 192, 1)', + 'rgba(153, 102, 255, 1)', + 'rgba(255, 159, 64, 1)' + ], + borderWidth: 0 + }] +}; + +var options = { + cornerRadius: 20, + fullCornerRadius: false, + scales: { + yAxes: [{ + ticks: { + beginAtZero: true, + } + }] + } +}; + +var fullCornerRadiusOptions = { + cornerRadius: 20, + scales: { + yAxes: [{ + ticks: { + beginAtZero: true, + } + }] + } +}; + +function onLoad() { + + // Standard Bar Chart + var ctxBar = document.getElementById("bar_chart"); + var myBarChart = new Chart(ctxBar, { + type: 'bar', + data: data, + options: options + }); + + // Horizontal Bar Chart + var ctxHBar = document.getElementById("horizontal_bar_chart"); + var myHorizBarChart = new Chart(ctxHBar, { + type: 'horizontalBar', + data: data, + options: options + }); + + + // Standard Bar Chart with all corners round + var ctxBarF = document.getElementById("bar_chart_fullCornerRadius"); + var myBarChartF = new Chart(ctxBarF, { + type: 'bar', + data: data, + options: fullCornerRadiusOptions + }); + + // Horizontal Bar Chart with all corners round + var ctxHBarF = document.getElementById("horizontal_bar_chart_fullCornerRadius"); + var myHorizBarChartF = new Chart(ctxHBarF, { + type: 'horizontalBar', + data: data, + options: fullCornerRadiusOptions + }); + +} \ No newline at end of file