Reputation: 1541
I have been trying different ways to achieve
linear-gradient(135deg, #FBCF33 0%, #F53939 90%);
in my bar chart. I got close to the required gradient. However, failed to achieve exactly the same as the one in CSS.
As far as I understand this is due to the angle. How to achieve the same with createLinearGradient
below is what I tried.
const angle = 136 * Math.PI / 180;
var x2 = 400 * Math.cos(angle); // angle in radians
var y2 = 400 * Math.sin(angle); // angle in radians
var g1 = ctx.createLinearGradient(0, 0, x2, y2);
g1.addColorStop(0, '#EDDE5D');
g1.addColorStop(0.5, '#F09819');
Can someone share some thoughts on this?
EDIT:
Dataset with color
const equipment = [100, 0, 20, 10, 60, 20, 0, 0, 20];
function bgColor(context, c1, c2) {
const {chart, datasetIndex, index} = context;
const ds = chart.data.datasets[datasetIndex];
const value = ds.data[index];
const y = chart.scales.y.getPixelForValue(value);
const meta = chart.getDatasetMeta(datasetIndex);
const data = meta.data[index];
const {x, width, base} = data;
if (x) {
const ctx = chart.ctx;
const gradient = ctx.createLinearGradient(x, y, x + width, base);
gradient.addColorStop(0, c1);
gradient.addColorStop(0.9, c2);
return gradient;
}
}
datasets: [
{
label: 'Equipment',
data: equipment,
backgroundColor(context) {
return bgColor(context, '#EDDE5D', '#F09819');
},
tension: 0.4,
fill: false,
borderWidth: 0,
hoverBorderColor: "#000",
hoverBackgroundColor: '#FBCF33',
hoverBorderWidth: 1,
}]
Upvotes: 1
Views: 497
Reputation: 383
You are correct in identifying the issue as the angle! Your issue here is that the way CSS linear-gradient
interprets "angle".
For CSS:
The gradient line's angle of direction. A value of 0deg is equivalent to to top; increasing values rotate clockwise from there.
Visualization of the angles:
When working with Javascript canvas, however, your origin lies with positive x to the right and positive y to the bottom, creating something that looks like this:
This is causing your gradient to actually be set up in a location off the canvas! Accounting for this, you can match the gradient by setting the same color stops as your CSS code, but adjusting the angle to be 45 degrees. Here's a working example of this:
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const angle = 45 * Math.PI / 180;
var x2 = 400 * Math.cos(angle); // angle in radians
var y2 = 400 * Math.sin(angle); // angle in radians
var g1 = ctx.createLinearGradient(0, 0, x2, y2);
g1.addColorStop(0, '#FBCF33');
g1.addColorStop(0.9, '#F53939');
ctx.fillStyle = g1;
ctx.fillRect(0, 0, 400, 400);
div{
width:400px;
height:400px;
background: linear-gradient(135deg, #FBCF33 0%, #F53939 90%);
}
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link type="text/css" rel="stylesheet" href="stylesheet.css"/>
</head>
<body>
<div></div>
<canvas id="canvas" width="400" height="400"></canvas>
<script src="index.js"></script>
</body>
</html>
Upvotes: 1