I am trying to achieve the following svg gradient
The closest I can achieve is
I'd be very grateful if someone could help out
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.4/d3.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Speed Arc</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
html,
body {
height: 100%;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
}
#speed-arc {
display: flex;
justify-content: center;
align-items: center;
}
.background {
fill: lightgray;
}
.path {
fill: url(#arcBackground);
}
</style>
</head>
<body>
<div id="speed-arc"></div>
<script>
// Set the dimensions and margins of the graph
var width = 500,
height = 500,
margin = 0;
// The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin.
var radius = Math.min(width, height) / 2 - margin;
// Append the svg object to the div called 'speed-arc'
var svg = d3.select("#speed-arc")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
// Create background arc
var backgroundArc = d3.arc()
.innerRadius(160)
.outerRadius(170)
.startAngle(-0.75 * Math.PI)
.endAngle(0.75 * Math.PI);
// Create foreground arc
var arc = d3.arc()
.innerRadius(160)
.outerRadius(170)
.cornerRadius(5)
.startAngle(-0.75 * Math.PI);
// Append background arc
svg.append("path")
.attr("class", "background")
.attr("d", backgroundArc);
// Append foreground arc
var path = svg.append("path")
.datum({
endAngle: -0.75 * Math.PI
})
.attr("class", "path")
.attr("d", arc)
.attr("fill", "url(#arcBackground)");
// Create the gradient for the arc
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "arcBackground")
.attr("x1", "0%")
.attr("x2", "100%")
.attr("y1", "0%")
.attr("y2", "0%");
gradient.append("stop")
.attr("offset", "0%")
.attr("stop-color", "#F95247"); // Red
gradient.append("stop")
.attr("offset", "20%")
.attr("stop-color", "#FD7A4F"); // Orange-red
gradient.append("stop")
.attr("offset", "50%")
.attr("stop-color", "#F8E23D"); // Yellow
gradient.append("stop")
.attr("offset", "75%")
.attr("stop-color", "#B6E359"); // Light green
gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "#15DA88"); // Green
// Create the arc scale
var arcScale = d3.scalePow()
.exponent(0.3)
.domain([0, 15])
.range([-0.75 * Math.PI, 0.75 * Math.PI])
.clamp(true);
// Function to update the arc
function updateArc(speed) {
var arcTween = function(transition, speed) {
transition.attrTween("d", function(d) {
var interpolate = d3.interpolate(d.endAngle, arcScale(speed));
return function(t) {
d.endAngle = interpolate(t);
return arc(d);
};
});
};
path.transition()
.duration(750)
.call(arcTween, speed);
}
// Example usage: update the arc with a speed value
updateArc(15);
// You can call updateArc function with different values to animate the arc
</script>
</body>
</html>