Vue.js SVG example
by boulabiar
HTML
<script src="http://vuejs.org/js/vue.min.js"></script>
<!-- Vue.js can handle SVG too! -->
<svg width="200" height="200"
viewPort="0 0 200 200" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<polygon v-attr="points:points"/>
<circle cx="100" cy="100" r="80"/>
<text v-component="svg-label"
v-repeat="stats"
v-attr="x:x, y:y">
{{label}}
</text>
</svg>
<!-- controls -->
<div v-repeat="stats">
<label>{{label}}</label>
<input type="range" v-model="value" min="0" max="100" />
<span>{{value}}</span>
</div>
<p style="font-size:12px">* input[type="range"] requires IE10 or above.</p>
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
var size = 200
// A label component
Vue.component('svg-label', {
created: function () {
this.x = this.y = 0
this.$watch('value', function (val) {
var point = valueToPoint(+val + 10, this.$index)
this.x = point.x - 4
this.y = point.y + 4
})
}
})
// bootstrap the demo
new Vue({
el: 'body',
data: {
stats: [
{ label: 'A', value: 100 },
{ label: 'B', value: 100 },
{ label: 'C', value: 100 },
{ label: 'D', value: 100 },
{ label: 'E', value: 100 },
{ label: 'F', value: 100 }
]
},
computed: {
points: function () {
return this.stats.map(function (stat, i) {
var point = valueToPoint(stat.value, i)
return point.x + ',' + point.y
}).join(' ')
}
}
})
// do some math...
function valueToPoint (value, i) {
var x = 0,
y = -value * (size / 100) * 0.4,
angle = Math.PI / 3 * i,
cos = Math.cos(angle),
sin = Math.sin(angle),
tx = x * cos - y * sin + size / 2,
ty = x * sin + y * cos + size / 2
return {
x: tx,
y: ty
}
}