JSFiddle - React, Tailwind, and code Playground
HTML
<body>
<table>
<thead><tr>
<th>Text</th><th>Ratio</th><th></th>
</tr></thead>
<tbody data-bind="foreach: points">
<tr>
<td><input data-bind="value: text" /></td>
<td><input data-bind="value: ratio" /></td>
<td><a href="#" data-bind="click: $root.removePoint">Remove</a></td>
</tr>
</tbody>
</table>
<div>
<button data-bind="click: addPoint">Add</button>
</div>
<canvas id="canvas" width="400" height="400" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
</body>
JavaScript
function Point(ratio, text){
this.ratio = ko.observable(ratio);
this.text = ko.observable(text);
this.ratio.subscribe(function(){ drawRader(); });
this.text.subscribe(function(){ drawRader(); });
}
function RaderViewModel(){
var self = this;
self.points = ko.observableArray([
new Point(0.5, 'text'),
new Point(0.75, 'text'),
new Point(0.5, 'text'),
new Point(0.75, 'text'),
new Point(0.5, 'text'),
]);
self.points.subscribe(function(){ drawRader(); });
self.addPoint = function() { self.points.push(new Point(0.5, '')); }
self.removePoint = function(point) { self.points.remove(point) }
};
var viewModel = new RaderViewModel();
ko.applyBindings(viewModel);
var canvas = document.getElementById("canvas")
, c = canvas.getContext("2d");
function drawRader(){
var points = viewModel.points()
, eachRad = (Math.PI*2) / points.length
, i
, accumRad = Math.PI/2
, radius = 150
, center = 200
, sin
, cos
, endOfAxisPt
, firstPt
, prevPt
, currentPt;
c.clearRect(0,0,400,400);
for(i = 0; i < points.length; i ++){
c.strokeStyle = "#ffa500";
c.beginPath();
sin = Math.sin(accumRad);
cos = Math.cos(accumRad);
endOfAxisPt = {
x: center + (cos * radius),
y: center - (sin * radius)
};
accumRad += eachRad;
c.moveTo(center, center);
c.lineTo(endOfAxisPt.x, endOfAxisPt.y);
c.stroke();
c.fillStyle = "#00A0E9";
c.fillText(points[i].text(),
endOfAxisPt.x - 10,
endOfAxisPt.y - (sin * 20));
c.strokeStyle = "#00A0E9";
c.beginPath();
currentPt = {
x: center + (cos * (radius * points[i].ratio())),
y: center - (sin * (radius * points[i].ratio()))
};
if(prevPt){
c.moveTo(prevPt.x, prevPt.y);
c.lineTo(currentPt.x, currentPt.y);
}
else
firstPt = currentPt;
prevPt =...