JSFiddle - React, Tailwind, and code Playground
by sukobuto
HTML
<script src="http://sukobuto.com/cdn/knockout-es5.min.js"></script>
<h1>SVG with Knockout-ES5</h1>
<a href="http://vuejs.org/examples/svg.html">Vue.js SVG Example</a> を Knockout-ES5 に移植しました。
<div id="demo">
<svg width="200" height="200">
<polygon data-bind="attr: { points: points }"></polygon>
<circle cx="100" cy="100" r="80"></circle>
<!--ko foreach: stats-->
<text data-bind="attr: { x: labelPoint.x, y: labelPoint.y }, text: label"></text>
<!--/ko-->
</svg>
<div data-bind="foreach: stats">
<div>
<label data-bind="text: label"></label>
<input type="range" data-bind="value: value" min="0" max="100" />
<span data-bind="text: value"></span>
<button data-bind="click: $parent.remove">X</button>
</div>
</div>
<button data-bind="click: reverse">REVERSE</button><br/>
<input type="text" data-bind="value: statInput"/>
<button data-bind="click: createStat">Create a Stat</button>
</div>
CSS
body {
font-family: Helvetica Neue, Arial, sans-serif;
}
polygon {
fill: #42b983;
opacity: .75;
}
circle {
fill: transparent;
stroke: #999;
}
text {
font-family: Helvetica Neue, Arial, sans-serif;
font-size: 10px;
fill: #666;
}
label {
display: inline-block;
margin-left: 10px;
width: 20px;
}
JavaScript
function AppViewModel() {
var self = this
, statsObs
;
self.stats = [];
self.statInput = "";
ko.track(self);
statsObs = ko.getObservable(self, 'stats');
ko.defineProperty(self, 'points', function() {
return self.stats.map(function (stat) {
var point = stat.point;
return point.x + ',' + point.y;
}).join(' ');
});
self.addStat = function(data) {
self.stats.push(new StatViewModel(data.label, data.value, statsObs));
}
self.createStat = function() {
self.stats.push(new StatViewModel(self.statInput, 100, statsObs));
}
self.reverse = function() {
self.stats.reverse();
}
self.remove = function(stat) {
self.stats.remove(stat);
}
}
function StatViewModel(label, value, list) {
var self = this;
self.label = label;
self.value = value;
ko.track(self);
function valueToPoint (value, index, total) {
var x = 0,
y = -value * 0.8,
angle = Math.PI * 2 / total * index,
cos = Math.cos(angle),
sin = Math.sin(angle),
tx = x * cos - y * sin + 100,
ty = x * sin + y * cos + 100
return {
x: tx,
y: ty
}
}
ko.defineProperty(self, 'point', function() {
return valueToPoint(self.value, list().indexOf(self), list().length);
});
ko.defineProperty(self, 'labelPoint', function() {
var point = valueToPoint(+self.value + 10, list().indexOf(self), list().length);
point.x -= 4;
point.y += 4;
return point;
});
}
App = new AppViewModel();
ko.applyBindings(window.App);
[
{ label: 'A', value: 100 },
{ label: 'B', value: 100 },
{ label: 'C', value: 100 },
{ label: 'D', value: 100 },
{ label: 'E', value: 100 },
{ label: 'F', value: 100 }
].forEach(App.addStat);