Skip to content

Instantly share code, notes, and snippets.

@espinielli
Last active January 25, 2016 08:54
Show Gist options
  • Save espinielli/0b4bfae049a96e031c81 to your computer and use it in GitHub Desktop.
Save espinielli/0b4bfae049a96e031c81 to your computer and use it in GitHub Desktop.
test FIR merging and topology
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<link rel="stylesheet" type="text/css" href="viz.css">
</head>
<body>
<div id="tooltip" class="hidden">
<p id="tooltiptext"></p>
</div>
<div id="viz"></div>
<script src="viz.js"></script>
</body>
.background {
fill: none;
pointer-events: all;
}
body {
margin: 0;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
fill: none;
}
svg {
width: 100%;
height: 100%;
background: none;
}
.A {
fill: red;
stroke: grey;
stroke-width: 0.5;
// opacity: 0.4;
}
.merged {
fill: green;
opacity: 0.2;
stroke: black;
stroke-dasharray: 5, 5;
}
#tooltip {
position: absolute;
width: auto;
height: auto;
padding: 2px 2px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
-webkit-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.4);
-moz-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.4);
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.4);
pointer-events: none;
background-color: #bbb;
}
#tooltip.hidden {
display: none;
}
#tooltip p {
margin: 0 0 0 0;
padding: 2px 2px;
font-family: sans-serif;
font-size: 11px;
}
.hidden {
display: none;
}
.fir {
/*display: none;*/
/*fill: yellow;*/
/*opacity: .41;*/
stroke: black;
stroke-width: 0.2;
}
.fir.EYVLFIR {
display: none;
fill: blue;
opacity: 1;
stroke: red;
stroke-width: 0.2;
}
.label {
/*text-anchor: left;*/
dx: 10px;
}
.label text {
font: 12px sans-serif;
}
.label-key {
font-weight: bold;
}
var width = 300,
height = 300
var scale = 1500
var translate = [-100, 1500]
var labelPadding = 3
var firs
var svg = d3.select('#viz')
.append('svg')
.attr('width', width)
.attr('height', height)
// find proper scale and translation from bounds of europe polygon
var projection = d3.geo.azimuthalEqualArea()
.scale(scale)
.translate(translate)
var path = d3.geo.path().projection(projection)
var selected = d3.set(['EYVLFIR', 'EPWWFIR'])
// var selected = d3.set(['EYVLFIR'])
// var selected = d3.set(['EPWWFIR'])
// var selected = d3.set([
// 'LGGGFIR',
// 'LIBBFIR', 'LIMMFIR', 'LIRRFIR',
// 'LMMMFIR',
// 'LCCCFIR'
// ])
// ca. BBox for Poland and Lituania
var geojObj = {
'type': 'FeatureCollection',
'features': [{
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [
[
[14.0, 48.7],
[14.0, 56.6],
[27.4, 56.6],
[27.4, 48.7],
[14.0, 48.7]
]
]
},
'properties': {
'name': 'A'
}
}]
}
var tooltip = d3.select('#tooltip').classed('hidden', true),
tooltiptext = d3.select('#tooltiptext')
var background = svg.selectAll('rect.background')
.data([{}]).enter()
.append('rect')
.classed('background', true)
var g = svg.selectAll('g.all')
.data([{}]).enter()
.append('g')
.classed('all', true)
var active = d3.select(null)
var zoom = d3.behavior.zoom()
.scaleExtent([1, 8000])
.on('zoom', zoomed)
function zoomed () {
g.style('stroke-width', 1.5 / d3.event.scale + 'px')
g.attr('transform', 'translate(' + d3.event.translate + ')scale(' + d3.event.scale + ')')
}
// If the drag behavior prevents the default click,
// also stop propagation so we don’t click-to-zoom.
function stopped () {
if (d3.event.defaultPrevented) d3.event.stopPropagation()
}
function reset () {
active.classed('active', false)
active = d3.select(null)
svg.transition()
.duration(750)
.call(zoom.translate([0, 0]).scale(1).event)
}
function clicked (d) {
if (active.node() === this) {
console.log('this node is active')
return reset()
}
active.classed('active', false)
active = d3.select(this).classed('active', true)
var bounds = path.bounds(d),
dx = bounds[1][0] - bounds[0][0],
dy = bounds[1][1] - bounds[0][1],
x = (bounds[0][0] + bounds[1][0]) / 2,
y = (bounds[0][1] + bounds[1][1]) / 2,
scale = .95 / Math.max(dx / width, dy / height),
translate = [width / 2 - scale * x, height / 2 - scale * y]
svg.transition()
.duration(750)
.call(zoom.translate(translate).scale(scale).event)
}
// prj is the projection
// pth is the path
// gObj is the geojson object
function scaleAndTranslate (prj, pth, gObj) {
prj
.scale(1)
.translate([0, 0])
var b = pth.bounds(gObj),
dx = (b[1][0] - b[0][0]),
dy = (b[1][1] - b[0][1]),
x = (b[1][0] + b[0][0]),
y = (b[1][1] + b[0][1]),
s = .95 / Math.max(dx / width,
dy / height),
t = [(width - s * x) / 2,
(height - s * y) / 2]
// return the scale and translate to be used to update the projection.
// Such as
// projection.scale(s).translate(t)
return {'scale': s, 'translate': t}
}
svg.on('click', stopped, true)
background.on('click', reset)
g.style('stroke-width', '0.5px')
svg
.call(zoom) // delete this line to disable free zooming
.call(zoom.event)
svg.on('mousemove', function () {
// update tooltip position
tooltip.style('top', (event.pageY + 16) + 'px').style('left', (event.pageX + 10) + 'px')
return true
})
d3.json('FIRs_NM.json', function (error, fir) {
if (error) throw error
firs = topojson.feature(fir, fir.objects.FIRs_NM)
var graticule = d3.geo.graticule()
var myfirs = firs.features.filter(function (d) {
return selected.has(d.id)
})
// var sAndT = scaleAndTranslate(projection, path, firs)
// projection.scale(sAndT.scale).translate(sAndT.translate)
var gFIR = g.selectAll('.fir')
.data(myfirs)
.enter()
.append('g')
.attr('class', 'fir')
var fff = gFIR
.append('path')
.attr('class', function (d) {
return 'fir ' + d.id
})
.attr('d', path)
gFIR.selectAll('.point')
.data(function (d, i) {
return d.geometry.coordinates[0]
})
.enter().append('circle')
.attr('class', 'point')
.attr('cx', function (d) {
return projection([d[0], d[1]])[0]
})
.attr('cy', function (d) {
return projection([d[0], d[1]])[1]
})
.attr('r', 1)
.attr('fill', 'red')
.attr('opacity', 0.3)
var label = gFIR.selectAll('.label')
.data(function (d) {
return (d.geometry.coordinates[0]).filter(function (d, i) {
// if (i%3 === 0) return true
return true
})
})
.enter().append('g')
.attr('class', 'label')
.attr('transform', function (d, i) {
return 'translate(' +
projection([d[0], d[1]])[0] + ',' +
projection([d[0], d[1]])[1] + ')'
})
label.append('text')
// .attr("dy", ".35em")
.text(function (d, i) {
return i
})
// from http://stackoverflow.com/a/16093597/963575
var mmm = topojson.merge(
fir,
fir.objects.FIRs_NM.geometries.filter(function (d) {
return selected.has(d.id)
}))
g.append('path')
.datum(mmm)
.attr('class', 'merged')
.attr('transform', 'translate(20, 30)')
.attr('d', path)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment