Skip to content

Instantly share code, notes, and snippets.

@Grace
Created November 9, 2015 15:40
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 Grace/00d5a38358609f66d49d to your computer and use it in GitHub Desktop.
Save Grace/00d5a38358609f66d49d to your computer and use it in GitHub Desktop.
Material Vue.js Map Card
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<template id='v-card-content'>
<div id="d3-canvas" class="d3-canvas"></div>
</template>
<!-- material card template for vue.js -->
<template id="v-card">
<div class="widget card">
<div class="card-content">
<span class="card-title grey-text text-darken-4">{{title}}</span>
<v-card-content></v-card-content>
</div>
<div class="card-action">
<a href="//materializecss.com">Documentation</a>
<a href='//github.com/Grace'>GitHub</a>
</div>
</div>
</div>
</template>
<div id="demo">
<v-card title="Material Vue.js Card" content='Example'>
</v-card>
</div>
// define
var Card = Vue.extend({
props: ['title'],
template: '#v-card'
});
var CardContent = Vue.extend({
template: '#v-card-content'
});
// Register MaterialCard Component
Vue.component('v-card', Card);
Vue.component('v-card-content', CardContent);
// Root Instance
var vm = new Vue({
el: '#demo'
});
$('.widget').draggable();
// D3 map source: Forked from [Benjamin](http://codepen.io/maggiben/)'s Pen [D3 Map & GeoIP](http://codepen.io/maggiben/pen/snljd/).
function drawMap() {
d3.select(window).on("resize", throttle);
var zoom = d3.behavior.zoom()
.scaleExtent([1, 9])
.on("zoom", move);
var width = document.getElementById('d3-canvas').offsetWidth;
var height = width / 2;
var topo,projection,path,svg,g;
var graticule = d3.geo.graticule();
var tooltip = d3.select("#d3-canvas").append("div").attr("class", "tooltip hidden");
setup(width,height);
function setup(width,height){
projection = d3.geo.mercator()
.translate([(width/2), (height/2)])
.scale( width / 2 / Math.PI);
path = d3.geo.path().projection(projection);
svg = d3.select("#d3-canvas").append("svg")
.attr("width", width)
.attr("height", height + 8)
.call(zoom)
.on("click", click)
.append("g");
g = svg.append("g");
}
d3.json("https://api.github.com/gists/9398333", function(error, root) {
var world = root.files['world.json'].content
world = JSON.parse(world)
var countries = topojson.feature(world, world.objects.countries).features;
topo = countries;
draw(topo);
});
function draw(topo) {
var country = g.selectAll(".country").data(topo);
country.enter().insert("path")
.attr("class", "country")
.attr("d", path)
.attr("id", function(d,i) { return d.id; })
.attr("title", function(d,i) { return d.properties.name; })
.style("fill", function(d, i) { return "#49cc90";return d.properties.color; });
//offsets for tooltips
var offsetL = document.getElementById('d3-canvas').offsetLeft+20;
var offsetT = document.getElementById('d3-canvas').offsetTop+10;
//tooltips
country
.on("mousemove", function(d,i) {
var mouse = d3.mouse(svg.node()).map( function(d) { return parseInt(d); } );
tooltip.classed("hidden", false)
.attr("style", "left:"+(mouse[0]+offsetL)+"px;top:"+(mouse[1]+offsetT)+"px")
.html(d.properties.name);
})
.on("mouseout", function(d,i) {
tooltip.classed("hidden", true);
});
$.getJSON( "http://smart-ip.net/geoip-json?callback=?",
function(data){
console.log( data);
addpoint(data.longitude, data.latitude, data.city);
$("span.city").html(data.city);
}
);
}
function redraw() {
width = document.getElementById('d3-canvas').offsetWidth;
height = width / 2;
d3.select('svg').remove();
setup(width,height);
draw(topo);
}
function move() {
var t = d3.event.translate;
var s = d3.event.scale;
zscale = s;
var h = height/4;
t[0] = Math.min(
(width/height) * (s - 1),
Math.max( width * (1 - s), t[0] )
);
t[1] = Math.min(
h * (s - 1) + h * s,
Math.max(height * (1 - s) - h * s, t[1])
);
zoom.translate(t);
g.attr("transform", "translate(" + t + ")scale(" + s + ")");
//adjust the country hover stroke width based on zoom level
d3.selectAll(".country").style("stroke-width", 1.5 / s);
}
var throttleTimer;
function throttle() {
window.clearTimeout(throttleTimer);
throttleTimer = window.setTimeout(function() {
redraw();
}, 200);
}
//geo translation on mouse click in map
function click() {
var latlon = projection.invert(d3.mouse(this));
console.log(latlon);
}
//function to add points and text to the map (used in plotting capitals)
function addpoint(longitude, latitude, text) {
var gpoint = g.append("g").attr("class", "gpoint");
var x = projection([longitude, latitude])[0];
var y = projection([longitude, latitude])[1];
gpoint.append("svg:circle")
.attr("cx", x)
.attr("cy", y)
.attr("class","point")
.attr("r", 2)
.style("fill", "#fff");
//conditional in case a point has no associated text
if(text.length>0){
gpoint.append("text")
.attr("x", x+2)
.attr("y", y+2)
.attr("class","text")
.text(text)
.style("fill", "#fff");
}
}
};
drawMap();
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.7/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.js"></script>
.widget {
width: 650px;
height: 500px;
}
/* Source: http://codepen.io/maggiben */
body {
background-image: url(http://subtlepatterns.com/patterns/low_contrast_linen_@2X.png);
background-size: 256px;
background-color: #252525;
font-family: "Roboto", Helvetica, Arial, sans-serif;
margin: 0;
}
h4 {
position: absolute;
text-align: center;
width: 100%;
color: rgba(255,255,255, 0.75);
text-align: center;
span.city {
color: rgba(255,255,255, 0.95);
}
}
.country:hover{
stroke: #fff;
stroke-width: 1.5px;
}
.text{
font-size: 10px;
text-transform:capitalize;
}
#d3-canvas {
margin: 0;
border: 0px solid #81D4FA;
border-radius: 5px;
height: 100%;
overflow:hidden;
background: #B3E5FC;
}
.hidden {
display: none;
}
div.tooltip {
color: #222;
background: #fff;
padding: .5em;
text-shadow: #f5f5f5 0 1px 0;
border-radius: 2px;
box-shadow: 0px 0px 2px 0px #a6a6a6;
opacity: 0.9;
position: absolute;
}
.graticule {
fill: none;
stroke: #8f8f8f;
stroke-width: .5px;
stroke-opacity: .5;
}
.equator {
stroke: #ccc;
stroke-width: 1px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.2/css/materialize.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment