You can use plotly.js traces and text to recreate the components of this chart. If you use a scatter to place down an array of markers, you can create the grey arc, then place the red arc over it. To calculate the coordinates of each these markers, you can center your axes at (0,0) then use x=r*cos(theta)
and y=r*sin(theta)
where theta is your angle in radians. You can get an array of x and y values to trace out the desired portions of the red and grey arcs.
To get the circular chart to look like yours, I set the range of the x-axes and y-axes both to [-2,2]
, made the radius of the circular arcs 0.9 with [0,0]
as the center, set the markers for these arcs to be size 10, and made the grey arc go from 210 to 85 degrees and red arc go from 90 to -200 degrees (using the function makeArr
written by mhodges in his answer here),. Then to get the green marker to display in the legend, I created a trace with a green marker but with null values so it doesn't plot anything on the chart. Text traces can be used to add text around the center of the circular arcs.
Here is an example (codepen is here):
// credit goes to mhodges: https://stackoverflow.com/a/40475362/5327068
function makeArr(startValue, stopValue, cardinality) {
var arr = [];
var step = (stopValue - startValue) / (cardinality - 1);
for (var i = 0; i < cardinality; i++) {
arr.push(startValue + (step * i));
}
return arr;
}
// The function returns two arrays of circle coordinates
// for the outer points of a circle centered at some (x,y)
// and with a radius r with an arc of theta values
function getCircleCoords(r, center, degree_values) {
var center_x=center[0]
var center_y=center[1]
var x_coords = []
var y_coords = []
for (var i = 0; i < degree_values.length; i++) {
x_coords.push(center_x + (r * Math.cos(degree_values[i]*Math.PI/180)));
y_coords.push(center_y + (r * Math.sin(degree_values[i]*Math.PI/180)));
}
return [x_coords,y_coords]
}
var trace1 = {
x: [0],
y: [0.15],
text: ['1000'],
mode: 'text',
textfont: {
family: 'arial',
size: 28,
color: 'black'
},
showlegend: false
};
var trace2 = {
x: [0],
y: [-0.15],
text: ['kW/kg'],
mode: 'text',
textfont: {
family: 'arial',
size: 22,
color: 'grey'
},
showlegend: false
};
circleCoords = getCircleCoords(r=0.9, center=[0,0], radian_values=makeArr(90,-200,1000))
backgroundCircleCoords = getCircleCoords(r=0.9, center=[0,0], radian_values=makeArr(210,85,1000))
// display a marker in the legend without plotting it
var trace3 = {
x: [null],
y: [null],
mode: 'markers',
marker: {color: 'green', size: 10},
name: 'Correcto funcionamiento'
};
// grey background circle
var trace4 = {
x: backgroundCircleCoords[0],
y: backgroundCircleCoords[1],
mode: 'markers',
marker: {color: '#eeeeee', size: 10},
name: null,
showlegend: false
};
// red foreground circle
var trace5 = {
x: circleCoords[0],
y: circleCoords[1],
mode: 'markers',
marker: {color: 'red', size: 10},
name: 'Funcionamiento erroneo'
};
var layout = {
title:'Relacíon potencia peso',
xaxis: {
range: [-2, 2],
zeroline: false,
showgrid: false,
zeroline: false,
showline: false,
showticklabels: false
},
yaxis: {
range: [-2, 2],
showgrid: false,
zeroline: false,
showline: false,
showticklabels: false
},
width: 600,
height: 600,
legend: {
x: 0,
y: 0,
"orientation": "h"
}
};
var data = [trace1, trace2, trace3, trace4, trace5];
Plotly.newPlot('myDiv', data, layout);

EDIT: for a smoother circle, you can increase the number of markers used to draw the circle.
circleCoords = getCircleCoords(r=0.9, center=[0,0], radian_values=makeArr(90,-200,5000))
backgroundCircleCoords = getCircleCoords(r=0.9, center=[0,0], radian_values=makeArr(210,85,5000))