Permalink
Browse files

Transofrm parameters should be taken into consideration while convert…

…ing map
  • Loading branch information...
1 parent a7df60f commit 48d6bf096b155ad821f26433c3921228aebd53f3 @bjornd committed Nov 15, 2012
Showing with 437 additions and 20 deletions.
  1. +38 −9 css/style.css
  2. +9 −6 index.html
  3. +124 −5 js/app.js
  4. +266 −0 map-africa.svg
View
@@ -8,7 +8,6 @@ html, body {
}
label {
- display: block;
font-weight: bold;
}
@@ -57,15 +56,34 @@ label {
padding: 8px 10px 12px 8px;
}
-#input-source {
- position: absolute;
- left: 0;
- top: 0;
- bottom: 0;
- right: 0;
- margin: 0 10px 0 10px;
+#card-input label {
+ width: 120px;
+ display: inline-block;
+}
+
+#card-input input {
+ width: 240px;
+ display: inline-block;
}
+ #input-id-attribute {
+ position: absolute;
+ top: 0;
+ }
+
+ #input-name-attribute {
+ position: absolute;
+ top: 2em;
+ }
+
+ #input-source {
+ position: absolute;
+ top: 5em;
+ left: 8px;
+ right: 6px;
+ bottom: 0;
+ }
+
#save-source {
position: absolute;
left: 0;
@@ -79,6 +97,7 @@ label {
width: 30%;
height: 100%;
float: left;
+ overflow: auto;
}
#settings-table tr.active {
@@ -90,6 +109,10 @@ label {
margin-bottom: 20px;
}
+ #settings-panel label {
+ display: block;
+ }
+
#settings-panel tr {
cursor: pointer;
}
@@ -113,8 +136,14 @@ label {
padding: 5px;
}
+#settings-divider {
+ width: 1%;
+ float: left;
+ height: 100%;
+}
+
#settings-map {
- width: 70%;
+ width: 69%;
height: 100%;
float: left;
}
View
@@ -8,14 +8,14 @@
<link href="css/jquery-ui-1.9.1.custom.min.css" rel="stylesheet" media="all"/>
<script src="js/knockout-2.2.0.js"></script>
<script src="js/jquery-1.8.2.min.js"></script>
- <script src="jvectormap/jquery.jvectormap.min.js"></script>
+ <script src="jvectormap/jquery-jvectormap.min.js"></script>
<script src="js/jquery-ui-1.9.1.custom.min.js"></script>
<script src="js/app.js"></script>
<script>
$(function(){
- /*$.get('map-sample.svg', function(response){
+ $.get('map-africa.svg', function(response){
$('#input-source').val(response);
- }, 'text');*/
+ }, 'text');
app();
});
</script>
@@ -24,6 +24,8 @@
<div id="card-input" class="card">
<div class="card-header">Paste SVG code</div>
<div class="card-content">
+ <div id="input-id-attribute"><label>Id attribute:</label><input value="id"/></div>
+ <div id="input-name-attribute"><label>Name attribute:</label><input value="title"/></div>
<textarea id="input-source"></textarea>
</div>
<div class="card-footer">
@@ -35,7 +37,7 @@
<div class="card-content">
<div id="settings-panel">
<label>Map name: <input type="text" value="map" id="setting-map-name"/></label>
- <label>Edit region ids and names:</label>
+ <label>Region parameters:</label>
<div id="settings-table">
<table cellpadding="0" cellspacing="0" width="100%">
<thead>
@@ -53,6 +55,7 @@
</table>
</div>
</div>
+ <div id="settings-divider"></div>
<div id="settings-map"></div>
</div>
<div class="card-footer">
@@ -67,8 +70,8 @@
<div class="card-footer"></div>
</div>
<div id="edit-dialog">
- <div><label>Id</label><input id="edit-dialog-id"/></div>
- <div><label>Name</label><input id="edit-dialog-name"/></div>
+ <div><label for="edit-dialog-id">Id</label><input id="edit-dialog-id"/></div>
+ <div><label for="edit-dialog-name">Name</label><input id="edit-dialog-name"/></div>
</div>
</body>
</html>
View
129 js/app.js
@@ -1,4 +1,111 @@
var app = (function(){
+
+ function Matrix(m){
+ this.m = m;
+ }
+
+ Matrix.multVectors = function(v1, v2){
+ var sum = 0,
+ i;
+
+ for (i = 0; i < v1.length; i++) {
+ sum += v1[i]*v2[i];
+ }
+ return sum;
+ };
+
+ Matrix.prototype.getRow = function(index){
+ return this.m[index];
+ };
+
+ Matrix.prototype.getColumn = function(index){
+ var i,
+ v = [];
+
+ for (i = 0; i < this.m.length; i++) {
+ v[i] = this.m[i][index];
+ }
+ return v;
+ };
+
+ Matrix.prototype.mult = function(m2){
+ var i,
+ j,
+ m1 = this,
+ m = [];
+
+ for (i = 0; i < m1.m.length; i++) {
+ m[i] = [];
+ for (j = 0; j < m2.m[i].length; j++) {
+ m[i][j] = Matrix.multVectors(m1.getRow(i), m2.getColumn(j));
+ }
+ };
+ return new Matrix(m);
+ };
+
+
+ function SvgUtils(){}
+
+ SvgUtils.transformRegExp = /(matrix|translate|scale)\(([^)]*)\)/g;
+
+ SvgUtils.parseTransform = function(transform){
+ var match,
+ args = [],
+ result = new Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]]),
+ matrix,
+ args,
+ i;
+
+ while ((match = SvgUtils.transformRegExp.exec(transform)) !== null) {
+ matrix = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];
+ args = match[2].split(',');
+ for (i = 0; i < args.length; i++) {
+ args[i] = parseFloat($.trim(args[i]));
+ }
+ if (match[1] == 'matrix') {
+ matrix[0] = [args[0], args[2], args[4]];
+ matrix[1] = [args[1], args[3], args[5]];
+ } else if (match[1] == 'translate') {
+ matrix[0][2] = args[0];
+ matrix[1][2] = args[1] || 0;
+ } else if (match[1] == 'scale') {
+ matrix[0][0] = args[0];
+ matrix[1][1] = args[1] || args[0];
+ }
+ result = result.mult(new Matrix(matrix));
+ }
+ return result;
+ };
+
+ SvgUtils.applyTransformToPath = function(path, matrix){
+ var re = /([MmLlHhVvCcSsZz])([^MmLlHhVvCcSsZz]*)/g,
+ coords,
+ i,
+ cmdIndex = 0,
+ m = matrix.m,
+ tPath = '',
+ point;
+ relativeMatrix = new Matrix([[m[0][0], m[0][1], 0], [m[1][0], m[1][1], 0], [0, 0, 1]]);
+
+ while ((match = re.exec(path)) !== null) {
+ coords = $.trim(match[2]).split(/[, ]+/g);
+ tCoords = [];
+ if (coords.length >= 2) {
+ for (i = 0; i < coords.length; i += 2) {
+ if (match[1] === match[1].toUpperCase() || cmdIndex == 0) {
+ point = matrix.mult(new Matrix([[ coords[i] ], [ coords[i+1] ], [1] ]));
+ } else {
+ point = relativeMatrix.mult(new Matrix([[ coords[i] ], [ coords[i+1] ], [1] ]));
+ }
+ tCoords.push(point.m[0][0].toFixed(2), point.m[1][0].toFixed(2));
+ }
+ }
+ tPath += match[1]+tCoords.join(' ');
+ cmdIndex++;
+ }
+ return tPath;
+ }
+
function MapRegion(data){
this.originalId = data.id || 'id'+MapRegion.uid;
this.id = ko.observable(this.originalId);
@@ -42,14 +149,21 @@ var app = (function(){
}
};
- Map.prototype.loadFromSvg = function(svg){
+ Map.prototype.loadFromSvg = function(svg, settings){
var that = this;
this.width = parseInt($(svg).find('svg').attr('width'), 10);
this.height = parseInt($(svg).find('svg').attr('height'), 10)
$(svg).find('path').each(function(i){
+ var fullTransform = '';
+
+ $(this).parents().add(this).each(function(){
+ fullTransform += ' '+$(this).attr('transform');
+ });
that.paths.push(new MapRegion({
- path: $(this).attr('d')
+ id: $(this).attr('id') || null,
+ name: $(this).attr('name') || null,
+ path: SvgUtils.applyTransformToPath( $(this).attr('d'), SvgUtils.parseTransform(fullTransform) )
}));
});
}
@@ -68,7 +182,7 @@ var app = (function(){
modal: true,
resizable: false,
buttons: {
- Ok: function() {
+ OK: function() {
that.path.id( $('#edit-dialog-id').val() );
that.path.name( $('#edit-dialog-name').val() );
$( this ).dialog( "close" );
@@ -118,15 +232,20 @@ var app = (function(){
layout = new CardLayout($('.card'));
$('#input-convert').click(function(){
- map.loadFromSvg( $.parseXML($('#input-source').val()) );
+ map.loadFromSvg( $.parseXML( $.trim( $('#input-source').val()) ), {
+ idAttribure: $('#input-id-attribute input').val(),
+ nameAttribute: $('#input-name-attribute input').val()
+ } );
layout.show('settings');
jvmMap = map.createJvmMap({
container: $('#settings-map'),
map: 'map',
backgroundColor: 'white',
regionStyle: {
initial: {
- fill: '#02B2FF'
+ fill: '#02B2FF',
+ stroke: 'white',
+ "stroke-width": 1.5
},
hover: {
fill: '#02DBFF'
Oops, something went wrong.

0 comments on commit 48d6bf0

Please sign in to comment.