Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active February 1, 2017 10:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nitaku/ddd57089ef8fc757c4ae59489b2059c9 to your computer and use it in GitHub Desktop.
Save nitaku/ddd57089ef8fc757c4ae59489b2059c9 to your computer and use it in GitHub Desktop.
Vue.js Matrix Component

This example uses Vue.js components to create a custom tag for a simple matrix diagram.

Vue.component 'matrix',
props:
data:
type: Array
required: true
padding:
type: Number
default: 1
cellsize:
type: Number
default: 20
template: '''
<svg :width="ncols*cellsize" :height="nrows*cellsize" class="matrix">
<g v-for="(row,i) in data">
<rect
v-for="(cell,j) in row"
class="cell"
:x="j*cellsize + cellsize/2 - scale(cell)/2"
:y="i*cellsize + cellsize/2 - scale(cell)/2"
:width="scale(cell)"
:height="scale(cell)"
/>
</g>
</svg>
'''
computed:
max: () -> d3.max @data, (r) -> d3.max r
nrows: () -> @data.length
ncols: () -> if @data.length > 0 then @data[0].length else 0
scale: () ->
d3.scaleSqrt()
.domain [0, @max]
.range [0, Math.max(0,@cellsize-@padding)]
app = new Vue
el: '#app'
data:
matrix1: [
[1,2,3],
[4,5,6],
[9,9,9]
],
matrix2: [
[12,24,35],
[45,15,60],
[60,60,60]
]
body, html {
padding: 0;
margin: 0;
height: 100%;
}
.matrix {
margin: 20px;
}
.cell {
fill: teal;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue.js Matrix Component</title>
<link type="text/css" href="index.css" rel="stylesheet"/>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<matrix
v-bind:data="matrix1"
:cellsize="60"
/>
<matrix
v-bind:data="matrix2"
:cellsize="40"
:padding="2"
/>
</div>
<script src="index.js"></script>
</body>
</html>
// Generated by CoffeeScript 1.10.0
(function() {
var app;
Vue.component('matrix', {
props: {
data: {
type: Array,
required: true
},
padding: {
type: Number,
"default": 1
},
cellsize: {
type: Number,
"default": 20
}
},
template: '<svg :width="ncols*cellsize" :height="nrows*cellsize" class="matrix">\n <g v-for="(row,i) in data">\n <rect\n v-for="(cell,j) in row"\n class="cell"\n :x="j*cellsize + cellsize/2 - scale(cell)/2"\n :y="i*cellsize + cellsize/2 - scale(cell)/2"\n :width="scale(cell)"\n :height="scale(cell)"\n />\n </g>\n</svg>',
computed: {
max: function() {
return d3.max(this.data, function(r) {
return d3.max(r);
});
},
nrows: function() {
return this.data.length;
},
ncols: function() {
if (this.data.length > 0) {
return this.data[0].length;
} else {
return 0;
}
},
scale: function() {
return d3.scaleSqrt().domain([0, this.max]).range([0, Math.max(0, this.cellsize - this.padding)]);
}
}
});
app = new Vue({
el: '#app',
data: {
matrix1: [[1, 2, 3], [4, 5, 6], [9, 9, 9]],
matrix2: [[12, 24, 35], [45, 15, 60], [60, 60, 60]]
}
});
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment