Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

give ability to have rounded just on the top corners #5

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
102 changes: 84 additions & 18 deletions Chart.roundedBarCharts.js
Original file line number Diff line number Diff line change
@@ -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() {

Expand All @@ -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
Expand All @@ -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;
Expand All @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -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){
Expand All @@ -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);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion Chart.roundedBarCharts.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
97 changes: 35 additions & 62 deletions demo/index.html
Original file line number Diff line number Diff line change
@@ -1,66 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<title>Chart.js Rounded Bar Charts Demo</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.min.js"></script>
<script src="../Chart.roundedBarCharts.js"></script>
</head>
<body onload="onLoad()">
<div class="container">
<canvas
id="bar_chart"
></canvas>
</div>
<div class="container">
<canvas
id="horizontal_bar_chart"
></canvas>
</div>
<script>
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,
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
};
<head>
<title>Chart.js Rounded Bar Charts Demo</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.js"></script>
<script src="../Chart.roundedBarCharts.js"></script>
</head>
<body onload="onLoad()">

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
});
}
</script>
</body>
</html>
<h1>Bar chart</h1>

<h2>With rounded coreners</h2>
<div class="container">
<canvas id="bar_chart"></canvas>
</div>

<h2>With all rounded corener</h2>
<div class="container">
<canvas id="bar_chart_fullCornerRadius"></canvas>
</div>


<h1>Horizontal Bar chart</h1>

<h2>With rounded corener</h2>
<div class="container">
<canvas id="horizontal_bar_chart"></canvas>
</div>


<h2>With all rounded corener</h2>
<div class="container">
<canvas id="horizontal_bar_chart_fullCornerRadius"></canvas>
</div>

<script src="script.js"></script>
</body>
</html>
Loading